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.R;
20import com.android.internal.os.BatteryStatsImpl;
21import com.android.server.AttributeCache;
22import com.android.server.IntentResolver;
23import com.android.server.ProcessMap;
24import com.android.server.ProcessStats;
25import com.android.server.SystemServer;
26import com.android.server.Watchdog;
27import com.android.server.WindowManagerService;
28import com.android.server.am.ActivityStack.ActivityState;
29
30import dalvik.system.Zygote;
31
32import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityManagerNative;
35import android.app.ActivityThread;
36import android.app.AlertDialog;
37import android.app.AppGlobals;
38import android.app.ApplicationErrorReport;
39import android.app.Dialog;
40import android.app.IActivityController;
41import android.app.IActivityWatcher;
42import android.app.IApplicationThread;
43import android.app.IInstrumentationWatcher;
44import android.app.INotificationManager;
45import android.app.IServiceConnection;
46import android.app.IThumbnailReceiver;
47import android.app.Instrumentation;
48import android.app.Notification;
49import android.app.NotificationManager;
50import android.app.PendingIntent;
51import android.app.Service;
52import android.app.backup.IBackupManager;
53import android.content.ActivityNotFoundException;
54import android.content.BroadcastReceiver;
55import android.content.ComponentName;
56import android.content.ContentResolver;
57import android.content.Context;
58import android.content.Intent;
59import android.content.IntentFilter;
60import android.content.IIntentReceiver;
61import android.content.IIntentSender;
62import android.content.IntentSender;
63import android.content.pm.ActivityInfo;
64import android.content.pm.ApplicationInfo;
65import android.content.pm.ConfigurationInfo;
66import android.content.pm.IPackageDataObserver;
67import android.content.pm.IPackageManager;
68import android.content.pm.InstrumentationInfo;
69import android.content.pm.PackageInfo;
70import android.content.pm.PackageManager;
71import android.content.pm.PathPermission;
72import android.content.pm.ProviderInfo;
73import android.content.pm.ResolveInfo;
74import android.content.pm.ServiceInfo;
75import android.content.pm.PackageManager.NameNotFoundException;
76import android.content.res.Configuration;
77import android.graphics.Bitmap;
78import android.net.Uri;
79import android.os.Binder;
80import android.os.Build;
81import android.os.Bundle;
82import android.os.Debug;
83import android.os.DropBoxManager;
84import android.os.Environment;
85import android.os.FileObserver;
86import android.os.FileUtils;
87import android.os.Handler;
88import android.os.IBinder;
89import android.os.IPermissionController;
90import android.os.Looper;
91import android.os.Message;
92import android.os.Parcel;
93import android.os.ParcelFileDescriptor;
94import android.os.Process;
95import android.os.RemoteCallbackList;
96import android.os.RemoteException;
97import android.os.ServiceManager;
98import android.os.StrictMode;
99import android.os.SystemClock;
100import android.os.SystemProperties;
101import android.provider.Settings;
102import android.util.Config;
103import android.util.EventLog;
104import android.util.Slog;
105import android.util.Log;
106import android.util.PrintWriterPrinter;
107import android.util.SparseArray;
108import android.util.TimeUtils;
109import android.view.Gravity;
110import android.view.LayoutInflater;
111import android.view.View;
112import android.view.WindowManager;
113import android.view.WindowManagerPolicy;
114
115import java.io.BufferedInputStream;
116import java.io.BufferedOutputStream;
117import java.io.DataInputStream;
118import java.io.DataOutputStream;
119import java.io.File;
120import java.io.FileDescriptor;
121import java.io.FileInputStream;
122import java.io.FileNotFoundException;
123import java.io.FileOutputStream;
124import java.io.IOException;
125import java.io.InputStreamReader;
126import java.io.PrintWriter;
127import java.lang.IllegalStateException;
128import java.lang.ref.WeakReference;
129import java.util.ArrayList;
130import java.util.Collections;
131import java.util.Comparator;
132import java.util.HashMap;
133import java.util.HashSet;
134import java.util.Iterator;
135import java.util.List;
136import java.util.Locale;
137import java.util.Map;
138import java.util.Set;
139import java.util.concurrent.atomic.AtomicBoolean;
140import java.util.concurrent.atomic.AtomicLong;
141
142public final class ActivityManagerService extends ActivityManagerNative
143        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
144    static final String TAG = "ActivityManager";
145    static final boolean DEBUG = false;
146    static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
147    static final boolean DEBUG_SWITCH = localLOGV || false;
148    static final boolean DEBUG_TASKS = localLOGV || false;
149    static final boolean DEBUG_PAUSE = localLOGV || false;
150    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
151    static final boolean DEBUG_TRANSITION = localLOGV || false;
152    static final boolean DEBUG_BROADCAST = localLOGV || false;
153    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
154    static final boolean DEBUG_SERVICE = localLOGV || false;
155    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
156    static final boolean DEBUG_VISBILITY = localLOGV || false;
157    static final boolean DEBUG_PROCESSES = localLOGV || false;
158    static final boolean DEBUG_PROVIDER = localLOGV || false;
159    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
160    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
161    static final boolean DEBUG_RESULTS = localLOGV || false;
162    static final boolean DEBUG_BACKUP = localLOGV || false;
163    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
164    static final boolean DEBUG_POWER = localLOGV || false;
165    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
166    static final boolean VALIDATE_TOKENS = false;
167    static final boolean SHOW_ACTIVITY_START_TIME = true;
168
169    // Control over CPU and battery monitoring.
170    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
171    static final boolean MONITOR_CPU_USAGE = true;
172    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
173    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
174    static final boolean MONITOR_THREAD_CPU_USAGE = false;
175
176    // The flags that are set for all calls we make to the package manager.
177    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
178
179    private static final String SYSTEM_SECURE = "ro.secure";
180
181    // This is the maximum number of application processes we would like
182    // to have running.  Due to the asynchronous nature of things, we can
183    // temporarily go beyond this limit.
184    static final int MAX_PROCESSES = 2;
185
186    // Set to false to leave processes running indefinitely, relying on
187    // the kernel killing them as resources are required.
188    static final boolean ENFORCE_PROCESS_LIMIT = false;
189
190    // This is the maximum number of activities that we would like to have
191    // running at a given time.
192    static final int MAX_ACTIVITIES = 20;
193
194    // Maximum number of recent tasks that we can remember.
195    static final int MAX_RECENT_TASKS = 20;
196
197    // Amount of time after a call to stopAppSwitches() during which we will
198    // prevent further untrusted switches from happening.
199    static final long APP_SWITCH_DELAY_TIME = 5*1000;
200
201    // How long we wait for a launched process to attach to the activity manager
202    // before we decide it's never going to come up for real.
203    static final int PROC_START_TIMEOUT = 10*1000;
204
205    // How long to wait after going idle before forcing apps to GC.
206    static final int GC_TIMEOUT = 5*1000;
207
208    // The minimum amount of time between successive GC requests for a process.
209    static final int GC_MIN_INTERVAL = 60*1000;
210
211    // The rate at which we check for apps using excessive power -- 15 mins.
212    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
213
214    // The minimum sample duration we will allow before deciding we have
215    // enough data on wake locks to start killing things.
216    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
217
218    // The minimum sample duration we will allow before deciding we have
219    // enough data on CPU usage to start killing things.
220    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
221
222    // How long we allow a receiver to run before giving up on it.
223    static final int BROADCAST_TIMEOUT = 10*1000;
224
225    // How long we wait for a service to finish executing.
226    static final int SERVICE_TIMEOUT = 20*1000;
227
228    // How long a service needs to be running until restarting its process
229    // is no longer considered to be a relaunch of the service.
230    static final int SERVICE_RESTART_DURATION = 5*1000;
231
232    // How long a service needs to be running until it will start back at
233    // SERVICE_RESTART_DURATION after being killed.
234    static final int SERVICE_RESET_RUN_DURATION = 60*1000;
235
236    // Multiplying factor to increase restart duration time by, for each time
237    // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
238    static final int SERVICE_RESTART_DURATION_FACTOR = 4;
239
240    // The minimum amount of time between restarting services that we allow.
241    // That is, when multiple services are restarting, we won't allow each
242    // to restart less than this amount of time from the last one.
243    static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
244
245    // Maximum amount of time for there to be no activity on a service before
246    // we consider it non-essential and allow its process to go on the
247    // LRU background list.
248    static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
249
250    // How long we wait until we timeout on key dispatching.
251    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
252
253    // The minimum time we allow between crashes, for us to consider this
254    // application to be bad and stop and its services and reject broadcasts.
255    static final int MIN_CRASH_INTERVAL = 60*1000;
256
257    // How long we wait until we timeout on key dispatching during instrumentation.
258    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
259
260    // OOM adjustments for processes in various states:
261
262    // This is a process without anything currently running in it.  Definitely
263    // the first to go! Value set in system/rootdir/init.rc on startup.
264    // This value is initalized in the constructor, careful when refering to
265    // this static variable externally.
266    static final int EMPTY_APP_ADJ;
267
268    // This is a process only hosting activities that are not visible,
269    // so it can be killed without any disruption. Value set in
270    // system/rootdir/init.rc on startup.
271    static final int HIDDEN_APP_MAX_ADJ;
272    static int HIDDEN_APP_MIN_ADJ;
273
274    // This is a process holding the home application -- we want to try
275    // avoiding killing it, even if it would normally be in the background,
276    // because the user interacts with it so much.
277    static final int HOME_APP_ADJ;
278
279    // This is a process currently hosting a backup operation.  Killing it
280    // is not entirely fatal but is generally a bad idea.
281    static final int BACKUP_APP_ADJ;
282
283    // This is a process holding a secondary server -- killing it will not
284    // have much of an impact as far as the user is concerned. Value set in
285    // system/rootdir/init.rc on startup.
286    static final int SECONDARY_SERVER_ADJ;
287
288    // This is a process with a heavy-weight application.  It is in the
289    // background, but we want to try to avoid killing it.  Value set in
290    // system/rootdir/init.rc on startup.
291    static final int HEAVY_WEIGHT_APP_ADJ;
292
293    // This is a process only hosting components that are perceptible to the
294    // user, and we really want to avoid killing them, but they are not
295    // immediately visible. An example is background music playback.  Value set in
296    // system/rootdir/init.rc on startup.
297    static final int PERCEPTIBLE_APP_ADJ;
298
299    // This is a process only hosting activities that are visible to the
300    // user, so we'd prefer they don't disappear. Value set in
301    // system/rootdir/init.rc on startup.
302    static final int VISIBLE_APP_ADJ;
303
304    // This is the process running the current foreground app.  We'd really
305    // rather not kill it! Value set in system/rootdir/init.rc on startup.
306    static final int FOREGROUND_APP_ADJ;
307
308    // This is a process running a core server, such as telephony.  Definitely
309    // don't want to kill it, but doing so is not completely fatal.
310    static final int CORE_SERVER_ADJ = -12;
311
312    // The system process runs at the default adjustment.
313    static final int SYSTEM_ADJ = -16;
314
315    // Memory pages are 4K.
316    static final int PAGE_SIZE = 4*1024;
317
318    // Corresponding memory levels for above adjustments.
319    static final int EMPTY_APP_MEM;
320    static final int HIDDEN_APP_MEM;
321    static final int HOME_APP_MEM;
322    static final int BACKUP_APP_MEM;
323    static final int SECONDARY_SERVER_MEM;
324    static final int HEAVY_WEIGHT_APP_MEM;
325    static final int PERCEPTIBLE_APP_MEM;
326    static final int VISIBLE_APP_MEM;
327    static final int FOREGROUND_APP_MEM;
328
329    // The minimum number of hidden apps we want to be able to keep around,
330    // without empty apps being able to push them out of memory.
331    static final int MIN_HIDDEN_APPS = 2;
332
333    // The maximum number of hidden processes we will keep around before
334    // killing them; this is just a control to not let us go too crazy with
335    // keeping around processes on devices with large amounts of RAM.
336    static final int MAX_HIDDEN_APPS = 15;
337
338    // We put empty content processes after any hidden processes that have
339    // been idle for less than 15 seconds.
340    static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
341
342    // We put empty content processes after any hidden processes that have
343    // been idle for less than 120 seconds.
344    static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
345
346    static int getIntProp(String name, boolean allowZero) {
347        String str = SystemProperties.get(name);
348        if (str == null) {
349            throw new IllegalArgumentException("Property not defined: " + name);
350        }
351        int val = Integer.valueOf(str);
352        if (val == 0 && !allowZero) {
353            throw new IllegalArgumentException("Property must not be zero: " + name);
354        }
355        return val;
356    }
357
358    static {
359        // These values are set in system/rootdir/init.rc on startup.
360        FOREGROUND_APP_ADJ = getIntProp("ro.FOREGROUND_APP_ADJ", true);
361        VISIBLE_APP_ADJ = getIntProp("ro.VISIBLE_APP_ADJ", true);
362        PERCEPTIBLE_APP_ADJ = getIntProp("ro.PERCEPTIBLE_APP_ADJ", true);
363        HEAVY_WEIGHT_APP_ADJ = getIntProp("ro.HEAVY_WEIGHT_APP_ADJ", true);
364        SECONDARY_SERVER_ADJ = getIntProp("ro.SECONDARY_SERVER_ADJ", true);
365        BACKUP_APP_ADJ = getIntProp("ro.BACKUP_APP_ADJ", true);
366        HOME_APP_ADJ = getIntProp("ro.HOME_APP_ADJ", true);
367        HIDDEN_APP_MIN_ADJ = getIntProp("ro.HIDDEN_APP_MIN_ADJ", true);
368        EMPTY_APP_ADJ = getIntProp("ro.EMPTY_APP_ADJ", true);
369        // These days we use the last empty slot for hidden apps as well.
370        HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ;
371        FOREGROUND_APP_MEM = getIntProp("ro.FOREGROUND_APP_MEM", false)*PAGE_SIZE;
372        VISIBLE_APP_MEM = getIntProp("ro.VISIBLE_APP_MEM", false)*PAGE_SIZE;
373        PERCEPTIBLE_APP_MEM = getIntProp("ro.PERCEPTIBLE_APP_MEM", false)*PAGE_SIZE;
374        HEAVY_WEIGHT_APP_MEM = getIntProp("ro.HEAVY_WEIGHT_APP_MEM", false)*PAGE_SIZE;
375        SECONDARY_SERVER_MEM = getIntProp("ro.SECONDARY_SERVER_MEM", false)*PAGE_SIZE;
376        BACKUP_APP_MEM = getIntProp("ro.BACKUP_APP_MEM", false)*PAGE_SIZE;
377        HOME_APP_MEM = getIntProp("ro.HOME_APP_MEM", false)*PAGE_SIZE;
378        HIDDEN_APP_MEM = getIntProp("ro.HIDDEN_APP_MEM", false)*PAGE_SIZE;
379        EMPTY_APP_MEM = getIntProp("ro.EMPTY_APP_MEM", false)*PAGE_SIZE;
380    }
381
382    static final int MY_PID = Process.myPid();
383
384    static final String[] EMPTY_STRING_ARRAY = new String[0];
385
386    public ActivityStack mMainStack;
387
388    /**
389     * Description of a request to start a new activity, which has been held
390     * due to app switches being disabled.
391     */
392    static class PendingActivityLaunch {
393        ActivityRecord r;
394        ActivityRecord sourceRecord;
395        Uri[] grantedUriPermissions;
396        int grantedMode;
397        boolean onlyIfNeeded;
398    }
399
400    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
401            = new ArrayList<PendingActivityLaunch>();
402
403    /**
404     * List of all active broadcasts that are to be executed immediately
405     * (without waiting for another broadcast to finish).  Currently this only
406     * contains broadcasts to registered receivers, to avoid spinning up
407     * a bunch of processes to execute IntentReceiver components.
408     */
409    final ArrayList<BroadcastRecord> mParallelBroadcasts
410            = new ArrayList<BroadcastRecord>();
411
412    /**
413     * List of all active broadcasts that are to be executed one at a time.
414     * The object at the top of the list is the currently activity broadcasts;
415     * those after it are waiting for the top to finish..
416     */
417    final ArrayList<BroadcastRecord> mOrderedBroadcasts
418            = new ArrayList<BroadcastRecord>();
419
420    /**
421     * Historical data of past broadcasts, for debugging.
422     */
423    static final int MAX_BROADCAST_HISTORY = 100;
424    final BroadcastRecord[] mBroadcastHistory
425            = new BroadcastRecord[MAX_BROADCAST_HISTORY];
426
427    /**
428     * Set when we current have a BROADCAST_INTENT_MSG in flight.
429     */
430    boolean mBroadcastsScheduled = false;
431
432    /**
433     * Activity we have told the window manager to have key focus.
434     */
435    ActivityRecord mFocusedActivity = null;
436    /**
437     * List of intents that were used to start the most recent tasks.
438     */
439    final ArrayList<TaskRecord> mRecentTasks
440            = new ArrayList<TaskRecord>();
441
442    /**
443     * All of the applications we currently have running organized by name.
444     * The keys are strings of the application package name (as
445     * returned by the package manager), and the keys are ApplicationRecord
446     * objects.
447     */
448    final ProcessMap<ProcessRecord> mProcessNames
449            = new ProcessMap<ProcessRecord>();
450
451    /**
452     * The currently running heavy-weight process, if any.
453     */
454    ProcessRecord mHeavyWeightProcess = null;
455
456    /**
457     * The last time that various processes have crashed.
458     */
459    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
460
461    /**
462     * Set of applications that we consider to be bad, and will reject
463     * incoming broadcasts from (which the user has no control over).
464     * Processes are added to this set when they have crashed twice within
465     * a minimum amount of time; they are removed from it when they are
466     * later restarted (hopefully due to some user action).  The value is the
467     * time it was added to the list.
468     */
469    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
470
471    /**
472     * All of the processes we currently have running organized by pid.
473     * The keys are the pid running the application.
474     *
475     * <p>NOTE: This object is protected by its own lock, NOT the global
476     * activity manager lock!
477     */
478    final SparseArray<ProcessRecord> mPidsSelfLocked
479            = new SparseArray<ProcessRecord>();
480
481    /**
482     * All of the processes that have been forced to be foreground.  The key
483     * is the pid of the caller who requested it (we hold a death
484     * link on it).
485     */
486    abstract class ForegroundToken implements IBinder.DeathRecipient {
487        int pid;
488        IBinder token;
489    }
490    final SparseArray<ForegroundToken> mForegroundProcesses
491            = new SparseArray<ForegroundToken>();
492
493    /**
494     * List of records for processes that someone had tried to start before the
495     * system was ready.  We don't start them at that point, but ensure they
496     * are started by the time booting is complete.
497     */
498    final ArrayList<ProcessRecord> mProcessesOnHold
499            = new ArrayList<ProcessRecord>();
500
501    /**
502     * List of records for processes that we have started and are waiting
503     * for them to call back.  This is really only needed when running in
504     * single processes mode, in which case we do not have a unique pid for
505     * each process.
506     */
507    final ArrayList<ProcessRecord> mStartingProcesses
508            = new ArrayList<ProcessRecord>();
509
510    /**
511     * List of persistent applications that are in the process
512     * of being started.
513     */
514    final ArrayList<ProcessRecord> mPersistentStartingProcesses
515            = new ArrayList<ProcessRecord>();
516
517    /**
518     * Processes that are being forcibly torn down.
519     */
520    final ArrayList<ProcessRecord> mRemovedProcesses
521            = new ArrayList<ProcessRecord>();
522
523    /**
524     * List of running applications, sorted by recent usage.
525     * The first entry in the list is the least recently used.
526     * It contains ApplicationRecord objects.  This list does NOT include
527     * any persistent application records (since we never want to exit them).
528     */
529    final ArrayList<ProcessRecord> mLruProcesses
530            = new ArrayList<ProcessRecord>();
531
532    /**
533     * List of processes that should gc as soon as things are idle.
534     */
535    final ArrayList<ProcessRecord> mProcessesToGc
536            = new ArrayList<ProcessRecord>();
537
538    /**
539     * This is the process holding what we currently consider to be
540     * the "home" activity.
541     */
542    ProcessRecord mHomeProcess;
543
544    /**
545     * Set of PendingResultRecord objects that are currently active.
546     */
547    final HashSet mPendingResultRecords = new HashSet();
548
549    /**
550     * Set of IntentSenderRecord objects that are currently active.
551     */
552    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
553            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
554
555    /**
556     * Fingerprints (String.hashCode()) of stack traces that we've
557     * already logged DropBox entries for.  Guarded by itself.  If
558     * something (rogue user app) forces this over
559     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
560     */
561    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
562    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
563
564    /**
565     * Strict Mode background batched logging state.
566     *
567     * The string buffer is guarded by itself, and its lock is also
568     * used to determine if another batched write is already
569     * in-flight.
570     */
571    private final StringBuilder mStrictModeBuffer = new StringBuilder();
572
573    /**
574     * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
575     */
576    private boolean mPendingBroadcastTimeoutMessage;
577
578    /**
579     * Intent broadcast that we have tried to start, but are
580     * waiting for its application's process to be created.  We only
581     * need one (instead of a list) because we always process broadcasts
582     * one at a time, so no others can be started while waiting for this
583     * one.
584     */
585    BroadcastRecord mPendingBroadcast = null;
586
587    /**
588     * The receiver index that is pending, to restart the broadcast if needed.
589     */
590    int mPendingBroadcastRecvIndex;
591
592    /**
593     * Keeps track of all IIntentReceivers that have been registered for
594     * broadcasts.  Hash keys are the receiver IBinder, hash value is
595     * a ReceiverList.
596     */
597    final HashMap mRegisteredReceivers = new HashMap();
598
599    /**
600     * Resolver for broadcast intents to registered receivers.
601     * Holds BroadcastFilter (subclass of IntentFilter).
602     */
603    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
604            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
605        @Override
606        protected boolean allowFilterResult(
607                BroadcastFilter filter, List<BroadcastFilter> dest) {
608            IBinder target = filter.receiverList.receiver.asBinder();
609            for (int i=dest.size()-1; i>=0; i--) {
610                if (dest.get(i).receiverList.receiver.asBinder() == target) {
611                    return false;
612                }
613            }
614            return true;
615        }
616    };
617
618    /**
619     * State of all active sticky broadcasts.  Keys are the action of the
620     * sticky Intent, values are an ArrayList of all broadcasted intents with
621     * that action (which should usually be one).
622     */
623    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
624            new HashMap<String, ArrayList<Intent>>();
625
626    /**
627     * All currently running services.
628     */
629    final HashMap<ComponentName, ServiceRecord> mServices =
630        new HashMap<ComponentName, ServiceRecord>();
631
632    /**
633     * All currently running services indexed by the Intent used to start them.
634     */
635    final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
636        new HashMap<Intent.FilterComparison, ServiceRecord>();
637
638    /**
639     * All currently bound service connections.  Keys are the IBinder of
640     * the client's IServiceConnection.
641     */
642    final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
643            = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
644
645    /**
646     * List of services that we have been asked to start,
647     * but haven't yet been able to.  It is used to hold start requests
648     * while waiting for their corresponding application thread to get
649     * going.
650     */
651    final ArrayList<ServiceRecord> mPendingServices
652            = new ArrayList<ServiceRecord>();
653
654    /**
655     * List of services that are scheduled to restart following a crash.
656     */
657    final ArrayList<ServiceRecord> mRestartingServices
658            = new ArrayList<ServiceRecord>();
659
660    /**
661     * List of services that are in the process of being stopped.
662     */
663    final ArrayList<ServiceRecord> mStoppingServices
664            = new ArrayList<ServiceRecord>();
665
666    /**
667     * Backup/restore process management
668     */
669    String mBackupAppName = null;
670    BackupRecord mBackupTarget = null;
671
672    /**
673     * List of PendingThumbnailsRecord objects of clients who are still
674     * waiting to receive all of the thumbnails for a task.
675     */
676    final ArrayList mPendingThumbnails = new ArrayList();
677
678    /**
679     * List of HistoryRecord objects that have been finished and must
680     * still report back to a pending thumbnail receiver.
681     */
682    final ArrayList mCancelledThumbnails = new ArrayList();
683
684    /**
685     * All of the currently running global content providers.  Keys are a
686     * string containing the provider name and values are a
687     * ContentProviderRecord object containing the data about it.  Note
688     * that a single provider may be published under multiple names, so
689     * there may be multiple entries here for a single one in mProvidersByClass.
690     */
691    final HashMap<String, ContentProviderRecord> mProvidersByName
692            = new HashMap<String, ContentProviderRecord>();
693
694    /**
695     * All of the currently running global content providers.  Keys are a
696     * string containing the provider's implementation class and values are a
697     * ContentProviderRecord object containing the data about it.
698     */
699    final HashMap<String, ContentProviderRecord> mProvidersByClass
700            = new HashMap<String, ContentProviderRecord>();
701
702    /**
703     * List of content providers who have clients waiting for them.  The
704     * application is currently being launched and the provider will be
705     * removed from this list once it is published.
706     */
707    final ArrayList<ContentProviderRecord> mLaunchingProviders
708            = new ArrayList<ContentProviderRecord>();
709
710    /**
711     * Global set of specific Uri permissions that have been granted.
712     */
713    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
714            = new SparseArray<HashMap<Uri, UriPermission>>();
715
716    /**
717     * Thread-local storage used to carry caller permissions over through
718     * indirect content-provider access.
719     * @see #ActivityManagerService.openContentUri()
720     */
721    private class Identity {
722        public int pid;
723        public int uid;
724
725        Identity(int _pid, int _uid) {
726            pid = _pid;
727            uid = _uid;
728        }
729    }
730    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
731
732    /**
733     * All information we have collected about the runtime performance of
734     * any user id that can impact battery performance.
735     */
736    final BatteryStatsService mBatteryStatsService;
737
738    /**
739     * information about component usage
740     */
741    final UsageStatsService mUsageStatsService;
742
743    /**
744     * Current configuration information.  HistoryRecord objects are given
745     * a reference to this object to indicate which configuration they are
746     * currently running in, so this object must be kept immutable.
747     */
748    Configuration mConfiguration = new Configuration();
749
750    /**
751     * Current sequencing integer of the configuration, for skipping old
752     * configurations.
753     */
754    int mConfigurationSeq = 0;
755
756    /**
757     * Hardware-reported OpenGLES version.
758     */
759    final int GL_ES_VERSION;
760
761    /**
762     * List of initialization arguments to pass to all processes when binding applications to them.
763     * For example, references to the commonly used services.
764     */
765    HashMap<String, IBinder> mAppBindArgs;
766
767    /**
768     * Temporary to avoid allocations.  Protected by main lock.
769     */
770    final StringBuilder mStringBuilder = new StringBuilder(256);
771
772    /**
773     * Used to control how we initialize the service.
774     */
775    boolean mStartRunning = false;
776    ComponentName mTopComponent;
777    String mTopAction;
778    String mTopData;
779    boolean mProcessesReady = false;
780    boolean mSystemReady = false;
781    boolean mBooting = false;
782    boolean mWaitingUpdate = false;
783    boolean mDidUpdate = false;
784    boolean mOnBattery = false;
785    boolean mLaunchWarningShown = false;
786
787    Context mContext;
788
789    int mFactoryTest;
790
791    boolean mCheckedForSetup;
792
793    /**
794     * The time at which we will allow normal application switches again,
795     * after a call to {@link #stopAppSwitches()}.
796     */
797    long mAppSwitchesAllowedTime;
798
799    /**
800     * This is set to true after the first switch after mAppSwitchesAllowedTime
801     * is set; any switches after that will clear the time.
802     */
803    boolean mDidAppSwitch;
804
805    /**
806     * Last time (in realtime) at which we checked for power usage.
807     */
808    long mLastPowerCheckRealtime;
809
810    /**
811     * Last time (in uptime) at which we checked for power usage.
812     */
813    long mLastPowerCheckUptime;
814
815    /**
816     * Set while we are wanting to sleep, to prevent any
817     * activities from being started/resumed.
818     */
819    boolean mSleeping = false;
820
821    /**
822     * Set if we are shutting down the system, similar to sleeping.
823     */
824    boolean mShuttingDown = false;
825
826    /**
827     * Task identifier that activities are currently being started
828     * in.  Incremented each time a new task is created.
829     * todo: Replace this with a TokenSpace class that generates non-repeating
830     * integers that won't wrap.
831     */
832    int mCurTask = 1;
833
834    /**
835     * Current sequence id for oom_adj computation traversal.
836     */
837    int mAdjSeq = 0;
838
839    /**
840     * Current sequence id for process LRU updating.
841     */
842    int mLruSeq = 0;
843
844    /**
845     * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
846     * is set, indicating the user wants processes started in such a way
847     * that they can use ANDROID_PROCESS_WRAPPER and know what will be
848     * running in each process (thus no pre-initialized process, etc).
849     */
850    boolean mSimpleProcessManagement = false;
851
852    /**
853     * System monitoring: number of processes that died since the last
854     * N procs were started.
855     */
856    int[] mProcDeaths = new int[20];
857
858    /**
859     * This is set if we had to do a delayed dexopt of an app before launching
860     * it, to increasing the ANR timeouts in that case.
861     */
862    boolean mDidDexOpt;
863
864    String mDebugApp = null;
865    boolean mWaitForDebugger = false;
866    boolean mDebugTransient = false;
867    String mOrigDebugApp = null;
868    boolean mOrigWaitForDebugger = false;
869    boolean mAlwaysFinishActivities = false;
870    IActivityController mController = null;
871
872    final RemoteCallbackList<IActivityWatcher> mWatchers
873            = new RemoteCallbackList<IActivityWatcher>();
874
875    /**
876     * Callback of last caller to {@link #requestPss}.
877     */
878    Runnable mRequestPssCallback;
879
880    /**
881     * Remaining processes for which we are waiting results from the last
882     * call to {@link #requestPss}.
883     */
884    final ArrayList<ProcessRecord> mRequestPssList
885            = new ArrayList<ProcessRecord>();
886
887    /**
888     * Runtime statistics collection thread.  This object's lock is used to
889     * protect all related state.
890     */
891    final Thread mProcessStatsThread;
892
893    /**
894     * Used to collect process stats when showing not responding dialog.
895     * Protected by mProcessStatsThread.
896     */
897    final ProcessStats mProcessStats = new ProcessStats(
898            MONITOR_THREAD_CPU_USAGE);
899    final AtomicLong mLastCpuTime = new AtomicLong(0);
900    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
901
902    long mLastWriteTime = 0;
903
904    /**
905     * Set to true after the system has finished booting.
906     */
907    boolean mBooted = false;
908
909    int mProcessLimit = 0;
910
911    WindowManagerService mWindowManager;
912
913    static ActivityManagerService mSelf;
914    static ActivityThread mSystemThread;
915
916    private final class AppDeathRecipient implements IBinder.DeathRecipient {
917        final ProcessRecord mApp;
918        final int mPid;
919        final IApplicationThread mAppThread;
920
921        AppDeathRecipient(ProcessRecord app, int pid,
922                IApplicationThread thread) {
923            if (localLOGV) Slog.v(
924                TAG, "New death recipient " + this
925                + " for thread " + thread.asBinder());
926            mApp = app;
927            mPid = pid;
928            mAppThread = thread;
929        }
930
931        public void binderDied() {
932            if (localLOGV) Slog.v(
933                TAG, "Death received in " + this
934                + " for thread " + mAppThread.asBinder());
935            synchronized(ActivityManagerService.this) {
936                appDiedLocked(mApp, mPid, mAppThread);
937            }
938        }
939    }
940
941    static final int SHOW_ERROR_MSG = 1;
942    static final int SHOW_NOT_RESPONDING_MSG = 2;
943    static final int SHOW_FACTORY_ERROR_MSG = 3;
944    static final int UPDATE_CONFIGURATION_MSG = 4;
945    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
946    static final int WAIT_FOR_DEBUGGER_MSG = 6;
947    static final int BROADCAST_INTENT_MSG = 7;
948    static final int BROADCAST_TIMEOUT_MSG = 8;
949    static final int SERVICE_TIMEOUT_MSG = 12;
950    static final int UPDATE_TIME_ZONE = 13;
951    static final int SHOW_UID_ERROR_MSG = 14;
952    static final int IM_FEELING_LUCKY_MSG = 15;
953    static final int PROC_START_TIMEOUT_MSG = 20;
954    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
955    static final int KILL_APPLICATION_MSG = 22;
956    static final int FINALIZE_PENDING_INTENT_MSG = 23;
957    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
958    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
959    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
960    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
961
962    AlertDialog mUidAlert;
963
964    final Handler mHandler = new Handler() {
965        //public Handler() {
966        //    if (localLOGV) Slog.v(TAG, "Handler started!");
967        //}
968
969        public void handleMessage(Message msg) {
970            switch (msg.what) {
971            case SHOW_ERROR_MSG: {
972                HashMap data = (HashMap) msg.obj;
973                synchronized (ActivityManagerService.this) {
974                    ProcessRecord proc = (ProcessRecord)data.get("app");
975                    if (proc != null && proc.crashDialog != null) {
976                        Slog.e(TAG, "App already has crash dialog: " + proc);
977                        return;
978                    }
979                    AppErrorResult res = (AppErrorResult) data.get("result");
980                    if (!mSleeping && !mShuttingDown) {
981                        Dialog d = new AppErrorDialog(mContext, res, proc);
982                        d.show();
983                        proc.crashDialog = d;
984                    } else {
985                        // The device is asleep, so just pretend that the user
986                        // saw a crash dialog and hit "force quit".
987                        res.set(0);
988                    }
989                }
990
991                ensureBootCompleted();
992            } break;
993            case SHOW_NOT_RESPONDING_MSG: {
994                synchronized (ActivityManagerService.this) {
995                    HashMap data = (HashMap) msg.obj;
996                    ProcessRecord proc = (ProcessRecord)data.get("app");
997                    if (proc != null && proc.anrDialog != null) {
998                        Slog.e(TAG, "App already has anr dialog: " + proc);
999                        return;
1000                    }
1001
1002                    Intent intent = new Intent("android.intent.action.ANR");
1003                    if (!mProcessesReady) {
1004                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1005                    }
1006                    broadcastIntentLocked(null, null, intent,
1007                            null, null, 0, null, null, null,
1008                            false, false, MY_PID, Process.SYSTEM_UID);
1009
1010                    Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1011                            mContext, proc, (ActivityRecord)data.get("activity"));
1012                    d.show();
1013                    proc.anrDialog = d;
1014                }
1015
1016                ensureBootCompleted();
1017            } break;
1018            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1019                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1020                synchronized (ActivityManagerService.this) {
1021                    ProcessRecord proc = (ProcessRecord) data.get("app");
1022                    if (proc == null) {
1023                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1024                        break;
1025                    }
1026                    if (proc.crashDialog != null) {
1027                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1028                        return;
1029                    }
1030                    AppErrorResult res = (AppErrorResult) data.get("result");
1031                    if (!mSleeping && !mShuttingDown) {
1032                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
1033                        d.show();
1034                        proc.crashDialog = d;
1035                    } else {
1036                        // The device is asleep, so just pretend that the user
1037                        // saw a crash dialog and hit "force quit".
1038                        res.set(0);
1039                    }
1040                }
1041                ensureBootCompleted();
1042            } break;
1043            case SHOW_FACTORY_ERROR_MSG: {
1044                Dialog d = new FactoryErrorDialog(
1045                    mContext, msg.getData().getCharSequence("msg"));
1046                d.show();
1047                ensureBootCompleted();
1048            } break;
1049            case UPDATE_CONFIGURATION_MSG: {
1050                final ContentResolver resolver = mContext.getContentResolver();
1051                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1052            } break;
1053            case GC_BACKGROUND_PROCESSES_MSG: {
1054                synchronized (ActivityManagerService.this) {
1055                    performAppGcsIfAppropriateLocked();
1056                }
1057            } break;
1058            case WAIT_FOR_DEBUGGER_MSG: {
1059                synchronized (ActivityManagerService.this) {
1060                    ProcessRecord app = (ProcessRecord)msg.obj;
1061                    if (msg.arg1 != 0) {
1062                        if (!app.waitedForDebugger) {
1063                            Dialog d = new AppWaitingForDebuggerDialog(
1064                                    ActivityManagerService.this,
1065                                    mContext, app);
1066                            app.waitDialog = d;
1067                            app.waitedForDebugger = true;
1068                            d.show();
1069                        }
1070                    } else {
1071                        if (app.waitDialog != null) {
1072                            app.waitDialog.dismiss();
1073                            app.waitDialog = null;
1074                        }
1075                    }
1076                }
1077            } break;
1078            case BROADCAST_INTENT_MSG: {
1079                if (DEBUG_BROADCAST) Slog.v(
1080                        TAG, "Received BROADCAST_INTENT_MSG");
1081                processNextBroadcast(true);
1082            } break;
1083            case BROADCAST_TIMEOUT_MSG: {
1084                synchronized (ActivityManagerService.this) {
1085                    broadcastTimeoutLocked(true);
1086                }
1087            } break;
1088            case SERVICE_TIMEOUT_MSG: {
1089                if (mDidDexOpt) {
1090                    mDidDexOpt = false;
1091                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1092                    nmsg.obj = msg.obj;
1093                    mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1094                    return;
1095                }
1096                serviceTimeout((ProcessRecord)msg.obj);
1097            } break;
1098            case UPDATE_TIME_ZONE: {
1099                synchronized (ActivityManagerService.this) {
1100                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1101                        ProcessRecord r = mLruProcesses.get(i);
1102                        if (r.thread != null) {
1103                            try {
1104                                r.thread.updateTimeZone();
1105                            } catch (RemoteException ex) {
1106                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1107                            }
1108                        }
1109                    }
1110                }
1111            } break;
1112            case SHOW_UID_ERROR_MSG: {
1113                // XXX This is a temporary dialog, no need to localize.
1114                AlertDialog d = new BaseErrorDialog(mContext);
1115                d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1116                d.setCancelable(false);
1117                d.setTitle("System UIDs Inconsistent");
1118                d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
1119                d.setButton("I'm Feeling Lucky",
1120                        mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1121                mUidAlert = d;
1122                d.show();
1123            } break;
1124            case IM_FEELING_LUCKY_MSG: {
1125                if (mUidAlert != null) {
1126                    mUidAlert.dismiss();
1127                    mUidAlert = null;
1128                }
1129            } break;
1130            case PROC_START_TIMEOUT_MSG: {
1131                if (mDidDexOpt) {
1132                    mDidDexOpt = false;
1133                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1134                    nmsg.obj = msg.obj;
1135                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1136                    return;
1137                }
1138                ProcessRecord app = (ProcessRecord)msg.obj;
1139                synchronized (ActivityManagerService.this) {
1140                    processStartTimedOutLocked(app);
1141                }
1142            } break;
1143            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1144                synchronized (ActivityManagerService.this) {
1145                    doPendingActivityLaunchesLocked(true);
1146                }
1147            } break;
1148            case KILL_APPLICATION_MSG: {
1149                synchronized (ActivityManagerService.this) {
1150                    int uid = msg.arg1;
1151                    boolean restart = (msg.arg2 == 1);
1152                    String pkg = (String) msg.obj;
1153                    forceStopPackageLocked(pkg, uid, restart, false, true);
1154                }
1155            } break;
1156            case FINALIZE_PENDING_INTENT_MSG: {
1157                ((PendingIntentRecord)msg.obj).completeFinalize();
1158            } break;
1159            case POST_HEAVY_NOTIFICATION_MSG: {
1160                INotificationManager inm = NotificationManager.getService();
1161                if (inm == null) {
1162                    return;
1163                }
1164
1165                ActivityRecord root = (ActivityRecord)msg.obj;
1166                ProcessRecord process = root.app;
1167                if (process == null) {
1168                    return;
1169                }
1170
1171                try {
1172                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1173                    String text = mContext.getString(R.string.heavy_weight_notification,
1174                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1175                    Notification notification = new Notification();
1176                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1177                    notification.when = 0;
1178                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1179                    notification.tickerText = text;
1180                    notification.defaults = 0; // please be quiet
1181                    notification.sound = null;
1182                    notification.vibrate = null;
1183                    notification.setLatestEventInfo(context, text,
1184                            mContext.getText(R.string.heavy_weight_notification_detail),
1185                            PendingIntent.getActivity(mContext, 0, root.intent,
1186                                    PendingIntent.FLAG_CANCEL_CURRENT));
1187
1188                    try {
1189                        int[] outId = new int[1];
1190                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
1191                                notification, outId);
1192                    } catch (RuntimeException e) {
1193                        Slog.w(ActivityManagerService.TAG,
1194                                "Error showing notification for heavy-weight app", e);
1195                    } catch (RemoteException e) {
1196                    }
1197                } catch (NameNotFoundException e) {
1198                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1199                }
1200            } break;
1201            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1202                INotificationManager inm = NotificationManager.getService();
1203                if (inm == null) {
1204                    return;
1205                }
1206                try {
1207                    inm.cancelNotification("android",
1208                            R.string.heavy_weight_notification);
1209                } catch (RuntimeException e) {
1210                    Slog.w(ActivityManagerService.TAG,
1211                            "Error canceling notification for service", e);
1212                } catch (RemoteException e) {
1213                }
1214            } break;
1215            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1216                synchronized (ActivityManagerService.this) {
1217                    checkExcessivePowerUsageLocked(true);
1218                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1219                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1220                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1221                }
1222            } break;
1223            }
1224        }
1225    };
1226
1227    public static void setSystemProcess() {
1228        try {
1229            ActivityManagerService m = mSelf;
1230
1231            ServiceManager.addService("activity", m);
1232            ServiceManager.addService("meminfo", new MemBinder(m));
1233            if (MONITOR_CPU_USAGE) {
1234                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1235            }
1236            ServiceManager.addService("permission", new PermissionController(m));
1237
1238            ApplicationInfo info =
1239                mSelf.mContext.getPackageManager().getApplicationInfo(
1240                        "android", STOCK_PM_FLAGS);
1241            mSystemThread.installSystemApplicationInfo(info);
1242
1243            synchronized (mSelf) {
1244                ProcessRecord app = mSelf.newProcessRecordLocked(
1245                        mSystemThread.getApplicationThread(), info,
1246                        info.processName);
1247                app.persistent = true;
1248                app.pid = MY_PID;
1249                app.maxAdj = SYSTEM_ADJ;
1250                mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1251                synchronized (mSelf.mPidsSelfLocked) {
1252                    mSelf.mPidsSelfLocked.put(app.pid, app);
1253                }
1254                mSelf.updateLruProcessLocked(app, true, true);
1255            }
1256        } catch (PackageManager.NameNotFoundException e) {
1257            throw new RuntimeException(
1258                    "Unable to find android system package", e);
1259        }
1260    }
1261
1262    public void setWindowManager(WindowManagerService wm) {
1263        mWindowManager = wm;
1264    }
1265
1266    public static final Context main(int factoryTest) {
1267        AThread thr = new AThread();
1268        thr.start();
1269
1270        synchronized (thr) {
1271            while (thr.mService == null) {
1272                try {
1273                    thr.wait();
1274                } catch (InterruptedException e) {
1275                }
1276            }
1277        }
1278
1279        ActivityManagerService m = thr.mService;
1280        mSelf = m;
1281        ActivityThread at = ActivityThread.systemMain();
1282        mSystemThread = at;
1283        Context context = at.getSystemContext();
1284        m.mContext = context;
1285        m.mFactoryTest = factoryTest;
1286        m.mMainStack = new ActivityStack(m, context, true);
1287
1288        m.mBatteryStatsService.publish(context);
1289        m.mUsageStatsService.publish(context);
1290
1291        synchronized (thr) {
1292            thr.mReady = true;
1293            thr.notifyAll();
1294        }
1295
1296        m.startRunning(null, null, null, null);
1297
1298        return context;
1299    }
1300
1301    public static ActivityManagerService self() {
1302        return mSelf;
1303    }
1304
1305    static class AThread extends Thread {
1306        ActivityManagerService mService;
1307        boolean mReady = false;
1308
1309        public AThread() {
1310            super("ActivityManager");
1311        }
1312
1313        public void run() {
1314            Looper.prepare();
1315
1316            android.os.Process.setThreadPriority(
1317                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1318            android.os.Process.setCanSelfBackground(false);
1319
1320            ActivityManagerService m = new ActivityManagerService();
1321
1322            synchronized (this) {
1323                mService = m;
1324                notifyAll();
1325            }
1326
1327            synchronized (this) {
1328                while (!mReady) {
1329                    try {
1330                        wait();
1331                    } catch (InterruptedException e) {
1332                    }
1333                }
1334            }
1335
1336            Looper.loop();
1337        }
1338    }
1339
1340    static class MemBinder extends Binder {
1341        ActivityManagerService mActivityManagerService;
1342        MemBinder(ActivityManagerService activityManagerService) {
1343            mActivityManagerService = activityManagerService;
1344        }
1345
1346        @Override
1347        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1348            ActivityManagerService service = mActivityManagerService;
1349            ArrayList<ProcessRecord> procs;
1350            synchronized (mActivityManagerService) {
1351                if (args != null && args.length > 0
1352                        && args[0].charAt(0) != '-') {
1353                    procs = new ArrayList<ProcessRecord>();
1354                    int pid = -1;
1355                    try {
1356                        pid = Integer.parseInt(args[0]);
1357                    } catch (NumberFormatException e) {
1358
1359                    }
1360                    for (int i=service.mLruProcesses.size()-1; i>=0; i--) {
1361                        ProcessRecord proc = service.mLruProcesses.get(i);
1362                        if (proc.pid == pid) {
1363                            procs.add(proc);
1364                        } else if (proc.processName.equals(args[0])) {
1365                            procs.add(proc);
1366                        }
1367                    }
1368                    if (procs.size() <= 0) {
1369                        pw.println("No process found for: " + args[0]);
1370                        return;
1371                    }
1372                } else {
1373                    procs = new ArrayList<ProcessRecord>(service.mLruProcesses);
1374                }
1375            }
1376            dumpApplicationMemoryUsage(fd, pw, procs, "  ", args);
1377        }
1378    }
1379
1380    static class CpuBinder extends Binder {
1381        ActivityManagerService mActivityManagerService;
1382        CpuBinder(ActivityManagerService activityManagerService) {
1383            mActivityManagerService = activityManagerService;
1384        }
1385
1386        @Override
1387        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1388            synchronized (mActivityManagerService.mProcessStatsThread) {
1389                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1390                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1391                        SystemClock.uptimeMillis()));
1392            }
1393        }
1394    }
1395
1396    private ActivityManagerService() {
1397        String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
1398        if (v != null && Integer.getInteger(v) != 0) {
1399            mSimpleProcessManagement = true;
1400        }
1401        v = System.getenv("ANDROID_DEBUG_APP");
1402        if (v != null) {
1403            mSimpleProcessManagement = true;
1404        }
1405
1406        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1407
1408        File dataDir = Environment.getDataDirectory();
1409        File systemDir = new File(dataDir, "system");
1410        systemDir.mkdirs();
1411        mBatteryStatsService = new BatteryStatsService(new File(
1412                systemDir, "batterystats.bin").toString());
1413        mBatteryStatsService.getActiveStatistics().readLocked();
1414        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1415        mOnBattery = DEBUG_POWER ? true
1416                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1417        mBatteryStatsService.getActiveStatistics().setCallback(this);
1418
1419        mUsageStatsService = new UsageStatsService(new File(
1420                systemDir, "usagestats").toString());
1421
1422        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1423            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1424
1425        mConfiguration.setToDefaults();
1426        mConfiguration.locale = Locale.getDefault();
1427        mProcessStats.init();
1428
1429        // Add ourself to the Watchdog monitors.
1430        Watchdog.getInstance().addMonitor(this);
1431
1432        mProcessStatsThread = new Thread("ProcessStats") {
1433            public void run() {
1434                while (true) {
1435                    try {
1436                        try {
1437                            synchronized(this) {
1438                                final long now = SystemClock.uptimeMillis();
1439                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1440                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1441                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1442                                //        + ", write delay=" + nextWriteDelay);
1443                                if (nextWriteDelay < nextCpuDelay) {
1444                                    nextCpuDelay = nextWriteDelay;
1445                                }
1446                                if (nextCpuDelay > 0) {
1447                                    mProcessStatsMutexFree.set(true);
1448                                    this.wait(nextCpuDelay);
1449                                }
1450                            }
1451                        } catch (InterruptedException e) {
1452                        }
1453                        updateCpuStatsNow();
1454                    } catch (Exception e) {
1455                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1456                    }
1457                }
1458            }
1459        };
1460        mProcessStatsThread.start();
1461    }
1462
1463    @Override
1464    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1465            throws RemoteException {
1466        try {
1467            return super.onTransact(code, data, reply, flags);
1468        } catch (RuntimeException e) {
1469            // The activity manager only throws security exceptions, so let's
1470            // log all others.
1471            if (!(e instanceof SecurityException)) {
1472                Slog.e(TAG, "Activity Manager Crash", e);
1473            }
1474            throw e;
1475        }
1476    }
1477
1478    void updateCpuStats() {
1479        final long now = SystemClock.uptimeMillis();
1480        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1481            return;
1482        }
1483        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1484            synchronized (mProcessStatsThread) {
1485                mProcessStatsThread.notify();
1486            }
1487        }
1488    }
1489
1490    void updateCpuStatsNow() {
1491        synchronized (mProcessStatsThread) {
1492            mProcessStatsMutexFree.set(false);
1493            final long now = SystemClock.uptimeMillis();
1494            boolean haveNewCpuStats = false;
1495
1496            if (MONITOR_CPU_USAGE &&
1497                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1498                mLastCpuTime.set(now);
1499                haveNewCpuStats = true;
1500                mProcessStats.update();
1501                //Slog.i(TAG, mProcessStats.printCurrentState());
1502                //Slog.i(TAG, "Total CPU usage: "
1503                //        + mProcessStats.getTotalCpuPercent() + "%");
1504
1505                // Slog the cpu usage if the property is set.
1506                if ("true".equals(SystemProperties.get("events.cpu"))) {
1507                    int user = mProcessStats.getLastUserTime();
1508                    int system = mProcessStats.getLastSystemTime();
1509                    int iowait = mProcessStats.getLastIoWaitTime();
1510                    int irq = mProcessStats.getLastIrqTime();
1511                    int softIrq = mProcessStats.getLastSoftIrqTime();
1512                    int idle = mProcessStats.getLastIdleTime();
1513
1514                    int total = user + system + iowait + irq + softIrq + idle;
1515                    if (total == 0) total = 1;
1516
1517                    EventLog.writeEvent(EventLogTags.CPU,
1518                            ((user+system+iowait+irq+softIrq) * 100) / total,
1519                            (user * 100) / total,
1520                            (system * 100) / total,
1521                            (iowait * 100) / total,
1522                            (irq * 100) / total,
1523                            (softIrq * 100) / total);
1524                }
1525            }
1526
1527            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1528            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1529            synchronized(bstats) {
1530                synchronized(mPidsSelfLocked) {
1531                    if (haveNewCpuStats) {
1532                        if (mOnBattery) {
1533                            int perc = bstats.startAddingCpuLocked();
1534                            int totalUTime = 0;
1535                            int totalSTime = 0;
1536                            final int N = mProcessStats.countStats();
1537                            for (int i=0; i<N; i++) {
1538                                ProcessStats.Stats st = mProcessStats.getStats(i);
1539                                if (!st.working) {
1540                                    continue;
1541                                }
1542                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1543                                int otherUTime = (st.rel_utime*perc)/100;
1544                                int otherSTime = (st.rel_stime*perc)/100;
1545                                totalUTime += otherUTime;
1546                                totalSTime += otherSTime;
1547                                if (pr != null) {
1548                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1549                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1550                                            st.rel_stime-otherSTime);
1551                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1552                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1553                                } else {
1554                                    BatteryStatsImpl.Uid.Proc ps =
1555                                            bstats.getProcessStatsLocked(st.name, st.pid);
1556                                    if (ps != null) {
1557                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1558                                                st.rel_stime-otherSTime);
1559                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1560                                    }
1561                                }
1562                            }
1563                            bstats.finishAddingCpuLocked(perc, totalUTime,
1564                                    totalSTime, cpuSpeedTimes);
1565                        }
1566                    }
1567                }
1568
1569                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1570                    mLastWriteTime = now;
1571                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1572                }
1573            }
1574        }
1575    }
1576
1577    @Override
1578    public void batteryNeedsCpuUpdate() {
1579        updateCpuStatsNow();
1580    }
1581
1582    @Override
1583    public void batteryPowerChanged(boolean onBattery) {
1584        // When plugging in, update the CPU stats first before changing
1585        // the plug state.
1586        updateCpuStatsNow();
1587        synchronized (this) {
1588            synchronized(mPidsSelfLocked) {
1589                mOnBattery = DEBUG_POWER ? true : onBattery;
1590            }
1591        }
1592    }
1593
1594    /**
1595     * Initialize the application bind args. These are passed to each
1596     * process when the bindApplication() IPC is sent to the process. They're
1597     * lazily setup to make sure the services are running when they're asked for.
1598     */
1599    private HashMap<String, IBinder> getCommonServicesLocked() {
1600        if (mAppBindArgs == null) {
1601            mAppBindArgs = new HashMap<String, IBinder>();
1602
1603            // Setup the application init args
1604            mAppBindArgs.put("package", ServiceManager.getService("package"));
1605            mAppBindArgs.put("window", ServiceManager.getService("window"));
1606            mAppBindArgs.put(Context.ALARM_SERVICE,
1607                    ServiceManager.getService(Context.ALARM_SERVICE));
1608        }
1609        return mAppBindArgs;
1610    }
1611
1612    final void setFocusedActivityLocked(ActivityRecord r) {
1613        if (mFocusedActivity != r) {
1614            mFocusedActivity = r;
1615            mWindowManager.setFocusedApp(r, true);
1616        }
1617    }
1618
1619    private final void updateLruProcessInternalLocked(ProcessRecord app,
1620            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1621        // put it on the LRU to keep track of when it should be exited.
1622        int lrui = mLruProcesses.indexOf(app);
1623        if (lrui >= 0) mLruProcesses.remove(lrui);
1624
1625        int i = mLruProcesses.size()-1;
1626        int skipTop = 0;
1627
1628        app.lruSeq = mLruSeq;
1629
1630        // compute the new weight for this process.
1631        if (updateActivityTime) {
1632            app.lastActivityTime = SystemClock.uptimeMillis();
1633        }
1634        if (app.activities.size() > 0) {
1635            // If this process has activities, we more strongly want to keep
1636            // it around.
1637            app.lruWeight = app.lastActivityTime;
1638        } else if (app.pubProviders.size() > 0) {
1639            // If this process contains content providers, we want to keep
1640            // it a little more strongly.
1641            app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
1642            // Also don't let it kick out the first few "real" hidden processes.
1643            skipTop = MIN_HIDDEN_APPS;
1644        } else {
1645            // If this process doesn't have activities, we less strongly
1646            // want to keep it around, and generally want to avoid getting
1647            // in front of any very recently used activities.
1648            app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
1649            // Also don't let it kick out the first few "real" hidden processes.
1650            skipTop = MIN_HIDDEN_APPS;
1651        }
1652
1653        while (i >= 0) {
1654            ProcessRecord p = mLruProcesses.get(i);
1655            // If this app shouldn't be in front of the first N background
1656            // apps, then skip over that many that are currently hidden.
1657            if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
1658                skipTop--;
1659            }
1660            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1661                mLruProcesses.add(i+1, app);
1662                break;
1663            }
1664            i--;
1665        }
1666        if (i < 0) {
1667            mLruProcesses.add(0, app);
1668        }
1669
1670        // If the app is currently using a content provider or service,
1671        // bump those processes as well.
1672        if (app.connections.size() > 0) {
1673            for (ConnectionRecord cr : app.connections) {
1674                if (cr.binding != null && cr.binding.service != null
1675                        && cr.binding.service.app != null
1676                        && cr.binding.service.app.lruSeq != mLruSeq) {
1677                    updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1678                            updateActivityTime, i+1);
1679                }
1680            }
1681        }
1682        if (app.conProviders.size() > 0) {
1683            for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1684                if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1685                    updateLruProcessInternalLocked(cpr.app, oomAdj,
1686                            updateActivityTime, i+1);
1687                }
1688            }
1689        }
1690
1691        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1692        if (oomAdj) {
1693            updateOomAdjLocked();
1694        }
1695    }
1696
1697    final void updateLruProcessLocked(ProcessRecord app,
1698            boolean oomAdj, boolean updateActivityTime) {
1699        mLruSeq++;
1700        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1701    }
1702
1703    final ProcessRecord getProcessRecordLocked(
1704            String processName, int uid) {
1705        if (uid == Process.SYSTEM_UID) {
1706            // The system gets to run in any process.  If there are multiple
1707            // processes with the same uid, just pick the first (this
1708            // should never happen).
1709            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1710                    processName);
1711            return procs != null ? procs.valueAt(0) : null;
1712        }
1713        ProcessRecord proc = mProcessNames.get(processName, uid);
1714        return proc;
1715    }
1716
1717    void ensurePackageDexOpt(String packageName) {
1718        IPackageManager pm = AppGlobals.getPackageManager();
1719        try {
1720            if (pm.performDexOpt(packageName)) {
1721                mDidDexOpt = true;
1722            }
1723        } catch (RemoteException e) {
1724        }
1725    }
1726
1727    boolean isNextTransitionForward() {
1728        int transit = mWindowManager.getPendingAppTransition();
1729        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1730                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1731                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1732    }
1733
1734    final ProcessRecord startProcessLocked(String processName,
1735            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1736            String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
1737        ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1738        // We don't have to do anything more if:
1739        // (1) There is an existing application record; and
1740        // (2) The caller doesn't think it is dead, OR there is no thread
1741        //     object attached to it so we know it couldn't have crashed; and
1742        // (3) There is a pid assigned to it, so it is either starting or
1743        //     already running.
1744        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1745                + " app=" + app + " knownToBeDead=" + knownToBeDead
1746                + " thread=" + (app != null ? app.thread : null)
1747                + " pid=" + (app != null ? app.pid : -1));
1748        if (app != null && app.pid > 0) {
1749            if (!knownToBeDead || app.thread == null) {
1750                // We already have the app running, or are waiting for it to
1751                // come up (we have a pid but not yet its thread), so keep it.
1752                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1753                return app;
1754            } else {
1755                // An application record is attached to a previous process,
1756                // clean it up now.
1757                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1758                handleAppDiedLocked(app, true);
1759            }
1760        }
1761
1762        String hostingNameStr = hostingName != null
1763                ? hostingName.flattenToShortString() : null;
1764
1765        if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1766            // If we are in the background, then check to see if this process
1767            // is bad.  If so, we will just silently fail.
1768            if (mBadProcesses.get(info.processName, info.uid) != null) {
1769                if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1770                        + "/" + info.processName);
1771                return null;
1772            }
1773        } else {
1774            // When the user is explicitly starting a process, then clear its
1775            // crash count so that we won't make it bad until they see at
1776            // least one crash dialog again, and make the process good again
1777            // if it had been bad.
1778            if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1779                    + "/" + info.processName);
1780            mProcessCrashTimes.remove(info.processName, info.uid);
1781            if (mBadProcesses.get(info.processName, info.uid) != null) {
1782                EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1783                        info.processName);
1784                mBadProcesses.remove(info.processName, info.uid);
1785                if (app != null) {
1786                    app.bad = false;
1787                }
1788            }
1789        }
1790
1791        if (app == null) {
1792            app = newProcessRecordLocked(null, info, processName);
1793            mProcessNames.put(processName, info.uid, app);
1794        } else {
1795            // If this is a new package in the process, add the package to the list
1796            app.addPackage(info.packageName);
1797        }
1798
1799        // If the system is not ready yet, then hold off on starting this
1800        // process until it is.
1801        if (!mProcessesReady
1802                && !isAllowedWhileBooting(info)
1803                && !allowWhileBooting) {
1804            if (!mProcessesOnHold.contains(app)) {
1805                mProcessesOnHold.add(app);
1806            }
1807            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1808            return app;
1809        }
1810
1811        startProcessLocked(app, hostingType, hostingNameStr);
1812        return (app.pid != 0) ? app : null;
1813    }
1814
1815    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1816        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1817    }
1818
1819    private final void startProcessLocked(ProcessRecord app,
1820            String hostingType, String hostingNameStr) {
1821        if (app.pid > 0 && app.pid != MY_PID) {
1822            synchronized (mPidsSelfLocked) {
1823                mPidsSelfLocked.remove(app.pid);
1824                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1825            }
1826            app.pid = 0;
1827        }
1828
1829        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1830                "startProcessLocked removing on hold: " + app);
1831        mProcessesOnHold.remove(app);
1832
1833        updateCpuStats();
1834
1835        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1836        mProcDeaths[0] = 0;
1837
1838        try {
1839            int uid = app.info.uid;
1840            int[] gids = null;
1841            try {
1842                gids = mContext.getPackageManager().getPackageGids(
1843                        app.info.packageName);
1844            } catch (PackageManager.NameNotFoundException e) {
1845                Slog.w(TAG, "Unable to retrieve gids", e);
1846            }
1847            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1848                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1849                        && mTopComponent != null
1850                        && app.processName.equals(mTopComponent.getPackageName())) {
1851                    uid = 0;
1852                }
1853                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1854                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1855                    uid = 0;
1856                }
1857            }
1858            int debugFlags = 0;
1859            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1860                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1861            }
1862            // Run the app in safe mode if its manifest requests so or the
1863            // system is booted in safe mode.
1864            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1865                Zygote.systemInSafeMode == true) {
1866                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1867            }
1868            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1869                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1870            }
1871            if ("1".equals(SystemProperties.get("debug.assert"))) {
1872                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1873            }
1874            int pid = Process.start("android.app.ActivityThread",
1875                    mSimpleProcessManagement ? app.processName : null, uid, uid,
1876                    gids, debugFlags, null);
1877            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1878            synchronized (bs) {
1879                if (bs.isOnBattery()) {
1880                    app.batteryStats.incStartsLocked();
1881                }
1882            }
1883
1884            EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
1885                    app.processName, hostingType,
1886                    hostingNameStr != null ? hostingNameStr : "");
1887
1888            if (app.persistent) {
1889                Watchdog.getInstance().processStarted(app.processName, pid);
1890            }
1891
1892            StringBuilder buf = mStringBuilder;
1893            buf.setLength(0);
1894            buf.append("Start proc ");
1895            buf.append(app.processName);
1896            buf.append(" for ");
1897            buf.append(hostingType);
1898            if (hostingNameStr != null) {
1899                buf.append(" ");
1900                buf.append(hostingNameStr);
1901            }
1902            buf.append(": pid=");
1903            buf.append(pid);
1904            buf.append(" uid=");
1905            buf.append(uid);
1906            buf.append(" gids={");
1907            if (gids != null) {
1908                for (int gi=0; gi<gids.length; gi++) {
1909                    if (gi != 0) buf.append(", ");
1910                    buf.append(gids[gi]);
1911
1912                }
1913            }
1914            buf.append("}");
1915            Slog.i(TAG, buf.toString());
1916            if (pid == 0 || pid == MY_PID) {
1917                // Processes are being emulated with threads.
1918                app.pid = MY_PID;
1919                app.removed = false;
1920                mStartingProcesses.add(app);
1921            } else if (pid > 0) {
1922                app.pid = pid;
1923                app.removed = false;
1924                synchronized (mPidsSelfLocked) {
1925                    this.mPidsSelfLocked.put(pid, app);
1926                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1927                    msg.obj = app;
1928                    mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
1929                }
1930            } else {
1931                app.pid = 0;
1932                RuntimeException e = new RuntimeException(
1933                        "Failure starting process " + app.processName
1934                        + ": returned pid=" + pid);
1935                Slog.e(TAG, e.getMessage(), e);
1936            }
1937        } catch (RuntimeException e) {
1938            // XXX do better error recovery.
1939            app.pid = 0;
1940            Slog.e(TAG, "Failure starting process " + app.processName, e);
1941        }
1942    }
1943
1944    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
1945        if (resumed) {
1946            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
1947        } else {
1948            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
1949        }
1950    }
1951
1952    boolean startHomeActivityLocked() {
1953        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1954                && mTopAction == null) {
1955            // We are running in factory test mode, but unable to find
1956            // the factory test app, so just sit around displaying the
1957            // error message and don't try to start anything.
1958            return false;
1959        }
1960        Intent intent = new Intent(
1961            mTopAction,
1962            mTopData != null ? Uri.parse(mTopData) : null);
1963        intent.setComponent(mTopComponent);
1964        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
1965            intent.addCategory(Intent.CATEGORY_HOME);
1966        }
1967        ActivityInfo aInfo =
1968            intent.resolveActivityInfo(mContext.getPackageManager(),
1969                    STOCK_PM_FLAGS);
1970        if (aInfo != null) {
1971            intent.setComponent(new ComponentName(
1972                    aInfo.applicationInfo.packageName, aInfo.name));
1973            // Don't do this if the home app is currently being
1974            // instrumented.
1975            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
1976                    aInfo.applicationInfo.uid);
1977            if (app == null || app.instrumentationClass == null) {
1978                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
1979                mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
1980                        null, null, 0, 0, 0, false, false);
1981            }
1982        }
1983
1984
1985        return true;
1986    }
1987
1988    /**
1989     * Starts the "new version setup screen" if appropriate.
1990     */
1991    void startSetupActivityLocked() {
1992        // Only do this once per boot.
1993        if (mCheckedForSetup) {
1994            return;
1995        }
1996
1997        // We will show this screen if the current one is a different
1998        // version than the last one shown, and we are not running in
1999        // low-level factory test mode.
2000        final ContentResolver resolver = mContext.getContentResolver();
2001        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2002                Settings.Secure.getInt(resolver,
2003                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2004            mCheckedForSetup = true;
2005
2006            // See if we should be showing the platform update setup UI.
2007            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2008            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2009                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2010
2011            // We don't allow third party apps to replace this.
2012            ResolveInfo ri = null;
2013            for (int i=0; ris != null && i<ris.size(); i++) {
2014                if ((ris.get(i).activityInfo.applicationInfo.flags
2015                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2016                    ri = ris.get(i);
2017                    break;
2018                }
2019            }
2020
2021            if (ri != null) {
2022                String vers = ri.activityInfo.metaData != null
2023                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2024                        : null;
2025                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2026                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2027                            Intent.METADATA_SETUP_VERSION);
2028                }
2029                String lastVers = Settings.Secure.getString(
2030                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2031                if (vers != null && !vers.equals(lastVers)) {
2032                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2033                    intent.setComponent(new ComponentName(
2034                            ri.activityInfo.packageName, ri.activityInfo.name));
2035                    mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
2036                            null, null, 0, 0, 0, false, false);
2037                }
2038            }
2039        }
2040    }
2041
2042    void reportResumedActivityLocked(ActivityRecord r) {
2043        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2044
2045        final int identHash = System.identityHashCode(r);
2046        updateUsageStats(r, true);
2047
2048        int i = mWatchers.beginBroadcast();
2049        while (i > 0) {
2050            i--;
2051            IActivityWatcher w = mWatchers.getBroadcastItem(i);
2052            if (w != null) {
2053                try {
2054                    w.activityResuming(identHash);
2055                } catch (RemoteException e) {
2056                }
2057            }
2058        }
2059        mWatchers.finishBroadcast();
2060    }
2061
2062    final void doPendingActivityLaunchesLocked(boolean doResume) {
2063        final int N = mPendingActivityLaunches.size();
2064        if (N <= 0) {
2065            return;
2066        }
2067        for (int i=0; i<N; i++) {
2068            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2069            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2070                    pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2071                    doResume && i == (N-1));
2072        }
2073        mPendingActivityLaunches.clear();
2074    }
2075
2076    public final int startActivity(IApplicationThread caller,
2077            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2078            int grantedMode, IBinder resultTo,
2079            String resultWho, int requestCode, boolean onlyIfNeeded,
2080            boolean debug) {
2081        return mMainStack.startActivityMayWait(caller, intent, resolvedType,
2082                grantedUriPermissions, grantedMode, resultTo, resultWho,
2083                requestCode, onlyIfNeeded, debug, null, null);
2084    }
2085
2086    public final WaitResult startActivityAndWait(IApplicationThread caller,
2087            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2088            int grantedMode, IBinder resultTo,
2089            String resultWho, int requestCode, boolean onlyIfNeeded,
2090            boolean debug) {
2091        WaitResult res = new WaitResult();
2092        mMainStack.startActivityMayWait(caller, intent, resolvedType,
2093                grantedUriPermissions, grantedMode, resultTo, resultWho,
2094                requestCode, onlyIfNeeded, debug, res, null);
2095        return res;
2096    }
2097
2098    public final int startActivityWithConfig(IApplicationThread caller,
2099            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2100            int grantedMode, IBinder resultTo,
2101            String resultWho, int requestCode, boolean onlyIfNeeded,
2102            boolean debug, Configuration config) {
2103        return mMainStack.startActivityMayWait(caller, intent, resolvedType,
2104                grantedUriPermissions, grantedMode, resultTo, resultWho,
2105                requestCode, onlyIfNeeded, debug, null, config);
2106    }
2107
2108     public int startActivityIntentSender(IApplicationThread caller,
2109            IntentSender intent, Intent fillInIntent, String resolvedType,
2110            IBinder resultTo, String resultWho, int requestCode,
2111            int flagsMask, int flagsValues) {
2112        // Refuse possible leaked file descriptors
2113        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2114            throw new IllegalArgumentException("File descriptors passed in Intent");
2115        }
2116
2117        IIntentSender sender = intent.getTarget();
2118        if (!(sender instanceof PendingIntentRecord)) {
2119            throw new IllegalArgumentException("Bad PendingIntent object");
2120        }
2121
2122        PendingIntentRecord pir = (PendingIntentRecord)sender;
2123
2124        synchronized (this) {
2125            // If this is coming from the currently resumed activity, it is
2126            // effectively saying that app switches are allowed at this point.
2127            if (mMainStack.mResumedActivity != null
2128                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2129                            Binder.getCallingUid()) {
2130                mAppSwitchesAllowedTime = 0;
2131            }
2132        }
2133
2134        return pir.sendInner(0, fillInIntent, resolvedType,
2135                null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2136    }
2137
2138    public boolean startNextMatchingActivity(IBinder callingActivity,
2139            Intent intent) {
2140        // Refuse possible leaked file descriptors
2141        if (intent != null && intent.hasFileDescriptors() == true) {
2142            throw new IllegalArgumentException("File descriptors passed in Intent");
2143        }
2144
2145        synchronized (this) {
2146            int index = mMainStack.indexOfTokenLocked(callingActivity);
2147            if (index < 0) {
2148                return false;
2149            }
2150            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
2151            if (r.app == null || r.app.thread == null) {
2152                // The caller is not running...  d'oh!
2153                return false;
2154            }
2155            intent = new Intent(intent);
2156            // The caller is not allowed to change the data.
2157            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2158            // And we are resetting to find the next component...
2159            intent.setComponent(null);
2160
2161            ActivityInfo aInfo = null;
2162            try {
2163                List<ResolveInfo> resolves =
2164                    AppGlobals.getPackageManager().queryIntentActivities(
2165                            intent, r.resolvedType,
2166                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
2167
2168                // Look for the original activity in the list...
2169                final int N = resolves != null ? resolves.size() : 0;
2170                for (int i=0; i<N; i++) {
2171                    ResolveInfo rInfo = resolves.get(i);
2172                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2173                            && rInfo.activityInfo.name.equals(r.info.name)) {
2174                        // We found the current one...  the next matching is
2175                        // after it.
2176                        i++;
2177                        if (i<N) {
2178                            aInfo = resolves.get(i).activityInfo;
2179                        }
2180                        break;
2181                    }
2182                }
2183            } catch (RemoteException e) {
2184            }
2185
2186            if (aInfo == null) {
2187                // Nobody who is next!
2188                return false;
2189            }
2190
2191            intent.setComponent(new ComponentName(
2192                    aInfo.applicationInfo.packageName, aInfo.name));
2193            intent.setFlags(intent.getFlags()&~(
2194                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2195                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2196                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2197                    Intent.FLAG_ACTIVITY_NEW_TASK));
2198
2199            // Okay now we need to start the new activity, replacing the
2200            // currently running activity.  This is a little tricky because
2201            // we want to start the new one as if the current one is finished,
2202            // but not finish the current one first so that there is no flicker.
2203            // And thus...
2204            final boolean wasFinishing = r.finishing;
2205            r.finishing = true;
2206
2207            // Propagate reply information over to the new activity.
2208            final ActivityRecord resultTo = r.resultTo;
2209            final String resultWho = r.resultWho;
2210            final int requestCode = r.requestCode;
2211            r.resultTo = null;
2212            if (resultTo != null) {
2213                resultTo.removeResultsLocked(r, resultWho, requestCode);
2214            }
2215
2216            final long origId = Binder.clearCallingIdentity();
2217            // XXX we are not dealing with propagating grantedUriPermissions...
2218            // those are not yet exposed to user code, so there is no need.
2219            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2220                    r.resolvedType, null, 0, aInfo, resultTo, resultWho,
2221                    requestCode, -1, r.launchedFromUid, false, false);
2222            Binder.restoreCallingIdentity(origId);
2223
2224            r.finishing = wasFinishing;
2225            if (res != START_SUCCESS) {
2226                return false;
2227            }
2228            return true;
2229        }
2230    }
2231
2232    public final int startActivityInPackage(int uid,
2233            Intent intent, String resolvedType, IBinder resultTo,
2234            String resultWho, int requestCode, boolean onlyIfNeeded) {
2235
2236        // This is so super not safe, that only the system (or okay root)
2237        // can do it.
2238        final int callingUid = Binder.getCallingUid();
2239        if (callingUid != 0 && callingUid != Process.myUid()) {
2240            throw new SecurityException(
2241                    "startActivityInPackage only available to the system");
2242        }
2243
2244        final boolean componentSpecified = intent.getComponent() != null;
2245
2246        // Don't modify the client's object!
2247        intent = new Intent(intent);
2248
2249        // Collect information about the target of the Intent.
2250        ActivityInfo aInfo;
2251        try {
2252            ResolveInfo rInfo =
2253                AppGlobals.getPackageManager().resolveIntent(
2254                        intent, resolvedType,
2255                        PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
2256            aInfo = rInfo != null ? rInfo.activityInfo : null;
2257        } catch (RemoteException e) {
2258            aInfo = null;
2259        }
2260
2261        if (aInfo != null) {
2262            // Store the found target back into the intent, because now that
2263            // we have it we never want to do this again.  For example, if the
2264            // user navigates back to this point in the history, we should
2265            // always restart the exact same activity.
2266            intent.setComponent(new ComponentName(
2267                    aInfo.applicationInfo.packageName, aInfo.name));
2268        }
2269
2270        synchronized(this) {
2271            return mMainStack.startActivityLocked(null, intent, resolvedType,
2272                    null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid,
2273                    onlyIfNeeded, componentSpecified);
2274        }
2275    }
2276
2277    final void addRecentTaskLocked(TaskRecord task) {
2278        // Remove any existing entries that are the same kind of task.
2279        int N = mRecentTasks.size();
2280        for (int i=0; i<N; i++) {
2281            TaskRecord tr = mRecentTasks.get(i);
2282            if ((task.affinity != null && task.affinity.equals(tr.affinity))
2283                    || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2284                mRecentTasks.remove(i);
2285                i--;
2286                N--;
2287                if (task.intent == null) {
2288                    // If the new recent task we are adding is not fully
2289                    // specified, then replace it with the existing recent task.
2290                    task = tr;
2291                }
2292            }
2293        }
2294        if (N >= MAX_RECENT_TASKS) {
2295            mRecentTasks.remove(N-1);
2296        }
2297        mRecentTasks.add(0, task);
2298    }
2299
2300    public void setRequestedOrientation(IBinder token,
2301            int requestedOrientation) {
2302        synchronized (this) {
2303            int index = mMainStack.indexOfTokenLocked(token);
2304            if (index < 0) {
2305                return;
2306            }
2307            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
2308            final long origId = Binder.clearCallingIdentity();
2309            mWindowManager.setAppOrientation(r, requestedOrientation);
2310            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2311                    mConfiguration,
2312                    r.mayFreezeScreenLocked(r.app) ? r : null);
2313            if (config != null) {
2314                r.frozenBeforeDestroy = true;
2315                if (!updateConfigurationLocked(config, r)) {
2316                    mMainStack.resumeTopActivityLocked(null);
2317                }
2318            }
2319            Binder.restoreCallingIdentity(origId);
2320        }
2321    }
2322
2323    public int getRequestedOrientation(IBinder token) {
2324        synchronized (this) {
2325            int index = mMainStack.indexOfTokenLocked(token);
2326            if (index < 0) {
2327                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2328            }
2329            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
2330            return mWindowManager.getAppOrientation(r);
2331        }
2332    }
2333
2334    /**
2335     * This is the internal entry point for handling Activity.finish().
2336     *
2337     * @param token The Binder token referencing the Activity we want to finish.
2338     * @param resultCode Result code, if any, from this Activity.
2339     * @param resultData Result data (Intent), if any, from this Activity.
2340     *
2341     * @return Returns true if the activity successfully finished, or false if it is still running.
2342     */
2343    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2344        // Refuse possible leaked file descriptors
2345        if (resultData != null && resultData.hasFileDescriptors() == true) {
2346            throw new IllegalArgumentException("File descriptors passed in Intent");
2347        }
2348
2349        synchronized(this) {
2350            if (mController != null) {
2351                // Find the first activity that is not finishing.
2352                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2353                if (next != null) {
2354                    // ask watcher if this is allowed
2355                    boolean resumeOK = true;
2356                    try {
2357                        resumeOK = mController.activityResuming(next.packageName);
2358                    } catch (RemoteException e) {
2359                        mController = null;
2360                    }
2361
2362                    if (!resumeOK) {
2363                        return false;
2364                    }
2365                }
2366            }
2367            final long origId = Binder.clearCallingIdentity();
2368            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2369                    resultData, "app-request");
2370            Binder.restoreCallingIdentity(origId);
2371            return res;
2372        }
2373    }
2374
2375    public final void finishHeavyWeightApp() {
2376        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2377                != PackageManager.PERMISSION_GRANTED) {
2378            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2379                    + Binder.getCallingPid()
2380                    + ", uid=" + Binder.getCallingUid()
2381                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2382            Slog.w(TAG, msg);
2383            throw new SecurityException(msg);
2384        }
2385
2386        synchronized(this) {
2387            if (mHeavyWeightProcess == null) {
2388                return;
2389            }
2390
2391            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2392                    mHeavyWeightProcess.activities);
2393            for (int i=0; i<activities.size(); i++) {
2394                ActivityRecord r = activities.get(i);
2395                if (!r.finishing) {
2396                    int index = mMainStack.indexOfTokenLocked(r);
2397                    if (index >= 0) {
2398                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2399                                null, "finish-heavy");
2400                    }
2401                }
2402            }
2403
2404            mHeavyWeightProcess = null;
2405            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2406        }
2407    }
2408
2409    public void crashApplication(int uid, int initialPid, String packageName,
2410            String message) {
2411        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2412                != PackageManager.PERMISSION_GRANTED) {
2413            String msg = "Permission Denial: crashApplication() from pid="
2414                    + Binder.getCallingPid()
2415                    + ", uid=" + Binder.getCallingUid()
2416                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2417            Slog.w(TAG, msg);
2418            throw new SecurityException(msg);
2419        }
2420
2421        synchronized(this) {
2422            ProcessRecord proc = null;
2423
2424            // Figure out which process to kill.  We don't trust that initialPid
2425            // still has any relation to current pids, so must scan through the
2426            // list.
2427            synchronized (mPidsSelfLocked) {
2428                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2429                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2430                    if (p.info.uid != uid) {
2431                        continue;
2432                    }
2433                    if (p.pid == initialPid) {
2434                        proc = p;
2435                        break;
2436                    }
2437                    for (String str : p.pkgList) {
2438                        if (str.equals(packageName)) {
2439                            proc = p;
2440                        }
2441                    }
2442                }
2443            }
2444
2445            if (proc == null) {
2446                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2447                        + " initialPid=" + initialPid
2448                        + " packageName=" + packageName);
2449                return;
2450            }
2451
2452            if (proc.thread != null) {
2453                long ident = Binder.clearCallingIdentity();
2454                try {
2455                    proc.thread.scheduleCrash(message);
2456                } catch (RemoteException e) {
2457                }
2458                Binder.restoreCallingIdentity(ident);
2459            }
2460        }
2461    }
2462
2463    public final void finishSubActivity(IBinder token, String resultWho,
2464            int requestCode) {
2465        synchronized(this) {
2466            int index = mMainStack.indexOfTokenLocked(token);
2467            if (index < 0) {
2468                return;
2469            }
2470            ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
2471
2472            final long origId = Binder.clearCallingIdentity();
2473
2474            int i;
2475            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2476                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2477                if (r.resultTo == self && r.requestCode == requestCode) {
2478                    if ((r.resultWho == null && resultWho == null) ||
2479                        (r.resultWho != null && r.resultWho.equals(resultWho))) {
2480                        mMainStack.finishActivityLocked(r, i,
2481                                Activity.RESULT_CANCELED, null, "request-sub");
2482                    }
2483                }
2484            }
2485
2486            Binder.restoreCallingIdentity(origId);
2487        }
2488    }
2489
2490    public boolean willActivityBeVisible(IBinder token) {
2491        synchronized(this) {
2492            int i;
2493            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2494                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2495                if (r == token) {
2496                    return true;
2497                }
2498                if (r.fullscreen && !r.finishing) {
2499                    return false;
2500                }
2501            }
2502            return true;
2503        }
2504    }
2505
2506    public void overridePendingTransition(IBinder token, String packageName,
2507            int enterAnim, int exitAnim) {
2508        synchronized(this) {
2509            int index = mMainStack.indexOfTokenLocked(token);
2510            if (index < 0) {
2511                return;
2512            }
2513            ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
2514
2515            final long origId = Binder.clearCallingIdentity();
2516
2517            if (self.state == ActivityState.RESUMED
2518                    || self.state == ActivityState.PAUSING) {
2519                mWindowManager.overridePendingAppTransition(packageName,
2520                        enterAnim, exitAnim);
2521            }
2522
2523            Binder.restoreCallingIdentity(origId);
2524        }
2525    }
2526
2527    /**
2528     * Main function for removing an existing process from the activity manager
2529     * as a result of that process going away.  Clears out all connections
2530     * to the process.
2531     */
2532    private final void handleAppDiedLocked(ProcessRecord app,
2533            boolean restarting) {
2534        cleanUpApplicationRecordLocked(app, restarting, -1);
2535        if (!restarting) {
2536            mLruProcesses.remove(app);
2537        }
2538
2539        // Just in case...
2540        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2541            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2542            mMainStack.mPausingActivity = null;
2543        }
2544        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2545            mMainStack.mLastPausedActivity = null;
2546        }
2547
2548        // Remove this application's activities from active lists.
2549        mMainStack.removeHistoryRecordsForAppLocked(app);
2550
2551        boolean atTop = true;
2552        boolean hasVisibleActivities = false;
2553
2554        // Clean out the history list.
2555        int i = mMainStack.mHistory.size();
2556        if (localLOGV) Slog.v(
2557            TAG, "Removing app " + app + " from history with " + i + " entries");
2558        while (i > 0) {
2559            i--;
2560            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2561            if (localLOGV) Slog.v(
2562                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2563            if (r.app == app) {
2564                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2565                    if (localLOGV) Slog.v(
2566                        TAG, "Removing this entry!  frozen=" + r.haveState
2567                        + " finishing=" + r.finishing);
2568                    mMainStack.mHistory.remove(i);
2569
2570                    r.inHistory = false;
2571                    mWindowManager.removeAppToken(r);
2572                    if (VALIDATE_TOKENS) {
2573                        mWindowManager.validateAppTokens(mMainStack.mHistory);
2574                    }
2575                    r.removeUriPermissionsLocked();
2576
2577                } else {
2578                    // We have the current state for this activity, so
2579                    // it can be restarted later when needed.
2580                    if (localLOGV) Slog.v(
2581                        TAG, "Keeping entry, setting app to null");
2582                    if (r.visible) {
2583                        hasVisibleActivities = true;
2584                    }
2585                    r.app = null;
2586                    r.nowVisible = false;
2587                    if (!r.haveState) {
2588                        r.icicle = null;
2589                    }
2590                }
2591
2592                r.stack.cleanUpActivityLocked(r, true);
2593                r.state = ActivityState.STOPPED;
2594            }
2595            atTop = false;
2596        }
2597
2598        app.activities.clear();
2599
2600        if (app.instrumentationClass != null) {
2601            Slog.w(TAG, "Crash of app " + app.processName
2602                  + " running instrumentation " + app.instrumentationClass);
2603            Bundle info = new Bundle();
2604            info.putString("shortMsg", "Process crashed.");
2605            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2606        }
2607
2608        if (!restarting) {
2609            if (!mMainStack.resumeTopActivityLocked(null)) {
2610                // If there was nothing to resume, and we are not already
2611                // restarting this process, but there is a visible activity that
2612                // is hosted by the process...  then make sure all visible
2613                // activities are running, taking care of restarting this
2614                // process.
2615                if (hasVisibleActivities) {
2616                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2617                }
2618            }
2619        }
2620    }
2621
2622    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2623        IBinder threadBinder = thread.asBinder();
2624
2625        // Find the application record.
2626        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2627            ProcessRecord rec = mLruProcesses.get(i);
2628            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2629                return i;
2630            }
2631        }
2632        return -1;
2633    }
2634
2635    final ProcessRecord getRecordForAppLocked(
2636            IApplicationThread thread) {
2637        if (thread == null) {
2638            return null;
2639        }
2640
2641        int appIndex = getLRURecordIndexForAppLocked(thread);
2642        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2643    }
2644
2645    final void appDiedLocked(ProcessRecord app, int pid,
2646            IApplicationThread thread) {
2647
2648        mProcDeaths[0]++;
2649
2650        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2651        synchronized (stats) {
2652            stats.noteProcessDiedLocked(app.info.uid, pid);
2653        }
2654
2655        // Clean up already done if the process has been re-started.
2656        if (app.pid == pid && app.thread != null &&
2657                app.thread.asBinder() == thread.asBinder()) {
2658            if (!app.killedBackground) {
2659                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2660                        + ") has died.");
2661            }
2662            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2663            if (localLOGV) Slog.v(
2664                TAG, "Dying app: " + app + ", pid: " + pid
2665                + ", thread: " + thread.asBinder());
2666            boolean doLowMem = app.instrumentationClass == null;
2667            handleAppDiedLocked(app, false);
2668
2669            if (doLowMem) {
2670                // If there are no longer any background processes running,
2671                // and the app that died was not running instrumentation,
2672                // then tell everyone we are now low on memory.
2673                boolean haveBg = false;
2674                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2675                    ProcessRecord rec = mLruProcesses.get(i);
2676                    if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
2677                        haveBg = true;
2678                        break;
2679                    }
2680                }
2681
2682                if (!haveBg) {
2683                    Slog.i(TAG, "Low Memory: No more background processes.");
2684                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2685                    long now = SystemClock.uptimeMillis();
2686                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2687                        ProcessRecord rec = mLruProcesses.get(i);
2688                        if (rec != app && rec.thread != null &&
2689                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2690                            // The low memory report is overriding any current
2691                            // state for a GC request.  Make sure to do
2692                            // heavy/important/visible/foreground processes first.
2693                            if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) {
2694                                rec.lastRequestedGc = 0;
2695                            } else {
2696                                rec.lastRequestedGc = rec.lastLowMemory;
2697                            }
2698                            rec.reportLowMemory = true;
2699                            rec.lastLowMemory = now;
2700                            mProcessesToGc.remove(rec);
2701                            addProcessToGcListLocked(rec);
2702                        }
2703                    }
2704                    scheduleAppGcsLocked();
2705                }
2706            }
2707        } else if (app.pid != pid) {
2708            // A new process has already been started.
2709            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2710                    + ") has died and restarted (pid " + app.pid + ").");
2711            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2712        } else if (DEBUG_PROCESSES) {
2713            Slog.d(TAG, "Received spurious death notification for thread "
2714                    + thread.asBinder());
2715        }
2716    }
2717
2718    /**
2719     * If a stack trace dump file is configured, dump process stack traces.
2720     * @param clearTraces causes the dump file to be erased prior to the new
2721     *    traces being written, if true; when false, the new traces will be
2722     *    appended to any existing file content.
2723     * @param firstPids of dalvik VM processes to dump stack traces for first
2724     * @param lastPids of dalvik VM processes to dump stack traces for last
2725     * @return file containing stack traces, or null if no dump file is configured
2726     */
2727    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2728            ProcessStats processStats, SparseArray<Boolean> lastPids) {
2729        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2730        if (tracesPath == null || tracesPath.length() == 0) {
2731            return null;
2732        }
2733
2734        File tracesFile = new File(tracesPath);
2735        try {
2736            File tracesDir = tracesFile.getParentFile();
2737            if (!tracesDir.exists()) tracesFile.mkdirs();
2738            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
2739
2740            if (clearTraces && tracesFile.exists()) tracesFile.delete();
2741            tracesFile.createNewFile();
2742            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2743        } catch (IOException e) {
2744            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
2745            return null;
2746        }
2747
2748        // Use a FileObserver to detect when traces finish writing.
2749        // The order of traces is considered important to maintain for legibility.
2750        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2751            public synchronized void onEvent(int event, String path) { notify(); }
2752        };
2753
2754        try {
2755            observer.startWatching();
2756
2757            // First collect all of the stacks of the most important pids.
2758            try {
2759                int num = firstPids.size();
2760                for (int i = 0; i < num; i++) {
2761                    synchronized (observer) {
2762                        Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2763                        observer.wait(200);  // Wait for write-close, give up after 200msec
2764                    }
2765                }
2766            } catch (InterruptedException e) {
2767                Log.wtf(TAG, e);
2768            }
2769
2770            // Next measure CPU usage.
2771            if (processStats != null) {
2772                processStats.init();
2773                System.gc();
2774                processStats.update();
2775                try {
2776                    synchronized (processStats) {
2777                        processStats.wait(500); // measure over 1/2 second.
2778                    }
2779                } catch (InterruptedException e) {
2780                }
2781                processStats.update();
2782
2783                // We'll take the stack crawls of just the top apps using CPU.
2784                final int N = processStats.countWorkingStats();
2785                int numProcs = 0;
2786                for (int i=0; i<N && numProcs<5; i++) {
2787                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
2788                    if (lastPids.indexOfKey(stats.pid) >= 0) {
2789                        numProcs++;
2790                        try {
2791                            synchronized (observer) {
2792                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2793                                observer.wait(200);  // Wait for write-close, give up after 200msec
2794                            }
2795                        } catch (InterruptedException e) {
2796                            Log.wtf(TAG, e);
2797                        }
2798
2799                    }
2800                }
2801            }
2802
2803            return tracesFile;
2804
2805        } finally {
2806            observer.stopWatching();
2807        }
2808    }
2809
2810    private final class AppNotResponding implements Runnable {
2811        private final ProcessRecord mApp;
2812        private final String mAnnotation;
2813
2814        public AppNotResponding(ProcessRecord app, String annotation) {
2815            mApp = app;
2816            mAnnotation = annotation;
2817        }
2818
2819        @Override
2820        public void run() {
2821            appNotResponding(mApp, null, null, mAnnotation);
2822        }
2823    }
2824
2825    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2826            ActivityRecord parent, final String annotation) {
2827        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2828        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2829
2830        if (mController != null) {
2831            try {
2832                // 0 == continue, -1 = kill process immediately
2833                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2834                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2835            } catch (RemoteException e) {
2836                mController = null;
2837            }
2838        }
2839
2840        long anrTime = SystemClock.uptimeMillis();
2841        if (MONITOR_CPU_USAGE) {
2842            updateCpuStatsNow();
2843        }
2844
2845        synchronized (this) {
2846            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2847            if (mShuttingDown) {
2848                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2849                return;
2850            } else if (app.notResponding) {
2851                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2852                return;
2853            } else if (app.crashing) {
2854                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2855                return;
2856            }
2857
2858            // In case we come through here for the same app before completing
2859            // this one, mark as anring now so we will bail out.
2860            app.notResponding = true;
2861
2862            // Log the ANR to the event log.
2863            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2864                    annotation);
2865
2866            // Dump thread traces as quickly as we can, starting with "interesting" processes.
2867            firstPids.add(app.pid);
2868
2869            int parentPid = app.pid;
2870            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
2871            if (parentPid != app.pid) firstPids.add(parentPid);
2872
2873            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
2874
2875            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2876                ProcessRecord r = mLruProcesses.get(i);
2877                if (r != null && r.thread != null) {
2878                    int pid = r.pid;
2879                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2880                        if (r.persistent) {
2881                            firstPids.add(pid);
2882                        } else {
2883                            lastPids.put(pid, Boolean.TRUE);
2884                        }
2885                    }
2886                }
2887            }
2888        }
2889
2890        // Log the ANR to the main log.
2891        StringBuilder info = mStringBuilder;
2892        info.setLength(0);
2893        info.append("ANR in ").append(app.processName);
2894        if (activity != null && activity.shortComponentName != null) {
2895            info.append(" (").append(activity.shortComponentName).append(")");
2896        }
2897        info.append("\n");
2898        if (annotation != null) {
2899            info.append("Reason: ").append(annotation).append("\n");
2900        }
2901        if (parent != null && parent != activity) {
2902            info.append("Parent: ").append(parent.shortComponentName).append("\n");
2903        }
2904
2905        final ProcessStats processStats = new ProcessStats(true);
2906
2907        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
2908
2909        String cpuInfo = null;
2910        if (MONITOR_CPU_USAGE) {
2911            updateCpuStatsNow();
2912            synchronized (mProcessStatsThread) {
2913                cpuInfo = mProcessStats.printCurrentState(anrTime);
2914            }
2915            info.append(processStats.printCurrentLoad());
2916            info.append(cpuInfo);
2917        }
2918
2919        info.append(processStats.printCurrentState(anrTime));
2920
2921        Slog.e(TAG, info.toString());
2922        if (tracesFile == null) {
2923            // There is no trace file, so dump (only) the alleged culprit's threads to the log
2924            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
2925        }
2926
2927        addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
2928
2929        if (mController != null) {
2930            try {
2931                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
2932                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
2933                if (res != 0) {
2934                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2935                    return;
2936                }
2937            } catch (RemoteException e) {
2938                mController = null;
2939            }
2940        }
2941
2942        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
2943        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
2944                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
2945
2946        synchronized (this) {
2947            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
2948                Process.killProcess(app.pid);
2949                return;
2950            }
2951
2952            // Set the app's notResponding state, and look up the errorReportReceiver
2953            makeAppNotRespondingLocked(app,
2954                    activity != null ? activity.shortComponentName : null,
2955                    annotation != null ? "ANR " + annotation : "ANR",
2956                    info.toString());
2957
2958            // Bring up the infamous App Not Responding dialog
2959            Message msg = Message.obtain();
2960            HashMap map = new HashMap();
2961            msg.what = SHOW_NOT_RESPONDING_MSG;
2962            msg.obj = map;
2963            map.put("app", app);
2964            if (activity != null) {
2965                map.put("activity", activity);
2966            }
2967
2968            mHandler.sendMessage(msg);
2969        }
2970    }
2971
2972    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
2973        if (!mLaunchWarningShown) {
2974            mLaunchWarningShown = true;
2975            mHandler.post(new Runnable() {
2976                @Override
2977                public void run() {
2978                    synchronized (ActivityManagerService.this) {
2979                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
2980                        d.show();
2981                        mHandler.postDelayed(new Runnable() {
2982                            @Override
2983                            public void run() {
2984                                synchronized (ActivityManagerService.this) {
2985                                    d.dismiss();
2986                                    mLaunchWarningShown = false;
2987                                }
2988                            }
2989                        }, 4000);
2990                    }
2991                }
2992            });
2993        }
2994    }
2995
2996    public boolean clearApplicationUserData(final String packageName,
2997            final IPackageDataObserver observer) {
2998        int uid = Binder.getCallingUid();
2999        int pid = Binder.getCallingPid();
3000        long callingId = Binder.clearCallingIdentity();
3001        try {
3002            IPackageManager pm = AppGlobals.getPackageManager();
3003            int pkgUid = -1;
3004            synchronized(this) {
3005                try {
3006                    pkgUid = pm.getPackageUid(packageName);
3007                } catch (RemoteException e) {
3008                }
3009                if (pkgUid == -1) {
3010                    Slog.w(TAG, "Invalid packageName:" + packageName);
3011                    return false;
3012                }
3013                if (uid == pkgUid || checkComponentPermission(
3014                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3015                        pid, uid, -1)
3016                        == PackageManager.PERMISSION_GRANTED) {
3017                    forceStopPackageLocked(packageName, pkgUid);
3018                } else {
3019                    throw new SecurityException(pid+" does not have permission:"+
3020                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3021                                    "for process:"+packageName);
3022                }
3023            }
3024
3025            try {
3026                //clear application user data
3027                pm.clearApplicationUserData(packageName, observer);
3028                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3029                        Uri.fromParts("package", packageName, null));
3030                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3031                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3032                        null, null, 0, null, null, null, false, false);
3033            } catch (RemoteException e) {
3034            }
3035        } finally {
3036            Binder.restoreCallingIdentity(callingId);
3037        }
3038        return true;
3039    }
3040
3041    public void killBackgroundProcesses(final String packageName) {
3042        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3043                != PackageManager.PERMISSION_GRANTED &&
3044                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3045                        != PackageManager.PERMISSION_GRANTED) {
3046            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3047                    + Binder.getCallingPid()
3048                    + ", uid=" + Binder.getCallingUid()
3049                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3050            Slog.w(TAG, msg);
3051            throw new SecurityException(msg);
3052        }
3053
3054        long callingId = Binder.clearCallingIdentity();
3055        try {
3056            IPackageManager pm = AppGlobals.getPackageManager();
3057            int pkgUid = -1;
3058            synchronized(this) {
3059                try {
3060                    pkgUid = pm.getPackageUid(packageName);
3061                } catch (RemoteException e) {
3062                }
3063                if (pkgUid == -1) {
3064                    Slog.w(TAG, "Invalid packageName: " + packageName);
3065                    return;
3066                }
3067                killPackageProcessesLocked(packageName, pkgUid,
3068                        SECONDARY_SERVER_ADJ, false, true);
3069            }
3070        } finally {
3071            Binder.restoreCallingIdentity(callingId);
3072        }
3073    }
3074
3075    public void forceStopPackage(final String packageName) {
3076        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3077                != PackageManager.PERMISSION_GRANTED) {
3078            String msg = "Permission Denial: forceStopPackage() from pid="
3079                    + Binder.getCallingPid()
3080                    + ", uid=" + Binder.getCallingUid()
3081                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3082            Slog.w(TAG, msg);
3083            throw new SecurityException(msg);
3084        }
3085
3086        long callingId = Binder.clearCallingIdentity();
3087        try {
3088            IPackageManager pm = AppGlobals.getPackageManager();
3089            int pkgUid = -1;
3090            synchronized(this) {
3091                try {
3092                    pkgUid = pm.getPackageUid(packageName);
3093                } catch (RemoteException e) {
3094                }
3095                if (pkgUid == -1) {
3096                    Slog.w(TAG, "Invalid packageName: " + packageName);
3097                    return;
3098                }
3099                forceStopPackageLocked(packageName, pkgUid);
3100            }
3101        } finally {
3102            Binder.restoreCallingIdentity(callingId);
3103        }
3104    }
3105
3106    /*
3107     * The pkg name and uid have to be specified.
3108     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3109     */
3110    public void killApplicationWithUid(String pkg, int uid) {
3111        if (pkg == null) {
3112            return;
3113        }
3114        // Make sure the uid is valid.
3115        if (uid < 0) {
3116            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3117            return;
3118        }
3119        int callerUid = Binder.getCallingUid();
3120        // Only the system server can kill an application
3121        if (callerUid == Process.SYSTEM_UID) {
3122            // Post an aysnc message to kill the application
3123            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3124            msg.arg1 = uid;
3125            msg.arg2 = 0;
3126            msg.obj = pkg;
3127            mHandler.sendMessage(msg);
3128        } else {
3129            throw new SecurityException(callerUid + " cannot kill pkg: " +
3130                    pkg);
3131        }
3132    }
3133
3134    public void closeSystemDialogs(String reason) {
3135        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3136        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3137        if (reason != null) {
3138            intent.putExtra("reason", reason);
3139        }
3140
3141        final int uid = Binder.getCallingUid();
3142        final long origId = Binder.clearCallingIdentity();
3143        synchronized (this) {
3144            int i = mWatchers.beginBroadcast();
3145            while (i > 0) {
3146                i--;
3147                IActivityWatcher w = mWatchers.getBroadcastItem(i);
3148                if (w != null) {
3149                    try {
3150                        w.closingSystemDialogs(reason);
3151                    } catch (RemoteException e) {
3152                    }
3153                }
3154            }
3155            mWatchers.finishBroadcast();
3156
3157            mWindowManager.closeSystemDialogs(reason);
3158
3159            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3160                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3161                if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3162                    r.stack.finishActivityLocked(r, i,
3163                            Activity.RESULT_CANCELED, null, "close-sys");
3164                }
3165            }
3166
3167            broadcastIntentLocked(null, null, intent, null,
3168                    null, 0, null, null, null, false, false, -1, uid);
3169        }
3170        Binder.restoreCallingIdentity(origId);
3171    }
3172
3173    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3174            throws RemoteException {
3175        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3176        for (int i=pids.length-1; i>=0; i--) {
3177            infos[i] = new Debug.MemoryInfo();
3178            Debug.getMemoryInfo(pids[i], infos[i]);
3179        }
3180        return infos;
3181    }
3182
3183    public void killApplicationProcess(String processName, int uid) {
3184        if (processName == null) {
3185            return;
3186        }
3187
3188        int callerUid = Binder.getCallingUid();
3189        // Only the system server can kill an application
3190        if (callerUid == Process.SYSTEM_UID) {
3191            synchronized (this) {
3192                ProcessRecord app = getProcessRecordLocked(processName, uid);
3193                if (app != null) {
3194                    try {
3195                        app.thread.scheduleSuicide();
3196                    } catch (RemoteException e) {
3197                        // If the other end already died, then our work here is done.
3198                    }
3199                } else {
3200                    Slog.w(TAG, "Process/uid not found attempting kill of "
3201                            + processName + " / " + uid);
3202                }
3203            }
3204        } else {
3205            throw new SecurityException(callerUid + " cannot kill app process: " +
3206                    processName);
3207        }
3208    }
3209
3210    private void forceStopPackageLocked(final String packageName, int uid) {
3211        forceStopPackageLocked(packageName, uid, false, false, true);
3212        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3213                Uri.fromParts("package", packageName, null));
3214        if (!mProcessesReady) {
3215            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3216        }
3217        intent.putExtra(Intent.EXTRA_UID, uid);
3218        broadcastIntentLocked(null, null, intent,
3219                null, null, 0, null, null, null,
3220                false, false, MY_PID, Process.SYSTEM_UID);
3221    }
3222
3223    private final boolean killPackageProcessesLocked(String packageName, int uid,
3224            int minOomAdj, boolean callerWillRestart, boolean doit) {
3225        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3226
3227        // Remove all processes this package may have touched: all with the
3228        // same UID (except for the system or root user), and all whose name
3229        // matches the package name.
3230        final String procNamePrefix = packageName + ":";
3231        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3232            final int NA = apps.size();
3233            for (int ia=0; ia<NA; ia++) {
3234                ProcessRecord app = apps.valueAt(ia);
3235                if (app.removed) {
3236                    if (doit) {
3237                        procs.add(app);
3238                    }
3239                } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3240                        || app.processName.equals(packageName)
3241                        || app.processName.startsWith(procNamePrefix)) {
3242                    if (app.setAdj >= minOomAdj) {
3243                        if (!doit) {
3244                            return true;
3245                        }
3246                        app.removed = true;
3247                        procs.add(app);
3248                    }
3249                }
3250            }
3251        }
3252
3253        int N = procs.size();
3254        for (int i=0; i<N; i++) {
3255            removeProcessLocked(procs.get(i), callerWillRestart);
3256        }
3257        return N > 0;
3258    }
3259
3260    private final boolean forceStopPackageLocked(String name, int uid,
3261            boolean callerWillRestart, boolean purgeCache, boolean doit) {
3262        int i, N;
3263
3264        if (uid < 0) {
3265            try {
3266                uid = AppGlobals.getPackageManager().getPackageUid(name);
3267            } catch (RemoteException e) {
3268            }
3269        }
3270
3271        if (doit) {
3272            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3273
3274            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3275            while (badApps.hasNext()) {
3276                SparseArray<Long> ba = badApps.next();
3277                if (ba.get(uid) != null) {
3278                    badApps.remove();
3279                }
3280            }
3281        }
3282
3283        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3284                callerWillRestart, doit);
3285
3286        for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3287            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3288            if (r.packageName.equals(name)) {
3289                if (!doit) {
3290                    return true;
3291                }
3292                didSomething = true;
3293                Slog.i(TAG, "  Force finishing activity " + r);
3294                if (r.app != null) {
3295                    r.app.removed = true;
3296                }
3297                r.app = null;
3298                r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
3299            }
3300        }
3301
3302        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3303        for (ServiceRecord service : mServices.values()) {
3304            if (service.packageName.equals(name)) {
3305                if (!doit) {
3306                    return true;
3307                }
3308                didSomething = true;
3309                Slog.i(TAG, "  Force stopping service " + service);
3310                if (service.app != null) {
3311                    service.app.removed = true;
3312                }
3313                service.app = null;
3314                services.add(service);
3315            }
3316        }
3317
3318        N = services.size();
3319        for (i=0; i<N; i++) {
3320            bringDownServiceLocked(services.get(i), true);
3321        }
3322
3323        if (doit) {
3324            if (purgeCache) {
3325                AttributeCache ac = AttributeCache.instance();
3326                if (ac != null) {
3327                    ac.removePackage(name);
3328                }
3329            }
3330            mMainStack.resumeTopActivityLocked(null);
3331        }
3332
3333        return didSomething;
3334    }
3335
3336    private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
3337        final String name = app.processName;
3338        final int uid = app.info.uid;
3339        if (DEBUG_PROCESSES) Slog.d(
3340            TAG, "Force removing process " + app + " (" + name
3341            + "/" + uid + ")");
3342
3343        mProcessNames.remove(name, uid);
3344        if (mHeavyWeightProcess == app) {
3345            mHeavyWeightProcess = null;
3346            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3347        }
3348        boolean needRestart = false;
3349        if (app.pid > 0 && app.pid != MY_PID) {
3350            int pid = app.pid;
3351            synchronized (mPidsSelfLocked) {
3352                mPidsSelfLocked.remove(pid);
3353                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3354            }
3355            handleAppDiedLocked(app, true);
3356            mLruProcesses.remove(app);
3357            Process.killProcess(pid);
3358
3359            if (app.persistent) {
3360                if (!callerWillRestart) {
3361                    addAppLocked(app.info);
3362                } else {
3363                    needRestart = true;
3364                }
3365            }
3366        } else {
3367            mRemovedProcesses.add(app);
3368        }
3369
3370        return needRestart;
3371    }
3372
3373    private final void processStartTimedOutLocked(ProcessRecord app) {
3374        final int pid = app.pid;
3375        boolean gone = false;
3376        synchronized (mPidsSelfLocked) {
3377            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3378            if (knownApp != null && knownApp.thread == null) {
3379                mPidsSelfLocked.remove(pid);
3380                gone = true;
3381            }
3382        }
3383
3384        if (gone) {
3385            Slog.w(TAG, "Process " + app + " failed to attach");
3386            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
3387                    app.processName);
3388            mProcessNames.remove(app.processName, app.info.uid);
3389            if (mHeavyWeightProcess == app) {
3390                mHeavyWeightProcess = null;
3391                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3392            }
3393            // Take care of any launching providers waiting for this process.
3394            checkAppInLaunchingProvidersLocked(app, true);
3395            // Take care of any services that are waiting for the process.
3396            for (int i=0; i<mPendingServices.size(); i++) {
3397                ServiceRecord sr = mPendingServices.get(i);
3398                if (app.info.uid == sr.appInfo.uid
3399                        && app.processName.equals(sr.processName)) {
3400                    Slog.w(TAG, "Forcing bringing down service: " + sr);
3401                    mPendingServices.remove(i);
3402                    i--;
3403                    bringDownServiceLocked(sr, true);
3404                }
3405            }
3406            Process.killProcess(pid);
3407            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3408                Slog.w(TAG, "Unattached app died before backup, skipping");
3409                try {
3410                    IBackupManager bm = IBackupManager.Stub.asInterface(
3411                            ServiceManager.getService(Context.BACKUP_SERVICE));
3412                    bm.agentDisconnected(app.info.packageName);
3413                } catch (RemoteException e) {
3414                    // Can't happen; the backup manager is local
3415                }
3416            }
3417            if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
3418                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3419                mPendingBroadcast.state = BroadcastRecord.IDLE;
3420                mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
3421                mPendingBroadcast = null;
3422                scheduleBroadcastsLocked();
3423            }
3424        } else {
3425            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3426        }
3427    }
3428
3429    private final boolean attachApplicationLocked(IApplicationThread thread,
3430            int pid) {
3431
3432        // Find the application record that is being attached...  either via
3433        // the pid if we are running in multiple processes, or just pull the
3434        // next app record if we are emulating process with anonymous threads.
3435        ProcessRecord app;
3436        if (pid != MY_PID && pid >= 0) {
3437            synchronized (mPidsSelfLocked) {
3438                app = mPidsSelfLocked.get(pid);
3439            }
3440        } else if (mStartingProcesses.size() > 0) {
3441            app = mStartingProcesses.remove(0);
3442            app.setPid(pid);
3443        } else {
3444            app = null;
3445        }
3446
3447        if (app == null) {
3448            Slog.w(TAG, "No pending application record for pid " + pid
3449                    + " (IApplicationThread " + thread + "); dropping process");
3450            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3451            if (pid > 0 && pid != MY_PID) {
3452                Process.killProcess(pid);
3453            } else {
3454                try {
3455                    thread.scheduleExit();
3456                } catch (Exception e) {
3457                    // Ignore exceptions.
3458                }
3459            }
3460            return false;
3461        }
3462
3463        // If this application record is still attached to a previous
3464        // process, clean it up now.
3465        if (app.thread != null) {
3466            handleAppDiedLocked(app, true);
3467        }
3468
3469        // Tell the process all about itself.
3470
3471        if (localLOGV) Slog.v(
3472                TAG, "Binding process pid " + pid + " to record " + app);
3473
3474        String processName = app.processName;
3475        try {
3476            thread.asBinder().linkToDeath(new AppDeathRecipient(
3477                    app, pid, thread), 0);
3478        } catch (RemoteException e) {
3479            app.resetPackageList();
3480            startProcessLocked(app, "link fail", processName);
3481            return false;
3482        }
3483
3484        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3485
3486        app.thread = thread;
3487        app.curAdj = app.setAdj = -100;
3488        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3489        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3490        app.forcingToForeground = null;
3491        app.foregroundServices = false;
3492        app.debugging = false;
3493
3494        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3495
3496        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3497        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3498
3499        if (!normalMode) {
3500            Slog.i(TAG, "Launching preboot mode app: " + app);
3501        }
3502
3503        if (localLOGV) Slog.v(
3504            TAG, "New app record " + app
3505            + " thread=" + thread.asBinder() + " pid=" + pid);
3506        try {
3507            int testMode = IApplicationThread.DEBUG_OFF;
3508            if (mDebugApp != null && mDebugApp.equals(processName)) {
3509                testMode = mWaitForDebugger
3510                    ? IApplicationThread.DEBUG_WAIT
3511                    : IApplicationThread.DEBUG_ON;
3512                app.debugging = true;
3513                if (mDebugTransient) {
3514                    mDebugApp = mOrigDebugApp;
3515                    mWaitForDebugger = mOrigWaitForDebugger;
3516                }
3517            }
3518
3519            // If the app is being launched for restore or full backup, set it up specially
3520            boolean isRestrictedBackupMode = false;
3521            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3522                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3523                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3524            }
3525
3526            ensurePackageDexOpt(app.instrumentationInfo != null
3527                    ? app.instrumentationInfo.packageName
3528                    : app.info.packageName);
3529            if (app.instrumentationClass != null) {
3530                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
3531            }
3532            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
3533                    + processName + " with config " + mConfiguration);
3534            thread.bindApplication(processName, app.instrumentationInfo != null
3535                    ? app.instrumentationInfo : app.info, providers,
3536                    app.instrumentationClass, app.instrumentationProfileFile,
3537                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
3538                    isRestrictedBackupMode || !normalMode,
3539                    mConfiguration, getCommonServicesLocked());
3540            updateLruProcessLocked(app, false, true);
3541            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
3542        } catch (Exception e) {
3543            // todo: Yikes!  What should we do?  For now we will try to
3544            // start another process, but that could easily get us in
3545            // an infinite loop of restarting processes...
3546            Slog.w(TAG, "Exception thrown during bind!", e);
3547
3548            app.resetPackageList();
3549            startProcessLocked(app, "bind fail", processName);
3550            return false;
3551        }
3552
3553        // Remove this record from the list of starting applications.
3554        mPersistentStartingProcesses.remove(app);
3555        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3556                "Attach application locked removing on hold: " + app);
3557        mProcessesOnHold.remove(app);
3558
3559        boolean badApp = false;
3560        boolean didSomething = false;
3561
3562        // See if the top visible activity is waiting to run in this process...
3563        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
3564        if (hr != null && normalMode) {
3565            if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3566                    && processName.equals(hr.processName)) {
3567                try {
3568                    if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
3569                        didSomething = true;
3570                    }
3571                } catch (Exception e) {
3572                    Slog.w(TAG, "Exception in new application when starting activity "
3573                          + hr.intent.getComponent().flattenToShortString(), e);
3574                    badApp = true;
3575                }
3576            } else {
3577                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
3578            }
3579        }
3580
3581        // Find any services that should be running in this process...
3582        if (!badApp && mPendingServices.size() > 0) {
3583            ServiceRecord sr = null;
3584            try {
3585                for (int i=0; i<mPendingServices.size(); i++) {
3586                    sr = mPendingServices.get(i);
3587                    if (app.info.uid != sr.appInfo.uid
3588                            || !processName.equals(sr.processName)) {
3589                        continue;
3590                    }
3591
3592                    mPendingServices.remove(i);
3593                    i--;
3594                    realStartServiceLocked(sr, app);
3595                    didSomething = true;
3596                }
3597            } catch (Exception e) {
3598                Slog.w(TAG, "Exception in new application when starting service "
3599                      + sr.shortName, e);
3600                badApp = true;
3601            }
3602        }
3603
3604        // Check if the next broadcast receiver is in this process...
3605        BroadcastRecord br = mPendingBroadcast;
3606        if (!badApp && br != null && br.curApp == app) {
3607            try {
3608                mPendingBroadcast = null;
3609                processCurBroadcastLocked(br, app);
3610                didSomething = true;
3611            } catch (Exception e) {
3612                Slog.w(TAG, "Exception in new application when starting receiver "
3613                      + br.curComponent.flattenToShortString(), e);
3614                badApp = true;
3615                logBroadcastReceiverDiscardLocked(br);
3616                finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3617                        br.resultExtras, br.resultAbort, true);
3618                scheduleBroadcastsLocked();
3619                // We need to reset the state if we fails to start the receiver.
3620                br.state = BroadcastRecord.IDLE;
3621            }
3622        }
3623
3624        // Check whether the next backup agent is in this process...
3625        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
3626            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
3627            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
3628            try {
3629                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode);
3630            } catch (Exception e) {
3631                Slog.w(TAG, "Exception scheduling backup agent creation: ");
3632                e.printStackTrace();
3633            }
3634        }
3635
3636        if (badApp) {
3637            // todo: Also need to kill application to deal with all
3638            // kinds of exceptions.
3639            handleAppDiedLocked(app, false);
3640            return false;
3641        }
3642
3643        if (!didSomething) {
3644            updateOomAdjLocked();
3645        }
3646
3647        return true;
3648    }
3649
3650    public final void attachApplication(IApplicationThread thread) {
3651        synchronized (this) {
3652            int callingPid = Binder.getCallingPid();
3653            final long origId = Binder.clearCallingIdentity();
3654            attachApplicationLocked(thread, callingPid);
3655            Binder.restoreCallingIdentity(origId);
3656        }
3657    }
3658
3659    public final void activityIdle(IBinder token, Configuration config) {
3660        final long origId = Binder.clearCallingIdentity();
3661        mMainStack.activityIdleInternal(token, false, config);
3662        Binder.restoreCallingIdentity(origId);
3663    }
3664
3665    void enableScreenAfterBoot() {
3666        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
3667                SystemClock.uptimeMillis());
3668        mWindowManager.enableScreenAfterBoot();
3669    }
3670
3671    final void finishBooting() {
3672        IntentFilter pkgFilter = new IntentFilter();
3673        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3674        pkgFilter.addDataScheme("package");
3675        mContext.registerReceiver(new BroadcastReceiver() {
3676            @Override
3677            public void onReceive(Context context, Intent intent) {
3678                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3679                if (pkgs != null) {
3680                    for (String pkg : pkgs) {
3681                        if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3682                            setResultCode(Activity.RESULT_OK);
3683                            return;
3684                        }
3685                    }
3686                }
3687            }
3688        }, pkgFilter);
3689
3690        synchronized (this) {
3691            // Ensure that any processes we had put on hold are now started
3692            // up.
3693            final int NP = mProcessesOnHold.size();
3694            if (NP > 0) {
3695                ArrayList<ProcessRecord> procs =
3696                    new ArrayList<ProcessRecord>(mProcessesOnHold);
3697                for (int ip=0; ip<NP; ip++) {
3698                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3699                            + procs.get(ip));
3700                    startProcessLocked(procs.get(ip), "on-hold", null);
3701                }
3702            }
3703
3704            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
3705                // Start looking for apps that are abusing wake locks.
3706                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
3707                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
3708                // Tell anyone interested that we are done booting!
3709                SystemProperties.set("sys.boot_completed", "1");
3710                broadcastIntentLocked(null, null,
3711                        new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3712                        null, null, 0, null, null,
3713                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3714                        false, false, MY_PID, Process.SYSTEM_UID);
3715            }
3716        }
3717    }
3718
3719    final void ensureBootCompleted() {
3720        boolean booting;
3721        boolean enableScreen;
3722        synchronized (this) {
3723            booting = mBooting;
3724            mBooting = false;
3725            enableScreen = !mBooted;
3726            mBooted = true;
3727        }
3728
3729        if (booting) {
3730            finishBooting();
3731        }
3732
3733        if (enableScreen) {
3734            enableScreenAfterBoot();
3735        }
3736    }
3737
3738    public final void activityPaused(IBinder token, Bundle icicle) {
3739        // Refuse possible leaked file descriptors
3740        if (icicle != null && icicle.hasFileDescriptors()) {
3741            throw new IllegalArgumentException("File descriptors passed in Bundle");
3742        }
3743
3744        final long origId = Binder.clearCallingIdentity();
3745        mMainStack.activityPaused(token, icicle, false);
3746        Binder.restoreCallingIdentity(origId);
3747    }
3748
3749    public final void activityStopped(IBinder token, Bitmap thumbnail,
3750            CharSequence description) {
3751        if (localLOGV) Slog.v(
3752            TAG, "Activity stopped: token=" + token);
3753
3754        ActivityRecord r = null;
3755
3756        final long origId = Binder.clearCallingIdentity();
3757
3758        synchronized (this) {
3759            int index = mMainStack.indexOfTokenLocked(token);
3760            if (index >= 0) {
3761                r = (ActivityRecord)mMainStack.mHistory.get(index);
3762                r.thumbnail = thumbnail;
3763                r.description = description;
3764                r.stopped = true;
3765                r.state = ActivityState.STOPPED;
3766                if (!r.finishing) {
3767                    if (r.configDestroy) {
3768                        r.stack.destroyActivityLocked(r, true);
3769                        r.stack.resumeTopActivityLocked(null);
3770                    }
3771                }
3772            }
3773        }
3774
3775        if (r != null) {
3776            sendPendingThumbnail(r, null, null, null, false);
3777        }
3778
3779        trimApplications();
3780
3781        Binder.restoreCallingIdentity(origId);
3782    }
3783
3784    public final void activityDestroyed(IBinder token) {
3785        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
3786        mMainStack.activityDestroyed(token);
3787    }
3788
3789    public String getCallingPackage(IBinder token) {
3790        synchronized (this) {
3791            ActivityRecord r = getCallingRecordLocked(token);
3792            return r != null && r.app != null ? r.info.packageName : null;
3793        }
3794    }
3795
3796    public ComponentName getCallingActivity(IBinder token) {
3797        synchronized (this) {
3798            ActivityRecord r = getCallingRecordLocked(token);
3799            return r != null ? r.intent.getComponent() : null;
3800        }
3801    }
3802
3803    private ActivityRecord getCallingRecordLocked(IBinder token) {
3804        int index = mMainStack.indexOfTokenLocked(token);
3805        if (index >= 0) {
3806            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
3807            if (r != null) {
3808                return r.resultTo;
3809            }
3810        }
3811        return null;
3812    }
3813
3814    public ComponentName getActivityClassForToken(IBinder token) {
3815        synchronized(this) {
3816            int index = mMainStack.indexOfTokenLocked(token);
3817            if (index >= 0) {
3818                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
3819                return r.intent.getComponent();
3820            }
3821            return null;
3822        }
3823    }
3824
3825    public String getPackageForToken(IBinder token) {
3826        synchronized(this) {
3827            int index = mMainStack.indexOfTokenLocked(token);
3828            if (index >= 0) {
3829                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
3830                return r.packageName;
3831            }
3832            return null;
3833        }
3834    }
3835
3836    public IIntentSender getIntentSender(int type,
3837            String packageName, IBinder token, String resultWho,
3838            int requestCode, Intent intent, String resolvedType, int flags) {
3839        // Refuse possible leaked file descriptors
3840        if (intent != null && intent.hasFileDescriptors() == true) {
3841            throw new IllegalArgumentException("File descriptors passed in Intent");
3842        }
3843
3844        if (type == INTENT_SENDER_BROADCAST) {
3845            if ((intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3846                throw new IllegalArgumentException(
3847                        "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3848            }
3849        }
3850
3851        synchronized(this) {
3852            int callingUid = Binder.getCallingUid();
3853            try {
3854                if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
3855                        Process.supportsProcesses()) {
3856                    int uid = AppGlobals.getPackageManager()
3857                            .getPackageUid(packageName);
3858                    if (uid != Binder.getCallingUid()) {
3859                        String msg = "Permission Denial: getIntentSender() from pid="
3860                            + Binder.getCallingPid()
3861                            + ", uid=" + Binder.getCallingUid()
3862                            + ", (need uid=" + uid + ")"
3863                            + " is not allowed to send as package " + packageName;
3864                        Slog.w(TAG, msg);
3865                        throw new SecurityException(msg);
3866                    }
3867                }
3868
3869                return getIntentSenderLocked(type, packageName, callingUid,
3870                        token, resultWho, requestCode, intent, resolvedType, flags);
3871
3872            } catch (RemoteException e) {
3873                throw new SecurityException(e);
3874            }
3875        }
3876    }
3877
3878    IIntentSender getIntentSenderLocked(int type,
3879            String packageName, int callingUid, IBinder token, String resultWho,
3880            int requestCode, Intent intent, String resolvedType, int flags) {
3881        ActivityRecord activity = null;
3882        if (type == INTENT_SENDER_ACTIVITY_RESULT) {
3883            int index = mMainStack.indexOfTokenLocked(token);
3884            if (index < 0) {
3885                return null;
3886            }
3887            activity = (ActivityRecord)mMainStack.mHistory.get(index);
3888            if (activity.finishing) {
3889                return null;
3890            }
3891        }
3892
3893        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
3894        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
3895        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
3896        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
3897                |PendingIntent.FLAG_UPDATE_CURRENT);
3898
3899        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
3900                type, packageName, activity, resultWho,
3901                requestCode, intent, resolvedType, flags);
3902        WeakReference<PendingIntentRecord> ref;
3903        ref = mIntentSenderRecords.get(key);
3904        PendingIntentRecord rec = ref != null ? ref.get() : null;
3905        if (rec != null) {
3906            if (!cancelCurrent) {
3907                if (updateCurrent) {
3908                    rec.key.requestIntent.replaceExtras(intent);
3909                }
3910                return rec;
3911            }
3912            rec.canceled = true;
3913            mIntentSenderRecords.remove(key);
3914        }
3915        if (noCreate) {
3916            return rec;
3917        }
3918        rec = new PendingIntentRecord(this, key, callingUid);
3919        mIntentSenderRecords.put(key, rec.ref);
3920        if (type == INTENT_SENDER_ACTIVITY_RESULT) {
3921            if (activity.pendingResults == null) {
3922                activity.pendingResults
3923                        = new HashSet<WeakReference<PendingIntentRecord>>();
3924            }
3925            activity.pendingResults.add(rec.ref);
3926        }
3927        return rec;
3928    }
3929
3930    public void cancelIntentSender(IIntentSender sender) {
3931        if (!(sender instanceof PendingIntentRecord)) {
3932            return;
3933        }
3934        synchronized(this) {
3935            PendingIntentRecord rec = (PendingIntentRecord)sender;
3936            try {
3937                int uid = AppGlobals.getPackageManager()
3938                        .getPackageUid(rec.key.packageName);
3939                if (uid != Binder.getCallingUid()) {
3940                    String msg = "Permission Denial: cancelIntentSender() from pid="
3941                        + Binder.getCallingPid()
3942                        + ", uid=" + Binder.getCallingUid()
3943                        + " is not allowed to cancel packges "
3944                        + rec.key.packageName;
3945                    Slog.w(TAG, msg);
3946                    throw new SecurityException(msg);
3947                }
3948            } catch (RemoteException e) {
3949                throw new SecurityException(e);
3950            }
3951            cancelIntentSenderLocked(rec, true);
3952        }
3953    }
3954
3955    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
3956        rec.canceled = true;
3957        mIntentSenderRecords.remove(rec.key);
3958        if (cleanActivity && rec.key.activity != null) {
3959            rec.key.activity.pendingResults.remove(rec.ref);
3960        }
3961    }
3962
3963    public String getPackageForIntentSender(IIntentSender pendingResult) {
3964        if (!(pendingResult instanceof PendingIntentRecord)) {
3965            return null;
3966        }
3967        try {
3968            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
3969            return res.key.packageName;
3970        } catch (ClassCastException e) {
3971        }
3972        return null;
3973    }
3974
3975    public void setProcessLimit(int max) {
3976        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
3977                "setProcessLimit()");
3978        mProcessLimit = max;
3979    }
3980
3981    public int getProcessLimit() {
3982        return mProcessLimit;
3983    }
3984
3985    void foregroundTokenDied(ForegroundToken token) {
3986        synchronized (ActivityManagerService.this) {
3987            synchronized (mPidsSelfLocked) {
3988                ForegroundToken cur
3989                    = mForegroundProcesses.get(token.pid);
3990                if (cur != token) {
3991                    return;
3992                }
3993                mForegroundProcesses.remove(token.pid);
3994                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
3995                if (pr == null) {
3996                    return;
3997                }
3998                pr.forcingToForeground = null;
3999                pr.foregroundServices = false;
4000            }
4001            updateOomAdjLocked();
4002        }
4003    }
4004
4005    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4006        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4007                "setProcessForeground()");
4008        synchronized(this) {
4009            boolean changed = false;
4010
4011            synchronized (mPidsSelfLocked) {
4012                ProcessRecord pr = mPidsSelfLocked.get(pid);
4013                if (pr == null) {
4014                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4015                    return;
4016                }
4017                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4018                if (oldToken != null) {
4019                    oldToken.token.unlinkToDeath(oldToken, 0);
4020                    mForegroundProcesses.remove(pid);
4021                    pr.forcingToForeground = null;
4022                    changed = true;
4023                }
4024                if (isForeground && token != null) {
4025                    ForegroundToken newToken = new ForegroundToken() {
4026                        public void binderDied() {
4027                            foregroundTokenDied(this);
4028                        }
4029                    };
4030                    newToken.pid = pid;
4031                    newToken.token = token;
4032                    try {
4033                        token.linkToDeath(newToken, 0);
4034                        mForegroundProcesses.put(pid, newToken);
4035                        pr.forcingToForeground = token;
4036                        changed = true;
4037                    } catch (RemoteException e) {
4038                        // If the process died while doing this, we will later
4039                        // do the cleanup with the process death link.
4040                    }
4041                }
4042            }
4043
4044            if (changed) {
4045                updateOomAdjLocked();
4046            }
4047        }
4048    }
4049
4050    // =========================================================
4051    // PERMISSIONS
4052    // =========================================================
4053
4054    static class PermissionController extends IPermissionController.Stub {
4055        ActivityManagerService mActivityManagerService;
4056        PermissionController(ActivityManagerService activityManagerService) {
4057            mActivityManagerService = activityManagerService;
4058        }
4059
4060        public boolean checkPermission(String permission, int pid, int uid) {
4061            return mActivityManagerService.checkPermission(permission, pid,
4062                    uid) == PackageManager.PERMISSION_GRANTED;
4063        }
4064    }
4065
4066    /**
4067     * This can be called with or without the global lock held.
4068     */
4069    int checkComponentPermission(String permission, int pid, int uid,
4070            int reqUid) {
4071        // We might be performing an operation on behalf of an indirect binder
4072        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4073        // client identity accordingly before proceeding.
4074        Identity tlsIdentity = sCallerIdentity.get();
4075        if (tlsIdentity != null) {
4076            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4077                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4078            uid = tlsIdentity.uid;
4079            pid = tlsIdentity.pid;
4080        }
4081
4082        // Root, system server and our own process get to do everything.
4083        if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
4084            !Process.supportsProcesses()) {
4085            return PackageManager.PERMISSION_GRANTED;
4086        }
4087        // If the target requires a specific UID, always fail for others.
4088        if (reqUid >= 0 && uid != reqUid) {
4089            Slog.w(TAG, "Permission denied: checkComponentPermission() reqUid=" + reqUid);
4090            return PackageManager.PERMISSION_DENIED;
4091        }
4092        if (permission == null) {
4093            return PackageManager.PERMISSION_GRANTED;
4094        }
4095        try {
4096            return AppGlobals.getPackageManager()
4097                    .checkUidPermission(permission, uid);
4098        } catch (RemoteException e) {
4099            // Should never happen, but if it does... deny!
4100            Slog.e(TAG, "PackageManager is dead?!?", e);
4101        }
4102        return PackageManager.PERMISSION_DENIED;
4103    }
4104
4105    /**
4106     * As the only public entry point for permissions checking, this method
4107     * can enforce the semantic that requesting a check on a null global
4108     * permission is automatically denied.  (Internally a null permission
4109     * string is used when calling {@link #checkComponentPermission} in cases
4110     * when only uid-based security is needed.)
4111     *
4112     * This can be called with or without the global lock held.
4113     */
4114    public int checkPermission(String permission, int pid, int uid) {
4115        if (permission == null) {
4116            return PackageManager.PERMISSION_DENIED;
4117        }
4118        return checkComponentPermission(permission, pid, uid, -1);
4119    }
4120
4121    /**
4122     * Binder IPC calls go through the public entry point.
4123     * This can be called with or without the global lock held.
4124     */
4125    int checkCallingPermission(String permission) {
4126        return checkPermission(permission,
4127                Binder.getCallingPid(),
4128                Binder.getCallingUid());
4129    }
4130
4131    /**
4132     * This can be called with or without the global lock held.
4133     */
4134    void enforceCallingPermission(String permission, String func) {
4135        if (checkCallingPermission(permission)
4136                == PackageManager.PERMISSION_GRANTED) {
4137            return;
4138        }
4139
4140        String msg = "Permission Denial: " + func + " from pid="
4141                + Binder.getCallingPid()
4142                + ", uid=" + Binder.getCallingUid()
4143                + " requires " + permission;
4144        Slog.w(TAG, msg);
4145        throw new SecurityException(msg);
4146    }
4147
4148    private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
4149            ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4150        boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4151        boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4152        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4153                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4154        try {
4155            // Is the component private from the target uid?
4156            final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4157
4158            // Acceptable if the there is no read permission needed from the
4159            // target or the target is holding the read permission.
4160            if (!readPerm) {
4161                if ((!prv && pi.readPermission == null) ||
4162                        (pm.checkUidPermission(pi.readPermission, uid)
4163                                == PackageManager.PERMISSION_GRANTED)) {
4164                    readPerm = true;
4165                }
4166            }
4167
4168            // Acceptable if the there is no write permission needed from the
4169            // target or the target is holding the read permission.
4170            if (!writePerm) {
4171                if (!prv && (pi.writePermission == null) ||
4172                        (pm.checkUidPermission(pi.writePermission, uid)
4173                                == PackageManager.PERMISSION_GRANTED)) {
4174                    writePerm = true;
4175                }
4176            }
4177
4178            // Acceptable if there is a path permission matching the URI that
4179            // the target holds the permission on.
4180            PathPermission[] pps = pi.pathPermissions;
4181            if (pps != null && (!readPerm || !writePerm)) {
4182                final String path = uri.getPath();
4183                int i = pps.length;
4184                while (i > 0 && (!readPerm || !writePerm)) {
4185                    i--;
4186                    PathPermission pp = pps[i];
4187                    if (!readPerm) {
4188                        final String pprperm = pp.getReadPermission();
4189                        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4190                                + pprperm + " for " + pp.getPath()
4191                                + ": match=" + pp.match(path)
4192                                + " check=" + pm.checkUidPermission(pprperm, uid));
4193                        if (pprperm != null && pp.match(path) &&
4194                                (pm.checkUidPermission(pprperm, uid)
4195                                        == PackageManager.PERMISSION_GRANTED)) {
4196                            readPerm = true;
4197                        }
4198                    }
4199                    if (!writePerm) {
4200                        final String ppwperm = pp.getWritePermission();
4201                        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4202                                + ppwperm + " for " + pp.getPath()
4203                                + ": match=" + pp.match(path)
4204                                + " check=" + pm.checkUidPermission(ppwperm, uid));
4205                        if (ppwperm != null && pp.match(path) &&
4206                                (pm.checkUidPermission(ppwperm, uid)
4207                                        == PackageManager.PERMISSION_GRANTED)) {
4208                            writePerm = true;
4209                        }
4210                    }
4211                }
4212            }
4213        } catch (RemoteException e) {
4214            return false;
4215        }
4216
4217        return readPerm && writePerm;
4218    }
4219
4220    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4221            int modeFlags) {
4222        // Root gets to do everything.
4223        if (uid == 0 || !Process.supportsProcesses()) {
4224            return true;
4225        }
4226        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4227        if (perms == null) return false;
4228        UriPermission perm = perms.get(uri);
4229        if (perm == null) return false;
4230        return (modeFlags&perm.modeFlags) == modeFlags;
4231    }
4232
4233    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4234        // Another redirected-binder-call permissions check as in
4235        // {@link checkComponentPermission}.
4236        Identity tlsIdentity = sCallerIdentity.get();
4237        if (tlsIdentity != null) {
4238            uid = tlsIdentity.uid;
4239            pid = tlsIdentity.pid;
4240        }
4241
4242        // Our own process gets to do everything.
4243        if (pid == MY_PID) {
4244            return PackageManager.PERMISSION_GRANTED;
4245        }
4246        synchronized(this) {
4247            return checkUriPermissionLocked(uri, uid, modeFlags)
4248                    ? PackageManager.PERMISSION_GRANTED
4249                    : PackageManager.PERMISSION_DENIED;
4250        }
4251    }
4252
4253    /**
4254     * Check if the targetPkg can be granted permission to access uri by
4255     * the callingUid using the given modeFlags.  Throws a security exception
4256     * if callingUid is not allowed to do this.  Returns the uid of the target
4257     * if the URI permission grant should be performed; returns -1 if it is not
4258     * needed (for example targetPkg already has permission to access the URI).
4259     */
4260    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4261            Uri uri, int modeFlags) {
4262        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4263                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4264        if (modeFlags == 0) {
4265            return -1;
4266        }
4267
4268        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4269                "Checking grant " + targetPkg + " permission to " + uri);
4270
4271        final IPackageManager pm = AppGlobals.getPackageManager();
4272
4273        // If this is not a content: uri, we can't do anything with it.
4274        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4275            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4276                    "Can't grant URI permission for non-content URI: " + uri);
4277            return -1;
4278        }
4279
4280        String name = uri.getAuthority();
4281        ProviderInfo pi = null;
4282        ContentProviderRecord cpr = mProvidersByName.get(name);
4283        if (cpr != null) {
4284            pi = cpr.info;
4285        } else {
4286            try {
4287                pi = pm.resolveContentProvider(name,
4288                        PackageManager.GET_URI_PERMISSION_PATTERNS);
4289            } catch (RemoteException ex) {
4290            }
4291        }
4292        if (pi == null) {
4293            Slog.w(TAG, "No content provider found for: " + name);
4294            return -1;
4295        }
4296
4297        int targetUid;
4298        try {
4299            targetUid = pm.getPackageUid(targetPkg);
4300            if (targetUid < 0) {
4301                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4302                        "Can't grant URI permission no uid for: " + targetPkg);
4303                return -1;
4304            }
4305        } catch (RemoteException ex) {
4306            return -1;
4307        }
4308
4309        // First...  does the target actually need this permission?
4310        if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4311            // No need to grant the target this permission.
4312            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4313                    "Target " + targetPkg + " already has full permission to " + uri);
4314            return -1;
4315        }
4316
4317        // Second...  is the provider allowing granting of URI permissions?
4318        if (!pi.grantUriPermissions) {
4319            throw new SecurityException("Provider " + pi.packageName
4320                    + "/" + pi.name
4321                    + " does not allow granting of Uri permissions (uri "
4322                    + uri + ")");
4323        }
4324        if (pi.uriPermissionPatterns != null) {
4325            final int N = pi.uriPermissionPatterns.length;
4326            boolean allowed = false;
4327            for (int i=0; i<N; i++) {
4328                if (pi.uriPermissionPatterns[i] != null
4329                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4330                    allowed = true;
4331                    break;
4332                }
4333            }
4334            if (!allowed) {
4335                throw new SecurityException("Provider " + pi.packageName
4336                        + "/" + pi.name
4337                        + " does not allow granting of permission to path of Uri "
4338                        + uri);
4339            }
4340        }
4341
4342        // Third...  does the caller itself have permission to access
4343        // this uri?
4344        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4345            if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4346                throw new SecurityException("Uid " + callingUid
4347                        + " does not have permission to uri " + uri);
4348            }
4349        }
4350
4351        return targetUid;
4352    }
4353
4354    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4355            Uri uri, int modeFlags, UriPermissionOwner owner) {
4356        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4357                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4358        if (modeFlags == 0) {
4359            return;
4360        }
4361
4362        // So here we are: the caller has the assumed permission
4363        // to the uri, and the target doesn't.  Let's now give this to
4364        // the target.
4365
4366        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4367                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
4368
4369        HashMap<Uri, UriPermission> targetUris
4370                = mGrantedUriPermissions.get(targetUid);
4371        if (targetUris == null) {
4372            targetUris = new HashMap<Uri, UriPermission>();
4373            mGrantedUriPermissions.put(targetUid, targetUris);
4374        }
4375
4376        UriPermission perm = targetUris.get(uri);
4377        if (perm == null) {
4378            perm = new UriPermission(targetUid, uri);
4379            targetUris.put(uri, perm);
4380        }
4381
4382        perm.modeFlags |= modeFlags;
4383        if (owner == null) {
4384            perm.globalModeFlags |= modeFlags;
4385        } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4386            perm.readOwners.add(owner);
4387            owner.addReadPermission(perm);
4388        } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4389            perm.writeOwners.add(owner);
4390            owner.addWritePermission(perm);
4391        }
4392    }
4393
4394    void grantUriPermissionLocked(int callingUid,
4395            String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
4396        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4397        if (targetUid < 0) {
4398            return;
4399        }
4400
4401        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4402    }
4403
4404    /**
4405     * Like checkGrantUriPermissionLocked, but takes an Intent.
4406     */
4407    int checkGrantUriPermissionFromIntentLocked(int callingUid,
4408            String targetPkg, Intent intent) {
4409        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4410                "Checking URI perm to " + (intent != null ? intent.getData() : null)
4411                + " from " + intent + "; flags=0x"
4412                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4413
4414        if (intent == null) {
4415            return -1;
4416        }
4417        Uri data = intent.getData();
4418        if (data == null) {
4419            return -1;
4420        }
4421        return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4422                intent.getFlags());
4423    }
4424
4425    /**
4426     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4427     */
4428    void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4429            String targetPkg, Intent intent, UriPermissionOwner owner) {
4430        grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4431                intent.getFlags(), owner);
4432    }
4433
4434    void grantUriPermissionFromIntentLocked(int callingUid,
4435            String targetPkg, Intent intent, UriPermissionOwner owner) {
4436        int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4437        if (targetUid < 0) {
4438            return;
4439        }
4440
4441        grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
4442    }
4443
4444    public void grantUriPermission(IApplicationThread caller, String targetPkg,
4445            Uri uri, int modeFlags) {
4446        synchronized(this) {
4447            final ProcessRecord r = getRecordForAppLocked(caller);
4448            if (r == null) {
4449                throw new SecurityException("Unable to find app for caller "
4450                        + caller
4451                        + " when granting permission to uri " + uri);
4452            }
4453            if (targetPkg == null) {
4454                throw new IllegalArgumentException("null target");
4455            }
4456            if (uri == null) {
4457                throw new IllegalArgumentException("null uri");
4458            }
4459
4460            grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4461                    null);
4462        }
4463    }
4464
4465    void removeUriPermissionIfNeededLocked(UriPermission perm) {
4466        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4467                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4468            HashMap<Uri, UriPermission> perms
4469                    = mGrantedUriPermissions.get(perm.uid);
4470            if (perms != null) {
4471                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4472                        "Removing " + perm.uid + " permission to " + perm.uri);
4473                perms.remove(perm.uri);
4474                if (perms.size() == 0) {
4475                    mGrantedUriPermissions.remove(perm.uid);
4476                }
4477            }
4478        }
4479    }
4480
4481    private void revokeUriPermissionLocked(int callingUid, Uri uri,
4482            int modeFlags) {
4483        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4484                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4485        if (modeFlags == 0) {
4486            return;
4487        }
4488
4489        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4490                "Revoking all granted permissions to " + uri);
4491
4492        final IPackageManager pm = AppGlobals.getPackageManager();
4493
4494        final String authority = uri.getAuthority();
4495        ProviderInfo pi = null;
4496        ContentProviderRecord cpr = mProvidersByName.get(authority);
4497        if (cpr != null) {
4498            pi = cpr.info;
4499        } else {
4500            try {
4501                pi = pm.resolveContentProvider(authority,
4502                        PackageManager.GET_URI_PERMISSION_PATTERNS);
4503            } catch (RemoteException ex) {
4504            }
4505        }
4506        if (pi == null) {
4507            Slog.w(TAG, "No content provider found for: " + authority);
4508            return;
4509        }
4510
4511        // Does the caller have this permission on the URI?
4512        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4513            // Right now, if you are not the original owner of the permission,
4514            // you are not allowed to revoke it.
4515            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4516                throw new SecurityException("Uid " + callingUid
4517                        + " does not have permission to uri " + uri);
4518            //}
4519        }
4520
4521        // Go through all of the permissions and remove any that match.
4522        final List<String> SEGMENTS = uri.getPathSegments();
4523        if (SEGMENTS != null) {
4524            final int NS = SEGMENTS.size();
4525            int N = mGrantedUriPermissions.size();
4526            for (int i=0; i<N; i++) {
4527                HashMap<Uri, UriPermission> perms
4528                        = mGrantedUriPermissions.valueAt(i);
4529                Iterator<UriPermission> it = perms.values().iterator();
4530            toploop:
4531                while (it.hasNext()) {
4532                    UriPermission perm = it.next();
4533                    Uri targetUri = perm.uri;
4534                    if (!authority.equals(targetUri.getAuthority())) {
4535                        continue;
4536                    }
4537                    List<String> targetSegments = targetUri.getPathSegments();
4538                    if (targetSegments == null) {
4539                        continue;
4540                    }
4541                    if (targetSegments.size() < NS) {
4542                        continue;
4543                    }
4544                    for (int j=0; j<NS; j++) {
4545                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4546                            continue toploop;
4547                        }
4548                    }
4549                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4550                            "Revoking " + perm.uid + " permission to " + perm.uri);
4551                    perm.clearModes(modeFlags);
4552                    if (perm.modeFlags == 0) {
4553                        it.remove();
4554                    }
4555                }
4556                if (perms.size() == 0) {
4557                    mGrantedUriPermissions.remove(
4558                            mGrantedUriPermissions.keyAt(i));
4559                    N--;
4560                    i--;
4561                }
4562            }
4563        }
4564    }
4565
4566    public void revokeUriPermission(IApplicationThread caller, Uri uri,
4567            int modeFlags) {
4568        synchronized(this) {
4569            final ProcessRecord r = getRecordForAppLocked(caller);
4570            if (r == null) {
4571                throw new SecurityException("Unable to find app for caller "
4572                        + caller
4573                        + " when revoking permission to uri " + uri);
4574            }
4575            if (uri == null) {
4576                Slog.w(TAG, "revokeUriPermission: null uri");
4577                return;
4578            }
4579
4580            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4581                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4582            if (modeFlags == 0) {
4583                return;
4584            }
4585
4586            final IPackageManager pm = AppGlobals.getPackageManager();
4587
4588            final String authority = uri.getAuthority();
4589            ProviderInfo pi = null;
4590            ContentProviderRecord cpr = mProvidersByName.get(authority);
4591            if (cpr != null) {
4592                pi = cpr.info;
4593            } else {
4594                try {
4595                    pi = pm.resolveContentProvider(authority,
4596                            PackageManager.GET_URI_PERMISSION_PATTERNS);
4597                } catch (RemoteException ex) {
4598                }
4599            }
4600            if (pi == null) {
4601                Slog.w(TAG, "No content provider found for: " + authority);
4602                return;
4603            }
4604
4605            revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4606        }
4607    }
4608
4609    @Override
4610    public IBinder newUriPermissionOwner(String name) {
4611        synchronized(this) {
4612            UriPermissionOwner owner = new UriPermissionOwner(this, name);
4613            return owner.getExternalTokenLocked();
4614        }
4615    }
4616
4617    @Override
4618    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4619            Uri uri, int modeFlags) {
4620        synchronized(this) {
4621            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4622            if (owner == null) {
4623                throw new IllegalArgumentException("Unknown owner: " + token);
4624            }
4625            if (fromUid != Binder.getCallingUid()) {
4626                if (Binder.getCallingUid() != Process.myUid()) {
4627                    // Only system code can grant URI permissions on behalf
4628                    // of other users.
4629                    throw new SecurityException("nice try");
4630                }
4631            }
4632            if (targetPkg == null) {
4633                throw new IllegalArgumentException("null target");
4634            }
4635            if (uri == null) {
4636                throw new IllegalArgumentException("null uri");
4637            }
4638
4639            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4640        }
4641    }
4642
4643    @Override
4644    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4645        synchronized(this) {
4646            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4647            if (owner == null) {
4648                throw new IllegalArgumentException("Unknown owner: " + token);
4649            }
4650
4651            if (uri == null) {
4652                owner.removeUriPermissionsLocked(mode);
4653            } else {
4654                owner.removeUriPermissionLocked(uri, mode);
4655            }
4656        }
4657    }
4658
4659    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4660        synchronized (this) {
4661            ProcessRecord app =
4662                who != null ? getRecordForAppLocked(who) : null;
4663            if (app == null) return;
4664
4665            Message msg = Message.obtain();
4666            msg.what = WAIT_FOR_DEBUGGER_MSG;
4667            msg.obj = app;
4668            msg.arg1 = waiting ? 1 : 0;
4669            mHandler.sendMessage(msg);
4670        }
4671    }
4672
4673    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
4674        outInfo.availMem = Process.getFreeMemory();
4675        outInfo.threshold = HOME_APP_MEM;
4676        outInfo.lowMemory = outInfo.availMem <
4677                (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
4678    }
4679
4680    // =========================================================
4681    // TASK MANAGEMENT
4682    // =========================================================
4683
4684    public List getTasks(int maxNum, int flags,
4685                         IThumbnailReceiver receiver) {
4686        ArrayList list = new ArrayList();
4687
4688        PendingThumbnailsRecord pending = null;
4689        IApplicationThread topThumbnail = null;
4690        ActivityRecord topRecord = null;
4691
4692        synchronized(this) {
4693            if (localLOGV) Slog.v(
4694                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4695                + ", receiver=" + receiver);
4696
4697            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4698                    != PackageManager.PERMISSION_GRANTED) {
4699                if (receiver != null) {
4700                    // If the caller wants to wait for pending thumbnails,
4701                    // it ain't gonna get them.
4702                    try {
4703                        receiver.finished();
4704                    } catch (RemoteException ex) {
4705                    }
4706                }
4707                String msg = "Permission Denial: getTasks() from pid="
4708                        + Binder.getCallingPid()
4709                        + ", uid=" + Binder.getCallingUid()
4710                        + " requires " + android.Manifest.permission.GET_TASKS;
4711                Slog.w(TAG, msg);
4712                throw new SecurityException(msg);
4713            }
4714
4715            int pos = mMainStack.mHistory.size()-1;
4716            ActivityRecord next =
4717                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
4718            ActivityRecord top = null;
4719            CharSequence topDescription = null;
4720            TaskRecord curTask = null;
4721            int numActivities = 0;
4722            int numRunning = 0;
4723            while (pos >= 0 && maxNum > 0) {
4724                final ActivityRecord r = next;
4725                pos--;
4726                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
4727
4728                // Initialize state for next task if needed.
4729                if (top == null ||
4730                        (top.state == ActivityState.INITIALIZING
4731                            && top.task == r.task)) {
4732                    top = r;
4733                    topDescription = r.description;
4734                    curTask = r.task;
4735                    numActivities = numRunning = 0;
4736                }
4737
4738                // Add 'r' into the current task.
4739                numActivities++;
4740                if (r.app != null && r.app.thread != null) {
4741                    numRunning++;
4742                }
4743                if (topDescription == null) {
4744                    topDescription = r.description;
4745                }
4746
4747                if (localLOGV) Slog.v(
4748                    TAG, r.intent.getComponent().flattenToShortString()
4749                    + ": task=" + r.task);
4750
4751                // If the next one is a different task, generate a new
4752                // TaskInfo entry for what we have.
4753                if (next == null || next.task != curTask) {
4754                    ActivityManager.RunningTaskInfo ci
4755                            = new ActivityManager.RunningTaskInfo();
4756                    ci.id = curTask.taskId;
4757                    ci.baseActivity = r.intent.getComponent();
4758                    ci.topActivity = top.intent.getComponent();
4759                    ci.thumbnail = top.thumbnail;
4760                    ci.description = topDescription;
4761                    ci.numActivities = numActivities;
4762                    ci.numRunning = numRunning;
4763                    //System.out.println(
4764                    //    "#" + maxNum + ": " + " descr=" + ci.description);
4765                    if (ci.thumbnail == null && receiver != null) {
4766                        if (localLOGV) Slog.v(
4767                            TAG, "State=" + top.state + "Idle=" + top.idle
4768                            + " app=" + top.app
4769                            + " thr=" + (top.app != null ? top.app.thread : null));
4770                        if (top.state == ActivityState.RESUMED
4771                                || top.state == ActivityState.PAUSING) {
4772                            if (top.idle && top.app != null
4773                                && top.app.thread != null) {
4774                                topRecord = top;
4775                                topThumbnail = top.app.thread;
4776                            } else {
4777                                top.thumbnailNeeded = true;
4778                            }
4779                        }
4780                        if (pending == null) {
4781                            pending = new PendingThumbnailsRecord(receiver);
4782                        }
4783                        pending.pendingRecords.add(top);
4784                    }
4785                    list.add(ci);
4786                    maxNum--;
4787                    top = null;
4788                }
4789            }
4790
4791            if (pending != null) {
4792                mPendingThumbnails.add(pending);
4793            }
4794        }
4795
4796        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
4797
4798        if (topThumbnail != null) {
4799            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
4800            try {
4801                topThumbnail.requestThumbnail(topRecord);
4802            } catch (Exception e) {
4803                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
4804                sendPendingThumbnail(null, topRecord, null, null, true);
4805            }
4806        }
4807
4808        if (pending == null && receiver != null) {
4809            // In this case all thumbnails were available and the client
4810            // is being asked to be told when the remaining ones come in...
4811            // which is unusually, since the top-most currently running
4812            // activity should never have a canned thumbnail!  Oh well.
4813            try {
4814                receiver.finished();
4815            } catch (RemoteException ex) {
4816            }
4817        }
4818
4819        return list;
4820    }
4821
4822    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
4823            int flags) {
4824        synchronized (this) {
4825            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
4826                    "getRecentTasks()");
4827
4828            IPackageManager pm = AppGlobals.getPackageManager();
4829
4830            final int N = mRecentTasks.size();
4831            ArrayList<ActivityManager.RecentTaskInfo> res
4832                    = new ArrayList<ActivityManager.RecentTaskInfo>(
4833                            maxNum < N ? maxNum : N);
4834            for (int i=0; i<N && maxNum > 0; i++) {
4835                TaskRecord tr = mRecentTasks.get(i);
4836                if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
4837                        || (tr.intent == null)
4838                        || ((tr.intent.getFlags()
4839                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
4840                    ActivityManager.RecentTaskInfo rti
4841                            = new ActivityManager.RecentTaskInfo();
4842                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
4843                    rti.baseIntent = new Intent(
4844                            tr.intent != null ? tr.intent : tr.affinityIntent);
4845                    rti.origActivity = tr.origActivity;
4846
4847                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
4848                        // Check whether this activity is currently available.
4849                        try {
4850                            if (rti.origActivity != null) {
4851                                if (pm.getActivityInfo(rti.origActivity, 0) == null) {
4852                                    continue;
4853                                }
4854                            } else if (rti.baseIntent != null) {
4855                                if (pm.queryIntentActivities(rti.baseIntent,
4856                                        null, 0) == null) {
4857                                    continue;
4858                                }
4859                            }
4860                        } catch (RemoteException e) {
4861                            // Will never happen.
4862                        }
4863                    }
4864
4865                    res.add(rti);
4866                    maxNum--;
4867                }
4868            }
4869            return res;
4870        }
4871    }
4872
4873    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
4874        int j;
4875        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
4876        TaskRecord jt = startTask;
4877
4878        // First look backwards
4879        for (j=startIndex-1; j>=0; j--) {
4880            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
4881            if (r.task != jt) {
4882                jt = r.task;
4883                if (affinity.equals(jt.affinity)) {
4884                    return j;
4885                }
4886            }
4887        }
4888
4889        // Now look forwards
4890        final int N = mMainStack.mHistory.size();
4891        jt = startTask;
4892        for (j=startIndex+1; j<N; j++) {
4893            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
4894            if (r.task != jt) {
4895                if (affinity.equals(jt.affinity)) {
4896                    return j;
4897                }
4898                jt = r.task;
4899            }
4900        }
4901
4902        // Might it be at the top?
4903        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
4904            return N-1;
4905        }
4906
4907        return -1;
4908    }
4909
4910    /**
4911     * TODO: Add mController hook
4912     */
4913    public void moveTaskToFront(int task) {
4914        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
4915                "moveTaskToFront()");
4916
4917        synchronized(this) {
4918            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
4919                    Binder.getCallingUid(), "Task to front")) {
4920                return;
4921            }
4922            final long origId = Binder.clearCallingIdentity();
4923            try {
4924                int N = mRecentTasks.size();
4925                for (int i=0; i<N; i++) {
4926                    TaskRecord tr = mRecentTasks.get(i);
4927                    if (tr.taskId == task) {
4928                        mMainStack.moveTaskToFrontLocked(tr, null);
4929                        return;
4930                    }
4931                }
4932                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
4933                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
4934                    if (hr.task.taskId == task) {
4935                        mMainStack.moveTaskToFrontLocked(hr.task, null);
4936                        return;
4937                    }
4938                }
4939            } finally {
4940                Binder.restoreCallingIdentity(origId);
4941            }
4942        }
4943    }
4944
4945    public void moveTaskToBack(int task) {
4946        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
4947                "moveTaskToBack()");
4948
4949        synchronized(this) {
4950            if (mMainStack.mResumedActivity != null
4951                    && mMainStack.mResumedActivity.task.taskId == task) {
4952                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
4953                        Binder.getCallingUid(), "Task to back")) {
4954                    return;
4955                }
4956            }
4957            final long origId = Binder.clearCallingIdentity();
4958            mMainStack.moveTaskToBackLocked(task, null);
4959            Binder.restoreCallingIdentity(origId);
4960        }
4961    }
4962
4963    /**
4964     * Moves an activity, and all of the other activities within the same task, to the bottom
4965     * of the history stack.  The activity's order within the task is unchanged.
4966     *
4967     * @param token A reference to the activity we wish to move
4968     * @param nonRoot If false then this only works if the activity is the root
4969     *                of a task; if true it will work for any activity in a task.
4970     * @return Returns true if the move completed, false if not.
4971     */
4972    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
4973        synchronized(this) {
4974            final long origId = Binder.clearCallingIdentity();
4975            int taskId = getTaskForActivityLocked(token, !nonRoot);
4976            if (taskId >= 0) {
4977                return mMainStack.moveTaskToBackLocked(taskId, null);
4978            }
4979            Binder.restoreCallingIdentity(origId);
4980        }
4981        return false;
4982    }
4983
4984    public void moveTaskBackwards(int task) {
4985        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
4986                "moveTaskBackwards()");
4987
4988        synchronized(this) {
4989            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
4990                    Binder.getCallingUid(), "Task backwards")) {
4991                return;
4992            }
4993            final long origId = Binder.clearCallingIdentity();
4994            moveTaskBackwardsLocked(task);
4995            Binder.restoreCallingIdentity(origId);
4996        }
4997    }
4998
4999    private final void moveTaskBackwardsLocked(int task) {
5000        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5001    }
5002
5003    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5004        synchronized(this) {
5005            return getTaskForActivityLocked(token, onlyRoot);
5006        }
5007    }
5008
5009    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5010        final int N = mMainStack.mHistory.size();
5011        TaskRecord lastTask = null;
5012        for (int i=0; i<N; i++) {
5013            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5014            if (r == token) {
5015                if (!onlyRoot || lastTask != r.task) {
5016                    return r.task.taskId;
5017                }
5018                return -1;
5019            }
5020            lastTask = r.task;
5021        }
5022
5023        return -1;
5024    }
5025
5026    public void finishOtherInstances(IBinder token, ComponentName className) {
5027        synchronized(this) {
5028            final long origId = Binder.clearCallingIdentity();
5029
5030            int N = mMainStack.mHistory.size();
5031            TaskRecord lastTask = null;
5032            for (int i=0; i<N; i++) {
5033                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5034                if (r.realActivity.equals(className)
5035                        && r != token && lastTask != r.task) {
5036                    if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
5037                            null, "others")) {
5038                        i--;
5039                        N--;
5040                    }
5041                }
5042                lastTask = r.task;
5043            }
5044
5045            Binder.restoreCallingIdentity(origId);
5046        }
5047    }
5048
5049    // =========================================================
5050    // THUMBNAILS
5051    // =========================================================
5052
5053    public void reportThumbnail(IBinder token,
5054            Bitmap thumbnail, CharSequence description) {
5055        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5056        final long origId = Binder.clearCallingIdentity();
5057        sendPendingThumbnail(null, token, thumbnail, description, true);
5058        Binder.restoreCallingIdentity(origId);
5059    }
5060
5061    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5062            Bitmap thumbnail, CharSequence description, boolean always) {
5063        TaskRecord task = null;
5064        ArrayList receivers = null;
5065
5066        //System.out.println("Send pending thumbnail: " + r);
5067
5068        synchronized(this) {
5069            if (r == null) {
5070                int index = mMainStack.indexOfTokenLocked(token);
5071                if (index < 0) {
5072                    return;
5073                }
5074                r = (ActivityRecord)mMainStack.mHistory.get(index);
5075            }
5076            if (thumbnail == null) {
5077                thumbnail = r.thumbnail;
5078                description = r.description;
5079            }
5080            if (thumbnail == null && !always) {
5081                // If there is no thumbnail, and this entry is not actually
5082                // going away, then abort for now and pick up the next
5083                // thumbnail we get.
5084                return;
5085            }
5086            task = r.task;
5087
5088            int N = mPendingThumbnails.size();
5089            int i=0;
5090            while (i<N) {
5091                PendingThumbnailsRecord pr =
5092                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5093                //System.out.println("Looking in " + pr.pendingRecords);
5094                if (pr.pendingRecords.remove(r)) {
5095                    if (receivers == null) {
5096                        receivers = new ArrayList();
5097                    }
5098                    receivers.add(pr);
5099                    if (pr.pendingRecords.size() == 0) {
5100                        pr.finished = true;
5101                        mPendingThumbnails.remove(i);
5102                        N--;
5103                        continue;
5104                    }
5105                }
5106                i++;
5107            }
5108        }
5109
5110        if (receivers != null) {
5111            final int N = receivers.size();
5112            for (int i=0; i<N; i++) {
5113                try {
5114                    PendingThumbnailsRecord pr =
5115                        (PendingThumbnailsRecord)receivers.get(i);
5116                    pr.receiver.newThumbnail(
5117                        task != null ? task.taskId : -1, thumbnail, description);
5118                    if (pr.finished) {
5119                        pr.receiver.finished();
5120                    }
5121                } catch (Exception e) {
5122                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
5123                }
5124            }
5125        }
5126    }
5127
5128    // =========================================================
5129    // CONTENT PROVIDERS
5130    // =========================================================
5131
5132    private final List generateApplicationProvidersLocked(ProcessRecord app) {
5133        List providers = null;
5134        try {
5135            providers = AppGlobals.getPackageManager().
5136                queryContentProviders(app.processName, app.info.uid,
5137                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
5138        } catch (RemoteException ex) {
5139        }
5140        if (providers != null) {
5141            final int N = providers.size();
5142            for (int i=0; i<N; i++) {
5143                ProviderInfo cpi =
5144                    (ProviderInfo)providers.get(i);
5145                ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
5146                if (cpr == null) {
5147                    cpr = new ContentProviderRecord(cpi, app.info);
5148                    mProvidersByClass.put(cpi.name, cpr);
5149                }
5150                app.pubProviders.put(cpi.name, cpr);
5151                app.addPackage(cpi.applicationInfo.packageName);
5152                ensurePackageDexOpt(cpi.applicationInfo.packageName);
5153            }
5154        }
5155        return providers;
5156    }
5157
5158    private final String checkContentProviderPermissionLocked(
5159            ProviderInfo cpi, ProcessRecord r) {
5160        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5161        final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5162        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
5163                cpi.exported ? -1 : cpi.applicationInfo.uid)
5164                == PackageManager.PERMISSION_GRANTED) {
5165            return null;
5166        }
5167        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
5168                cpi.exported ? -1 : cpi.applicationInfo.uid)
5169                == PackageManager.PERMISSION_GRANTED) {
5170            return null;
5171        }
5172
5173        PathPermission[] pps = cpi.pathPermissions;
5174        if (pps != null) {
5175            int i = pps.length;
5176            while (i > 0) {
5177                i--;
5178                PathPermission pp = pps[i];
5179                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
5180                        cpi.exported ? -1 : cpi.applicationInfo.uid)
5181                        == PackageManager.PERMISSION_GRANTED) {
5182                    return null;
5183                }
5184                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
5185                        cpi.exported ? -1 : cpi.applicationInfo.uid)
5186                        == PackageManager.PERMISSION_GRANTED) {
5187                    return null;
5188                }
5189            }
5190        }
5191
5192        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5193        if (perms != null) {
5194            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5195                if (uri.getKey().getAuthority().equals(cpi.authority)) {
5196                    return null;
5197                }
5198            }
5199        }
5200
5201        String msg = "Permission Denial: opening provider " + cpi.name
5202                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5203                + ", uid=" + callingUid + ") requires "
5204                + cpi.readPermission + " or " + cpi.writePermission;
5205        Slog.w(TAG, msg);
5206        return msg;
5207    }
5208
5209    private final ContentProviderHolder getContentProviderImpl(
5210        IApplicationThread caller, String name) {
5211        ContentProviderRecord cpr;
5212        ProviderInfo cpi = null;
5213
5214        synchronized(this) {
5215            ProcessRecord r = null;
5216            if (caller != null) {
5217                r = getRecordForAppLocked(caller);
5218                if (r == null) {
5219                    throw new SecurityException(
5220                            "Unable to find app for caller " + caller
5221                          + " (pid=" + Binder.getCallingPid()
5222                          + ") when getting content provider " + name);
5223                }
5224            }
5225
5226            // First check if this content provider has been published...
5227            cpr = mProvidersByName.get(name);
5228            if (cpr != null) {
5229                cpi = cpr.info;
5230                String msg;
5231                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5232                    throw new SecurityException(msg);
5233                }
5234
5235                if (r != null && cpr.canRunHere(r)) {
5236                    // This provider has been published or is in the process
5237                    // of being published...  but it is also allowed to run
5238                    // in the caller's process, so don't make a connection
5239                    // and just let the caller instantiate its own instance.
5240                    if (cpr.provider != null) {
5241                        // don't give caller the provider object, it needs
5242                        // to make its own.
5243                        cpr = new ContentProviderRecord(cpr);
5244                    }
5245                    return cpr;
5246                }
5247
5248                final long origId = Binder.clearCallingIdentity();
5249
5250                // In this case the provider instance already exists, so we can
5251                // return it right away.
5252                if (r != null) {
5253                    if (DEBUG_PROVIDER) Slog.v(TAG,
5254                            "Adding provider requested by "
5255                            + r.processName + " from process "
5256                            + cpr.info.processName);
5257                    Integer cnt = r.conProviders.get(cpr);
5258                    if (cnt == null) {
5259                        r.conProviders.put(cpr, new Integer(1));
5260                    } else {
5261                        r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5262                    }
5263                    cpr.clients.add(r);
5264                    if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) {
5265                        // If this is a perceptible app accessing the provider,
5266                        // make sure to count it as being accessed and thus
5267                        // back up on the LRU list.  This is good because
5268                        // content providers are often expensive to start.
5269                        updateLruProcessLocked(cpr.app, false, true);
5270                    }
5271                } else {
5272                    cpr.externals++;
5273                }
5274
5275                if (cpr.app != null) {
5276                    updateOomAdjLocked(cpr.app);
5277                }
5278
5279                Binder.restoreCallingIdentity(origId);
5280
5281            } else {
5282                try {
5283                    cpi = AppGlobals.getPackageManager().
5284                        resolveContentProvider(name,
5285                                STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
5286                } catch (RemoteException ex) {
5287                }
5288                if (cpi == null) {
5289                    return null;
5290                }
5291
5292                String msg;
5293                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5294                    throw new SecurityException(msg);
5295                }
5296
5297                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
5298                        && !cpi.processName.equals("system")) {
5299                    // If this content provider does not run in the system
5300                    // process, and the system is not yet ready to run other
5301                    // processes, then fail fast instead of hanging.
5302                    throw new IllegalArgumentException(
5303                            "Attempt to launch content provider before system ready");
5304                }
5305
5306                cpr = mProvidersByClass.get(cpi.name);
5307                final boolean firstClass = cpr == null;
5308                if (firstClass) {
5309                    try {
5310                        ApplicationInfo ai =
5311                            AppGlobals.getPackageManager().
5312                                getApplicationInfo(
5313                                        cpi.applicationInfo.packageName,
5314                                        STOCK_PM_FLAGS);
5315                        if (ai == null) {
5316                            Slog.w(TAG, "No package info for content provider "
5317                                    + cpi.name);
5318                            return null;
5319                        }
5320                        cpr = new ContentProviderRecord(cpi, ai);
5321                    } catch (RemoteException ex) {
5322                        // pm is in same process, this will never happen.
5323                    }
5324                }
5325
5326                if (r != null && cpr.canRunHere(r)) {
5327                    // If this is a multiprocess provider, then just return its
5328                    // info and allow the caller to instantiate it.  Only do
5329                    // this if the provider is the same user as the caller's
5330                    // process, or can run as root (so can be in any process).
5331                    return cpr;
5332                }
5333
5334                if (DEBUG_PROVIDER) {
5335                    RuntimeException e = new RuntimeException("here");
5336                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
5337                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
5338                }
5339
5340                // This is single process, and our app is now connecting to it.
5341                // See if we are already in the process of launching this
5342                // provider.
5343                final int N = mLaunchingProviders.size();
5344                int i;
5345                for (i=0; i<N; i++) {
5346                    if (mLaunchingProviders.get(i) == cpr) {
5347                        break;
5348                    }
5349                }
5350
5351                // If the provider is not already being launched, then get it
5352                // started.
5353                if (i >= N) {
5354                    final long origId = Binder.clearCallingIdentity();
5355                    ProcessRecord proc = startProcessLocked(cpi.processName,
5356                            cpr.appInfo, false, 0, "content provider",
5357                            new ComponentName(cpi.applicationInfo.packageName,
5358                                    cpi.name), false);
5359                    if (proc == null) {
5360                        Slog.w(TAG, "Unable to launch app "
5361                                + cpi.applicationInfo.packageName + "/"
5362                                + cpi.applicationInfo.uid + " for provider "
5363                                + name + ": process is bad");
5364                        return null;
5365                    }
5366                    cpr.launchingApp = proc;
5367                    mLaunchingProviders.add(cpr);
5368                    Binder.restoreCallingIdentity(origId);
5369                }
5370
5371                // Make sure the provider is published (the same provider class
5372                // may be published under multiple names).
5373                if (firstClass) {
5374                    mProvidersByClass.put(cpi.name, cpr);
5375                }
5376                mProvidersByName.put(name, cpr);
5377
5378                if (r != null) {
5379                    if (DEBUG_PROVIDER) Slog.v(TAG,
5380                            "Adding provider requested by "
5381                            + r.processName + " from process "
5382                            + cpr.info.processName);
5383                    Integer cnt = r.conProviders.get(cpr);
5384                    if (cnt == null) {
5385                        r.conProviders.put(cpr, new Integer(1));
5386                    } else {
5387                        r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5388                    }
5389                    cpr.clients.add(r);
5390                } else {
5391                    cpr.externals++;
5392                }
5393            }
5394        }
5395
5396        // Wait for the provider to be published...
5397        synchronized (cpr) {
5398            while (cpr.provider == null) {
5399                if (cpr.launchingApp == null) {
5400                    Slog.w(TAG, "Unable to launch app "
5401                            + cpi.applicationInfo.packageName + "/"
5402                            + cpi.applicationInfo.uid + " for provider "
5403                            + name + ": launching app became null");
5404                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
5405                            cpi.applicationInfo.packageName,
5406                            cpi.applicationInfo.uid, name);
5407                    return null;
5408                }
5409                try {
5410                    cpr.wait();
5411                } catch (InterruptedException ex) {
5412                }
5413            }
5414        }
5415        return cpr;
5416    }
5417
5418    public final ContentProviderHolder getContentProvider(
5419            IApplicationThread caller, String name) {
5420        if (caller == null) {
5421            String msg = "null IApplicationThread when getting content provider "
5422                    + name;
5423            Slog.w(TAG, msg);
5424            throw new SecurityException(msg);
5425        }
5426
5427        return getContentProviderImpl(caller, name);
5428    }
5429
5430    private ContentProviderHolder getContentProviderExternal(String name) {
5431        return getContentProviderImpl(null, name);
5432    }
5433
5434    /**
5435     * Drop a content provider from a ProcessRecord's bookkeeping
5436     * @param cpr
5437     */
5438    public void removeContentProvider(IApplicationThread caller, String name) {
5439        synchronized (this) {
5440            ContentProviderRecord cpr = mProvidersByName.get(name);
5441            if(cpr == null) {
5442                // remove from mProvidersByClass
5443                if (DEBUG_PROVIDER) Slog.v(TAG, name +
5444                        " provider not found in providers list");
5445                return;
5446            }
5447            final ProcessRecord r = getRecordForAppLocked(caller);
5448            if (r == null) {
5449                throw new SecurityException(
5450                        "Unable to find app for caller " + caller +
5451                        " when removing content provider " + name);
5452            }
5453            //update content provider record entry info
5454            ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
5455            if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
5456                    + r.info.processName + " from process "
5457                    + localCpr.appInfo.processName);
5458            if (localCpr.app == r) {
5459                //should not happen. taken care of as a local provider
5460                Slog.w(TAG, "removeContentProvider called on local provider: "
5461                        + cpr.info.name + " in process " + r.processName);
5462                return;
5463            } else {
5464                Integer cnt = r.conProviders.get(localCpr);
5465                if (cnt == null || cnt.intValue() <= 1) {
5466                    localCpr.clients.remove(r);
5467                    r.conProviders.remove(localCpr);
5468                } else {
5469                    r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5470                }
5471            }
5472            updateOomAdjLocked();
5473        }
5474    }
5475
5476    private void removeContentProviderExternal(String name) {
5477        synchronized (this) {
5478            ContentProviderRecord cpr = mProvidersByName.get(name);
5479            if(cpr == null) {
5480                //remove from mProvidersByClass
5481                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
5482                return;
5483            }
5484
5485            //update content provider record entry info
5486            ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
5487            localCpr.externals--;
5488            if (localCpr.externals < 0) {
5489                Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
5490            }
5491            updateOomAdjLocked();
5492        }
5493    }
5494
5495    public final void publishContentProviders(IApplicationThread caller,
5496            List<ContentProviderHolder> providers) {
5497        if (providers == null) {
5498            return;
5499        }
5500
5501        synchronized(this) {
5502            final ProcessRecord r = getRecordForAppLocked(caller);
5503            if (r == null) {
5504                throw new SecurityException(
5505                        "Unable to find app for caller " + caller
5506                      + " (pid=" + Binder.getCallingPid()
5507                      + ") when publishing content providers");
5508            }
5509
5510            final long origId = Binder.clearCallingIdentity();
5511
5512            final int N = providers.size();
5513            for (int i=0; i<N; i++) {
5514                ContentProviderHolder src = providers.get(i);
5515                if (src == null || src.info == null || src.provider == null) {
5516                    continue;
5517                }
5518                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
5519                if (dst != null) {
5520                    mProvidersByClass.put(dst.info.name, dst);
5521                    String names[] = dst.info.authority.split(";");
5522                    for (int j = 0; j < names.length; j++) {
5523                        mProvidersByName.put(names[j], dst);
5524                    }
5525
5526                    int NL = mLaunchingProviders.size();
5527                    int j;
5528                    for (j=0; j<NL; j++) {
5529                        if (mLaunchingProviders.get(j) == dst) {
5530                            mLaunchingProviders.remove(j);
5531                            j--;
5532                            NL--;
5533                        }
5534                    }
5535                    synchronized (dst) {
5536                        dst.provider = src.provider;
5537                        dst.app = r;
5538                        dst.notifyAll();
5539                    }
5540                    updateOomAdjLocked(r);
5541                }
5542            }
5543
5544            Binder.restoreCallingIdentity(origId);
5545        }
5546    }
5547
5548    public static final void installSystemProviders() {
5549        List providers;
5550        synchronized (mSelf) {
5551            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5552            providers = mSelf.generateApplicationProvidersLocked(app);
5553            if (providers != null) {
5554                for (int i=providers.size()-1; i>=0; i--) {
5555                    ProviderInfo pi = (ProviderInfo)providers.get(i);
5556                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5557                        Slog.w(TAG, "Not installing system proc provider " + pi.name
5558                                + ": not system .apk");
5559                        providers.remove(i);
5560                    }
5561                }
5562            }
5563        }
5564        if (providers != null) {
5565            mSystemThread.installSystemProviders(providers);
5566        }
5567    }
5568
5569    /**
5570     * Allows app to retrieve the MIME type of a URI without having permission
5571     * to access its content provider.
5572     *
5573     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5574     *
5575     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5576     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5577     */
5578    public String getProviderMimeType(Uri uri) {
5579        final String name = uri.getAuthority();
5580        final long ident = Binder.clearCallingIdentity();
5581        ContentProviderHolder holder = null;
5582
5583        try {
5584            holder = getContentProviderExternal(name);
5585            if (holder != null) {
5586                return holder.provider.getType(uri);
5587            }
5588        } catch (RemoteException e) {
5589            Log.w(TAG, "Content provider dead retrieving " + uri, e);
5590            return null;
5591        } finally {
5592            if (holder != null) {
5593                removeContentProviderExternal(name);
5594            }
5595            Binder.restoreCallingIdentity(ident);
5596        }
5597
5598        return null;
5599    }
5600
5601    // =========================================================
5602    // GLOBAL MANAGEMENT
5603    // =========================================================
5604
5605    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5606            ApplicationInfo info, String customProcess) {
5607        String proc = customProcess != null ? customProcess : info.processName;
5608        BatteryStatsImpl.Uid.Proc ps = null;
5609        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5610        synchronized (stats) {
5611            ps = stats.getProcessStatsLocked(info.uid, proc);
5612        }
5613        return new ProcessRecord(ps, thread, info, proc);
5614    }
5615
5616    final ProcessRecord addAppLocked(ApplicationInfo info) {
5617        ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
5618
5619        if (app == null) {
5620            app = newProcessRecordLocked(null, info, null);
5621            mProcessNames.put(info.processName, info.uid, app);
5622            updateLruProcessLocked(app, true, true);
5623        }
5624
5625        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
5626                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
5627            app.persistent = true;
5628            app.maxAdj = CORE_SERVER_ADJ;
5629        }
5630        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
5631            mPersistentStartingProcesses.add(app);
5632            startProcessLocked(app, "added application", app.processName);
5633        }
5634
5635        return app;
5636    }
5637
5638    public void unhandledBack() {
5639        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
5640                "unhandledBack()");
5641
5642        synchronized(this) {
5643            int count = mMainStack.mHistory.size();
5644            if (DEBUG_SWITCH) Slog.d(
5645                TAG, "Performing unhandledBack(): stack size = " + count);
5646            if (count > 1) {
5647                final long origId = Binder.clearCallingIdentity();
5648                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
5649                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
5650                Binder.restoreCallingIdentity(origId);
5651            }
5652        }
5653    }
5654
5655    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
5656        String name = uri.getAuthority();
5657        ContentProviderHolder cph = getContentProviderExternal(name);
5658        ParcelFileDescriptor pfd = null;
5659        if (cph != null) {
5660            // We record the binder invoker's uid in thread-local storage before
5661            // going to the content provider to open the file.  Later, in the code
5662            // that handles all permissions checks, we look for this uid and use
5663            // that rather than the Activity Manager's own uid.  The effect is that
5664            // we do the check against the caller's permissions even though it looks
5665            // to the content provider like the Activity Manager itself is making
5666            // the request.
5667            sCallerIdentity.set(new Identity(
5668                    Binder.getCallingPid(), Binder.getCallingUid()));
5669            try {
5670                pfd = cph.provider.openFile(uri, "r");
5671            } catch (FileNotFoundException e) {
5672                // do nothing; pfd will be returned null
5673            } finally {
5674                // Ensure that whatever happens, we clean up the identity state
5675                sCallerIdentity.remove();
5676            }
5677
5678            // We've got the fd now, so we're done with the provider.
5679            removeContentProviderExternal(name);
5680        } else {
5681            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
5682        }
5683        return pfd;
5684    }
5685
5686    public void goingToSleep() {
5687        synchronized(this) {
5688            mSleeping = true;
5689            mWindowManager.setEventDispatching(false);
5690
5691            if (mMainStack.mResumedActivity != null) {
5692                mMainStack.pauseIfSleepingLocked();
5693            } else {
5694                Slog.w(TAG, "goingToSleep with no resumed activity!");
5695            }
5696
5697            // Initialize the wake times of all processes.
5698            checkExcessivePowerUsageLocked(false);
5699            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5700            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5701            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5702        }
5703    }
5704
5705    public boolean shutdown(int timeout) {
5706        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
5707                != PackageManager.PERMISSION_GRANTED) {
5708            throw new SecurityException("Requires permission "
5709                    + android.Manifest.permission.SHUTDOWN);
5710        }
5711
5712        boolean timedout = false;
5713
5714        synchronized(this) {
5715            mShuttingDown = true;
5716            mWindowManager.setEventDispatching(false);
5717
5718            if (mMainStack.mResumedActivity != null) {
5719                mMainStack.pauseIfSleepingLocked();
5720                final long endTime = System.currentTimeMillis() + timeout;
5721                while (mMainStack.mResumedActivity != null
5722                        || mMainStack.mPausingActivity != null) {
5723                    long delay = endTime - System.currentTimeMillis();
5724                    if (delay <= 0) {
5725                        Slog.w(TAG, "Activity manager shutdown timed out");
5726                        timedout = true;
5727                        break;
5728                    }
5729                    try {
5730                        this.wait();
5731                    } catch (InterruptedException e) {
5732                    }
5733                }
5734            }
5735        }
5736
5737        mUsageStatsService.shutdown();
5738        mBatteryStatsService.shutdown();
5739
5740        return timedout;
5741    }
5742
5743    public void wakingUp() {
5744        synchronized(this) {
5745            if (mMainStack.mGoingToSleep.isHeld()) {
5746                mMainStack.mGoingToSleep.release();
5747            }
5748            mWindowManager.setEventDispatching(true);
5749            mSleeping = false;
5750            mMainStack.resumeTopActivityLocked(null);
5751        }
5752    }
5753
5754    public void stopAppSwitches() {
5755        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
5756                != PackageManager.PERMISSION_GRANTED) {
5757            throw new SecurityException("Requires permission "
5758                    + android.Manifest.permission.STOP_APP_SWITCHES);
5759        }
5760
5761        synchronized(this) {
5762            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
5763                    + APP_SWITCH_DELAY_TIME;
5764            mDidAppSwitch = false;
5765            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
5766            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
5767            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
5768        }
5769    }
5770
5771    public void resumeAppSwitches() {
5772        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
5773                != PackageManager.PERMISSION_GRANTED) {
5774            throw new SecurityException("Requires permission "
5775                    + android.Manifest.permission.STOP_APP_SWITCHES);
5776        }
5777
5778        synchronized(this) {
5779            // Note that we don't execute any pending app switches... we will
5780            // let those wait until either the timeout, or the next start
5781            // activity request.
5782            mAppSwitchesAllowedTime = 0;
5783        }
5784    }
5785
5786    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
5787            String name) {
5788        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
5789            return true;
5790        }
5791
5792        final int perm = checkComponentPermission(
5793                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
5794                callingUid, -1);
5795        if (perm == PackageManager.PERMISSION_GRANTED) {
5796            return true;
5797        }
5798
5799        Slog.w(TAG, name + " request from " + callingUid + " stopped");
5800        return false;
5801    }
5802
5803    public void setDebugApp(String packageName, boolean waitForDebugger,
5804            boolean persistent) {
5805        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
5806                "setDebugApp()");
5807
5808        // Note that this is not really thread safe if there are multiple
5809        // callers into it at the same time, but that's not a situation we
5810        // care about.
5811        if (persistent) {
5812            final ContentResolver resolver = mContext.getContentResolver();
5813            Settings.System.putString(
5814                resolver, Settings.System.DEBUG_APP,
5815                packageName);
5816            Settings.System.putInt(
5817                resolver, Settings.System.WAIT_FOR_DEBUGGER,
5818                waitForDebugger ? 1 : 0);
5819        }
5820
5821        synchronized (this) {
5822            if (!persistent) {
5823                mOrigDebugApp = mDebugApp;
5824                mOrigWaitForDebugger = mWaitForDebugger;
5825            }
5826            mDebugApp = packageName;
5827            mWaitForDebugger = waitForDebugger;
5828            mDebugTransient = !persistent;
5829            if (packageName != null) {
5830                final long origId = Binder.clearCallingIdentity();
5831                forceStopPackageLocked(packageName, -1, false, false, true);
5832                Binder.restoreCallingIdentity(origId);
5833            }
5834        }
5835    }
5836
5837    public void setAlwaysFinish(boolean enabled) {
5838        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
5839                "setAlwaysFinish()");
5840
5841        Settings.System.putInt(
5842                mContext.getContentResolver(),
5843                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
5844
5845        synchronized (this) {
5846            mAlwaysFinishActivities = enabled;
5847        }
5848    }
5849
5850    public void setActivityController(IActivityController controller) {
5851        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
5852                "setActivityController()");
5853        synchronized (this) {
5854            mController = controller;
5855        }
5856    }
5857
5858    public boolean isUserAMonkey() {
5859        // For now the fact that there is a controller implies
5860        // we have a monkey.
5861        synchronized (this) {
5862            return mController != null;
5863        }
5864    }
5865
5866    public void registerActivityWatcher(IActivityWatcher watcher) {
5867        synchronized (this) {
5868            mWatchers.register(watcher);
5869        }
5870    }
5871
5872    public void unregisterActivityWatcher(IActivityWatcher watcher) {
5873        synchronized (this) {
5874            mWatchers.unregister(watcher);
5875        }
5876    }
5877
5878    public final void enterSafeMode() {
5879        synchronized(this) {
5880            // It only makes sense to do this before the system is ready
5881            // and started launching other packages.
5882            if (!mSystemReady) {
5883                try {
5884                    AppGlobals.getPackageManager().enterSafeMode();
5885                } catch (RemoteException e) {
5886                }
5887
5888                View v = LayoutInflater.from(mContext).inflate(
5889                        com.android.internal.R.layout.safe_mode, null);
5890                WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
5891                lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
5892                lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
5893                lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
5894                lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
5895                lp.format = v.getBackground().getOpacity();
5896                lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
5897                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
5898                ((WindowManager)mContext.getSystemService(
5899                        Context.WINDOW_SERVICE)).addView(v, lp);
5900            }
5901        }
5902    }
5903
5904    public void noteWakeupAlarm(IIntentSender sender) {
5905        if (!(sender instanceof PendingIntentRecord)) {
5906            return;
5907        }
5908        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5909        synchronized (stats) {
5910            if (mBatteryStatsService.isOnBattery()) {
5911                mBatteryStatsService.enforceCallingPermission();
5912                PendingIntentRecord rec = (PendingIntentRecord)sender;
5913                int MY_UID = Binder.getCallingUid();
5914                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
5915                BatteryStatsImpl.Uid.Pkg pkg =
5916                    stats.getPackageStatsLocked(uid, rec.key.packageName);
5917                pkg.incWakeupsLocked();
5918            }
5919        }
5920    }
5921
5922    public boolean killPids(int[] pids, String pReason) {
5923        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
5924            throw new SecurityException("killPids only available to the system");
5925        }
5926        String reason = (pReason == null) ? "Unknown" : pReason;
5927        // XXX Note: don't acquire main activity lock here, because the window
5928        // manager calls in with its locks held.
5929
5930        boolean killed = false;
5931        synchronized (mPidsSelfLocked) {
5932            int[] types = new int[pids.length];
5933            int worstType = 0;
5934            for (int i=0; i<pids.length; i++) {
5935                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
5936                if (proc != null) {
5937                    int type = proc.setAdj;
5938                    types[i] = type;
5939                    if (type > worstType) {
5940                        worstType = type;
5941                    }
5942                }
5943            }
5944
5945            // If the worse oom_adj is somewhere in the hidden proc LRU range,
5946            // then constrain it so we will kill all hidden procs.
5947            if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
5948                worstType = HIDDEN_APP_MIN_ADJ;
5949            }
5950            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
5951            for (int i=0; i<pids.length; i++) {
5952                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
5953                if (proc == null) {
5954                    continue;
5955                }
5956                int adj = proc.setAdj;
5957                if (adj >= worstType && !proc.killedBackground) {
5958                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
5959                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
5960                            proc.processName, adj, reason);
5961                    killed = true;
5962                    proc.killedBackground = true;
5963                    Process.killProcessQuiet(pids[i]);
5964                }
5965            }
5966        }
5967        return killed;
5968    }
5969
5970    public final void startRunning(String pkg, String cls, String action,
5971            String data) {
5972        synchronized(this) {
5973            if (mStartRunning) {
5974                return;
5975            }
5976            mStartRunning = true;
5977            mTopComponent = pkg != null && cls != null
5978                    ? new ComponentName(pkg, cls) : null;
5979            mTopAction = action != null ? action : Intent.ACTION_MAIN;
5980            mTopData = data;
5981            if (!mSystemReady) {
5982                return;
5983            }
5984        }
5985
5986        systemReady(null);
5987    }
5988
5989    private void retrieveSettings() {
5990        final ContentResolver resolver = mContext.getContentResolver();
5991        String debugApp = Settings.System.getString(
5992            resolver, Settings.System.DEBUG_APP);
5993        boolean waitForDebugger = Settings.System.getInt(
5994            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
5995        boolean alwaysFinishActivities = Settings.System.getInt(
5996            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
5997
5998        Configuration configuration = new Configuration();
5999        Settings.System.getConfiguration(resolver, configuration);
6000
6001        synchronized (this) {
6002            mDebugApp = mOrigDebugApp = debugApp;
6003            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6004            mAlwaysFinishActivities = alwaysFinishActivities;
6005            // This happens before any activities are started, so we can
6006            // change mConfiguration in-place.
6007            mConfiguration.updateFrom(configuration);
6008            mConfigurationSeq = mConfiguration.seq = 1;
6009            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
6010        }
6011    }
6012
6013    public boolean testIsSystemReady() {
6014        // no need to synchronize(this) just to read & return the value
6015        return mSystemReady;
6016    }
6017
6018    private static File getCalledPreBootReceiversFile() {
6019        File dataDir = Environment.getDataDirectory();
6020        File systemDir = new File(dataDir, "system");
6021        File fname = new File(systemDir, "called_pre_boots.dat");
6022        return fname;
6023    }
6024
6025    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6026        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6027        File file = getCalledPreBootReceiversFile();
6028        FileInputStream fis = null;
6029        try {
6030            fis = new FileInputStream(file);
6031            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6032            int vers = dis.readInt();
6033            String codename = dis.readUTF();
6034            if (vers == android.os.Build.VERSION.SDK_INT
6035                    && codename.equals(android.os.Build.VERSION.CODENAME)) {
6036                int num = dis.readInt();
6037                while (num > 0) {
6038                    num--;
6039                    String pkg = dis.readUTF();
6040                    String cls = dis.readUTF();
6041                    lastDoneReceivers.add(new ComponentName(pkg, cls));
6042                }
6043            }
6044        } catch (FileNotFoundException e) {
6045        } catch (IOException e) {
6046            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6047        } finally {
6048            if (fis != null) {
6049                try {
6050                    fis.close();
6051                } catch (IOException e) {
6052                }
6053            }
6054        }
6055        return lastDoneReceivers;
6056    }
6057
6058    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6059        File file = getCalledPreBootReceiversFile();
6060        FileOutputStream fos = null;
6061        DataOutputStream dos = null;
6062        try {
6063            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6064            fos = new FileOutputStream(file);
6065            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6066            dos.writeInt(android.os.Build.VERSION.SDK_INT);
6067            dos.writeUTF(android.os.Build.VERSION.CODENAME);
6068            dos.writeInt(list.size());
6069            for (int i=0; i<list.size(); i++) {
6070                dos.writeUTF(list.get(i).getPackageName());
6071                dos.writeUTF(list.get(i).getClassName());
6072            }
6073        } catch (IOException e) {
6074            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6075            file.delete();
6076        } finally {
6077            FileUtils.sync(fos);
6078            if (dos != null) {
6079                try {
6080                    dos.close();
6081                } catch (IOException e) {
6082                    // TODO Auto-generated catch block
6083                    e.printStackTrace();
6084                }
6085            }
6086        }
6087    }
6088
6089    public void systemReady(final Runnable goingCallback) {
6090        // In the simulator, startRunning will never have been called, which
6091        // normally sets a few crucial variables. Do it here instead.
6092        if (!Process.supportsProcesses()) {
6093            mStartRunning = true;
6094            mTopAction = Intent.ACTION_MAIN;
6095        }
6096
6097        synchronized(this) {
6098            if (mSystemReady) {
6099                if (goingCallback != null) goingCallback.run();
6100                return;
6101            }
6102
6103            // Check to see if there are any update receivers to run.
6104            if (!mDidUpdate) {
6105                if (mWaitingUpdate) {
6106                    return;
6107                }
6108                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6109                List<ResolveInfo> ris = null;
6110                try {
6111                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
6112                                intent, null, 0);
6113                } catch (RemoteException e) {
6114                }
6115                if (ris != null) {
6116                    for (int i=ris.size()-1; i>=0; i--) {
6117                        if ((ris.get(i).activityInfo.applicationInfo.flags
6118                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
6119                            ris.remove(i);
6120                        }
6121                    }
6122                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
6123
6124                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6125
6126                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
6127                    for (int i=0; i<ris.size(); i++) {
6128                        ActivityInfo ai = ris.get(i).activityInfo;
6129                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
6130                        if (lastDoneReceivers.contains(comp)) {
6131                            ris.remove(i);
6132                            i--;
6133                        }
6134                    }
6135
6136                    for (int i=0; i<ris.size(); i++) {
6137                        ActivityInfo ai = ris.get(i).activityInfo;
6138                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
6139                        doneReceivers.add(comp);
6140                        intent.setComponent(comp);
6141                        IIntentReceiver finisher = null;
6142                        if (i == ris.size()-1) {
6143                            finisher = new IIntentReceiver.Stub() {
6144                                public void performReceive(Intent intent, int resultCode,
6145                                        String data, Bundle extras, boolean ordered,
6146                                        boolean sticky) {
6147                                    // The raw IIntentReceiver interface is called
6148                                    // with the AM lock held, so redispatch to
6149                                    // execute our code without the lock.
6150                                    mHandler.post(new Runnable() {
6151                                        public void run() {
6152                                            synchronized (ActivityManagerService.this) {
6153                                                mDidUpdate = true;
6154                                            }
6155                                            writeLastDonePreBootReceivers(doneReceivers);
6156                                            systemReady(goingCallback);
6157                                        }
6158                                    });
6159                                }
6160                            };
6161                        }
6162                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
6163                        broadcastIntentLocked(null, null, intent, null, finisher,
6164                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
6165                        if (finisher != null) {
6166                            mWaitingUpdate = true;
6167                        }
6168                    }
6169                }
6170                if (mWaitingUpdate) {
6171                    return;
6172                }
6173                mDidUpdate = true;
6174            }
6175
6176            mSystemReady = true;
6177            if (!mStartRunning) {
6178                return;
6179            }
6180        }
6181
6182        ArrayList<ProcessRecord> procsToKill = null;
6183        synchronized(mPidsSelfLocked) {
6184            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6185                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6186                if (!isAllowedWhileBooting(proc.info)){
6187                    if (procsToKill == null) {
6188                        procsToKill = new ArrayList<ProcessRecord>();
6189                    }
6190                    procsToKill.add(proc);
6191                }
6192            }
6193        }
6194
6195        synchronized(this) {
6196            if (procsToKill != null) {
6197                for (int i=procsToKill.size()-1; i>=0; i--) {
6198                    ProcessRecord proc = procsToKill.get(i);
6199                    Slog.i(TAG, "Removing system update proc: " + proc);
6200                    removeProcessLocked(proc, true);
6201                }
6202            }
6203
6204            // Now that we have cleaned up any update processes, we
6205            // are ready to start launching real processes and know that
6206            // we won't trample on them any more.
6207            mProcessesReady = true;
6208        }
6209
6210        Slog.i(TAG, "System now ready");
6211        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
6212            SystemClock.uptimeMillis());
6213
6214        synchronized(this) {
6215            // Make sure we have no pre-ready processes sitting around.
6216
6217            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6218                ResolveInfo ri = mContext.getPackageManager()
6219                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
6220                                STOCK_PM_FLAGS);
6221                CharSequence errorMsg = null;
6222                if (ri != null) {
6223                    ActivityInfo ai = ri.activityInfo;
6224                    ApplicationInfo app = ai.applicationInfo;
6225                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6226                        mTopAction = Intent.ACTION_FACTORY_TEST;
6227                        mTopData = null;
6228                        mTopComponent = new ComponentName(app.packageName,
6229                                ai.name);
6230                    } else {
6231                        errorMsg = mContext.getResources().getText(
6232                                com.android.internal.R.string.factorytest_not_system);
6233                    }
6234                } else {
6235                    errorMsg = mContext.getResources().getText(
6236                            com.android.internal.R.string.factorytest_no_action);
6237                }
6238                if (errorMsg != null) {
6239                    mTopAction = null;
6240                    mTopData = null;
6241                    mTopComponent = null;
6242                    Message msg = Message.obtain();
6243                    msg.what = SHOW_FACTORY_ERROR_MSG;
6244                    msg.getData().putCharSequence("msg", errorMsg);
6245                    mHandler.sendMessage(msg);
6246                }
6247            }
6248        }
6249
6250        retrieveSettings();
6251
6252        if (goingCallback != null) goingCallback.run();
6253
6254        synchronized (this) {
6255            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6256                try {
6257                    List apps = AppGlobals.getPackageManager().
6258                        getPersistentApplications(STOCK_PM_FLAGS);
6259                    if (apps != null) {
6260                        int N = apps.size();
6261                        int i;
6262                        for (i=0; i<N; i++) {
6263                            ApplicationInfo info
6264                                = (ApplicationInfo)apps.get(i);
6265                            if (info != null &&
6266                                    !info.packageName.equals("android")) {
6267                                addAppLocked(info);
6268                            }
6269                        }
6270                    }
6271                } catch (RemoteException ex) {
6272                    // pm is in same process, this will never happen.
6273                }
6274            }
6275
6276            // Start up initial activity.
6277            mBooting = true;
6278
6279            try {
6280                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
6281                    Message msg = Message.obtain();
6282                    msg.what = SHOW_UID_ERROR_MSG;
6283                    mHandler.sendMessage(msg);
6284                }
6285            } catch (RemoteException e) {
6286            }
6287
6288            mMainStack.resumeTopActivityLocked(null);
6289        }
6290    }
6291
6292    private boolean makeAppCrashingLocked(ProcessRecord app,
6293            String shortMsg, String longMsg, String stackTrace) {
6294        app.crashing = true;
6295        app.crashingReport = generateProcessError(app,
6296                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
6297        startAppProblemLocked(app);
6298        app.stopFreezingAllLocked();
6299        return handleAppCrashLocked(app);
6300    }
6301
6302    private void makeAppNotRespondingLocked(ProcessRecord app,
6303            String activity, String shortMsg, String longMsg) {
6304        app.notResponding = true;
6305        app.notRespondingReport = generateProcessError(app,
6306                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6307                activity, shortMsg, longMsg, null);
6308        startAppProblemLocked(app);
6309        app.stopFreezingAllLocked();
6310    }
6311
6312    /**
6313     * Generate a process error record, suitable for attachment to a ProcessRecord.
6314     *
6315     * @param app The ProcessRecord in which the error occurred.
6316     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
6317     *                      ActivityManager.AppErrorStateInfo
6318     * @param activity The activity associated with the crash, if known.
6319     * @param shortMsg Short message describing the crash.
6320     * @param longMsg Long message describing the crash.
6321     * @param stackTrace Full crash stack trace, may be null.
6322     *
6323     * @return Returns a fully-formed AppErrorStateInfo record.
6324     */
6325    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
6326            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
6327        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
6328
6329        report.condition = condition;
6330        report.processName = app.processName;
6331        report.pid = app.pid;
6332        report.uid = app.info.uid;
6333        report.tag = activity;
6334        report.shortMsg = shortMsg;
6335        report.longMsg = longMsg;
6336        report.stackTrace = stackTrace;
6337
6338        return report;
6339    }
6340
6341    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
6342        synchronized (this) {
6343            app.crashing = false;
6344            app.crashingReport = null;
6345            app.notResponding = false;
6346            app.notRespondingReport = null;
6347            if (app.anrDialog == fromDialog) {
6348                app.anrDialog = null;
6349            }
6350            if (app.waitDialog == fromDialog) {
6351                app.waitDialog = null;
6352            }
6353            if (app.pid > 0 && app.pid != MY_PID) {
6354                handleAppCrashLocked(app);
6355                Slog.i(ActivityManagerService.TAG, "Killing "
6356                        + app.processName + " (pid=" + app.pid + "): user's request");
6357                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6358                        app.processName, app.setAdj, "user's request after error");
6359                Process.killProcess(app.pid);
6360            }
6361        }
6362    }
6363
6364    private boolean handleAppCrashLocked(ProcessRecord app) {
6365        long now = SystemClock.uptimeMillis();
6366
6367        Long crashTime = mProcessCrashTimes.get(app.info.processName,
6368                app.info.uid);
6369        if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
6370            // This process loses!
6371            Slog.w(TAG, "Process " + app.info.processName
6372                    + " has crashed too many times: killing!");
6373            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
6374                    app.info.processName, app.info.uid);
6375            killServicesLocked(app, false);
6376            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6377                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6378                if (r.app == app) {
6379                    Slog.w(TAG, "  Force finishing activity "
6380                        + r.intent.getComponent().flattenToShortString());
6381                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
6382                }
6383            }
6384            if (!app.persistent) {
6385                // We don't want to start this process again until the user
6386                // explicitly does so...  but for persistent process, we really
6387                // need to keep it running.  If a persistent process is actually
6388                // repeatedly crashing, then badness for everyone.
6389                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
6390                        app.info.processName);
6391                mBadProcesses.put(app.info.processName, app.info.uid, now);
6392                app.bad = true;
6393                mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6394                app.removed = true;
6395                removeProcessLocked(app, false);
6396                return false;
6397            }
6398        } else {
6399            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
6400            if (r.app == app) {
6401                // If the top running activity is from this crashing
6402                // process, then terminate it to avoid getting in a loop.
6403                Slog.w(TAG, "  Force finishing activity "
6404                        + r.intent.getComponent().flattenToShortString());
6405                int index = mMainStack.indexOfTokenLocked(r);
6406                r.stack.finishActivityLocked(r, index,
6407                        Activity.RESULT_CANCELED, null, "crashed");
6408                // Also terminate an activities below it that aren't yet
6409                // stopped, to avoid a situation where one will get
6410                // re-start our crashing activity once it gets resumed again.
6411                index--;
6412                if (index >= 0) {
6413                    r = (ActivityRecord)mMainStack.mHistory.get(index);
6414                    if (r.state == ActivityState.RESUMED
6415                            || r.state == ActivityState.PAUSING
6416                            || r.state == ActivityState.PAUSED) {
6417                        if (!r.isHomeActivity) {
6418                            Slog.w(TAG, "  Force finishing activity "
6419                                    + r.intent.getComponent().flattenToShortString());
6420                            r.stack.finishActivityLocked(r, index,
6421                                    Activity.RESULT_CANCELED, null, "crashed");
6422                        }
6423                    }
6424                }
6425            }
6426        }
6427
6428        // Bump up the crash count of any services currently running in the proc.
6429        if (app.services.size() != 0) {
6430            // Any services running in the application need to be placed
6431            // back in the pending list.
6432            Iterator<ServiceRecord> it = app.services.iterator();
6433            while (it.hasNext()) {
6434                ServiceRecord sr = it.next();
6435                sr.crashCount++;
6436            }
6437        }
6438
6439        mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6440        return true;
6441    }
6442
6443    void startAppProblemLocked(ProcessRecord app) {
6444        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6445                mContext, app.info.packageName, app.info.flags);
6446        skipCurrentReceiverLocked(app);
6447    }
6448
6449    void skipCurrentReceiverLocked(ProcessRecord app) {
6450        boolean reschedule = false;
6451        BroadcastRecord r = app.curReceiver;
6452        if (r != null) {
6453            // The current broadcast is waiting for this app's receiver
6454            // to be finished.  Looks like that's not going to happen, so
6455            // let the broadcast continue.
6456            logBroadcastReceiverDiscardLocked(r);
6457            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6458                    r.resultExtras, r.resultAbort, true);
6459            reschedule = true;
6460        }
6461        r = mPendingBroadcast;
6462        if (r != null && r.curApp == app) {
6463            if (DEBUG_BROADCAST) Slog.v(TAG,
6464                    "skip & discard pending app " + r);
6465            logBroadcastReceiverDiscardLocked(r);
6466            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6467                    r.resultExtras, r.resultAbort, true);
6468            reschedule = true;
6469        }
6470        if (reschedule) {
6471            scheduleBroadcastsLocked();
6472        }
6473    }
6474
6475    /**
6476     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6477     * The application process will exit immediately after this call returns.
6478     * @param app object of the crashing app, null for the system server
6479     * @param crashInfo describing the exception
6480     */
6481    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
6482        ProcessRecord r = findAppProcess(app);
6483
6484        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6485                app == null ? "system" : (r == null ? "unknown" : r.processName),
6486                r == null ? -1 : r.info.flags,
6487                crashInfo.exceptionClassName,
6488                crashInfo.exceptionMessage,
6489                crashInfo.throwFileName,
6490                crashInfo.throwLineNumber);
6491
6492        addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
6493
6494        crashApplication(r, crashInfo);
6495    }
6496
6497    public void handleApplicationStrictModeViolation(
6498            IBinder app,
6499            int violationMask,
6500            StrictMode.ViolationInfo info) {
6501        ProcessRecord r = findAppProcess(app);
6502
6503        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
6504            Integer stackFingerprint = info.crashInfo.stackTrace.hashCode();
6505            boolean logIt = true;
6506            synchronized (mAlreadyLoggedViolatedStacks) {
6507                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
6508                    logIt = false;
6509                    // TODO: sub-sample into EventLog for these, with
6510                    // the info.durationMillis?  Then we'd get
6511                    // the relative pain numbers, without logging all
6512                    // the stack traces repeatedly.  We'd want to do
6513                    // likewise in the client code, which also does
6514                    // dup suppression, before the Binder call.
6515                } else {
6516                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
6517                        mAlreadyLoggedViolatedStacks.clear();
6518                    }
6519                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
6520                }
6521            }
6522            if (logIt) {
6523                logStrictModeViolationToDropBox(r, info);
6524            }
6525        }
6526
6527        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
6528            AppErrorResult result = new AppErrorResult();
6529            synchronized (this) {
6530                final long origId = Binder.clearCallingIdentity();
6531
6532                Message msg = Message.obtain();
6533                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
6534                HashMap<String, Object> data = new HashMap<String, Object>();
6535                data.put("result", result);
6536                data.put("app", r);
6537                data.put("violationMask", violationMask);
6538                data.put("info", info);
6539                msg.obj = data;
6540                mHandler.sendMessage(msg);
6541
6542                Binder.restoreCallingIdentity(origId);
6543            }
6544            int res = result.get();
6545            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
6546        }
6547    }
6548
6549    // Depending on the policy in effect, there could be a bunch of
6550    // these in quick succession so we try to batch these together to
6551    // minimize disk writes, number of dropbox entries, and maximize
6552    // compression, by having more fewer, larger records.
6553    private void logStrictModeViolationToDropBox(
6554            ProcessRecord process,
6555            StrictMode.ViolationInfo info) {
6556        if (info == null) {
6557            return;
6558        }
6559        final boolean isSystemApp = process == null ||
6560                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
6561                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
6562        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
6563        final DropBoxManager dbox = (DropBoxManager)
6564                mContext.getSystemService(Context.DROPBOX_SERVICE);
6565
6566        // Exit early if the dropbox isn't configured to accept this report type.
6567        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
6568
6569        boolean bufferWasEmpty;
6570        boolean needsFlush;
6571        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
6572        synchronized (sb) {
6573            bufferWasEmpty = sb.length() == 0;
6574            appendDropBoxProcessHeaders(process, sb);
6575            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
6576            sb.append("System-App: ").append(isSystemApp).append("\n");
6577            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
6578            if (info.violationNumThisLoop != 0) {
6579                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
6580            }
6581            if (info != null && info.durationMillis != -1) {
6582                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
6583            }
6584            sb.append("\n");
6585            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
6586                sb.append(info.crashInfo.stackTrace);
6587            }
6588            sb.append("\n");
6589
6590            // Only buffer up to ~64k.  Various logging bits truncate
6591            // things at 128k.
6592            needsFlush = (sb.length() > 64 * 1024);
6593        }
6594
6595        // Flush immediately if the buffer's grown too large, or this
6596        // is a non-system app.  Non-system apps are isolated with a
6597        // different tag & policy and not batched.
6598        //
6599        // Batching is useful during internal testing with
6600        // StrictMode settings turned up high.  Without batching,
6601        // thousands of separate files could be created on boot.
6602        if (!isSystemApp || needsFlush) {
6603            new Thread("Error dump: " + dropboxTag) {
6604                @Override
6605                public void run() {
6606                    String report;
6607                    synchronized (sb) {
6608                        report = sb.toString();
6609                        sb.delete(0, sb.length());
6610                        sb.trimToSize();
6611                    }
6612                    if (report.length() != 0) {
6613                        dbox.addText(dropboxTag, report);
6614                    }
6615                }
6616            }.start();
6617            return;
6618        }
6619
6620        // System app batching:
6621        if (!bufferWasEmpty) {
6622            // An existing dropbox-writing thread is outstanding, so
6623            // we don't need to start it up.  The existing thread will
6624            // catch the buffer appends we just did.
6625            return;
6626        }
6627
6628        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
6629        // (After this point, we shouldn't access AMS internal data structures.)
6630        new Thread("Error dump: " + dropboxTag) {
6631            @Override
6632            public void run() {
6633                // 5 second sleep to let stacks arrive and be batched together
6634                try {
6635                    Thread.sleep(5000);  // 5 seconds
6636                } catch (InterruptedException e) {}
6637
6638                String errorReport;
6639                synchronized (mStrictModeBuffer) {
6640                    errorReport = mStrictModeBuffer.toString();
6641                    if (errorReport.length() == 0) {
6642                        return;
6643                    }
6644                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
6645                    mStrictModeBuffer.trimToSize();
6646                }
6647                dbox.addText(dropboxTag, errorReport);
6648            }
6649        }.start();
6650    }
6651
6652    /**
6653     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
6654     * @param app object of the crashing app, null for the system server
6655     * @param tag reported by the caller
6656     * @param crashInfo describing the context of the error
6657     * @return true if the process should exit immediately (WTF is fatal)
6658     */
6659    public boolean handleApplicationWtf(IBinder app, String tag,
6660            ApplicationErrorReport.CrashInfo crashInfo) {
6661        ProcessRecord r = findAppProcess(app);
6662
6663        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
6664                app == null ? "system" : (r == null ? "unknown" : r.processName),
6665                r == null ? -1 : r.info.flags,
6666                tag, crashInfo.exceptionMessage);
6667
6668        addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
6669
6670        if (r != null && r.pid != Process.myPid() &&
6671                Settings.Secure.getInt(mContext.getContentResolver(),
6672                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
6673            crashApplication(r, crashInfo);
6674            return true;
6675        } else {
6676            return false;
6677        }
6678    }
6679
6680    /**
6681     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
6682     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
6683     */
6684    private ProcessRecord findAppProcess(IBinder app) {
6685        if (app == null) {
6686            return null;
6687        }
6688
6689        synchronized (this) {
6690            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
6691                final int NA = apps.size();
6692                for (int ia=0; ia<NA; ia++) {
6693                    ProcessRecord p = apps.valueAt(ia);
6694                    if (p.thread != null && p.thread.asBinder() == app) {
6695                        return p;
6696                    }
6697                }
6698            }
6699
6700            Slog.w(TAG, "Can't find mystery application: " + app);
6701            return null;
6702        }
6703    }
6704
6705    /**
6706     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
6707     * to append various headers to the dropbox log text.
6708     */
6709    private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
6710        // Note: ProcessRecord 'process' is guarded by the service
6711        // instance.  (notably process.pkgList, which could otherwise change
6712        // concurrently during execution of this method)
6713        synchronized (this) {
6714            if (process == null || process.pid == MY_PID) {
6715                sb.append("Process: system_server\n");
6716            } else {
6717                sb.append("Process: ").append(process.processName).append("\n");
6718            }
6719            if (process == null) {
6720                return;
6721            }
6722            int flags = process.info.flags;
6723            IPackageManager pm = AppGlobals.getPackageManager();
6724            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
6725            for (String pkg : process.pkgList) {
6726                sb.append("Package: ").append(pkg);
6727                try {
6728                    PackageInfo pi = pm.getPackageInfo(pkg, 0);
6729                    if (pi != null) {
6730                        sb.append(" v").append(pi.versionCode);
6731                        if (pi.versionName != null) {
6732                            sb.append(" (").append(pi.versionName).append(")");
6733                        }
6734                    }
6735                } catch (RemoteException e) {
6736                    Slog.e(TAG, "Error getting package info: " + pkg, e);
6737                }
6738                sb.append("\n");
6739            }
6740        }
6741    }
6742
6743    private static String processClass(ProcessRecord process) {
6744        if (process == null || process.pid == MY_PID) {
6745            return "system_server";
6746        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
6747            return "system_app";
6748        } else {
6749            return "data_app";
6750        }
6751    }
6752
6753    /**
6754     * Write a description of an error (crash, WTF, ANR) to the drop box.
6755     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
6756     * @param process which caused the error, null means the system server
6757     * @param activity which triggered the error, null if unknown
6758     * @param parent activity related to the error, null if unknown
6759     * @param subject line related to the error, null if absent
6760     * @param report in long form describing the error, null if absent
6761     * @param logFile to include in the report, null if none
6762     * @param crashInfo giving an application stack trace, null if absent
6763     */
6764    public void addErrorToDropBox(String eventType,
6765            ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
6766            final String report, final File logFile,
6767            final ApplicationErrorReport.CrashInfo crashInfo) {
6768        // NOTE -- this must never acquire the ActivityManagerService lock,
6769        // otherwise the watchdog may be prevented from resetting the system.
6770
6771        final String dropboxTag = processClass(process) + "_" + eventType;
6772        final DropBoxManager dbox = (DropBoxManager)
6773                mContext.getSystemService(Context.DROPBOX_SERVICE);
6774
6775        // Exit early if the dropbox isn't configured to accept this report type.
6776        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
6777
6778        final StringBuilder sb = new StringBuilder(1024);
6779        appendDropBoxProcessHeaders(process, sb);
6780        if (activity != null) {
6781            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
6782        }
6783        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
6784            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
6785        }
6786        if (parent != null && parent != activity) {
6787            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
6788        }
6789        if (subject != null) {
6790            sb.append("Subject: ").append(subject).append("\n");
6791        }
6792        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
6793        sb.append("\n");
6794
6795        // Do the rest in a worker thread to avoid blocking the caller on I/O
6796        // (After this point, we shouldn't access AMS internal data structures.)
6797        Thread worker = new Thread("Error dump: " + dropboxTag) {
6798            @Override
6799            public void run() {
6800                if (report != null) {
6801                    sb.append(report);
6802                }
6803                if (logFile != null) {
6804                    try {
6805                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
6806                    } catch (IOException e) {
6807                        Slog.e(TAG, "Error reading " + logFile, e);
6808                    }
6809                }
6810                if (crashInfo != null && crashInfo.stackTrace != null) {
6811                    sb.append(crashInfo.stackTrace);
6812                }
6813
6814                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
6815                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
6816                if (lines > 0) {
6817                    sb.append("\n");
6818
6819                    // Merge several logcat streams, and take the last N lines
6820                    InputStreamReader input = null;
6821                    try {
6822                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
6823                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
6824                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
6825
6826                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
6827                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
6828                        input = new InputStreamReader(logcat.getInputStream());
6829
6830                        int num;
6831                        char[] buf = new char[8192];
6832                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
6833                    } catch (IOException e) {
6834                        Slog.e(TAG, "Error running logcat", e);
6835                    } finally {
6836                        if (input != null) try { input.close(); } catch (IOException e) {}
6837                    }
6838                }
6839
6840                dbox.addText(dropboxTag, sb.toString());
6841            }
6842        };
6843
6844        if (process == null || process.pid == MY_PID) {
6845            worker.run();  // We may be about to die -- need to run this synchronously
6846        } else {
6847            worker.start();
6848        }
6849    }
6850
6851    /**
6852     * Bring up the "unexpected error" dialog box for a crashing app.
6853     * Deal with edge cases (intercepts from instrumented applications,
6854     * ActivityController, error intent receivers, that sort of thing).
6855     * @param r the application crashing
6856     * @param crashInfo describing the failure
6857     */
6858    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
6859        long timeMillis = System.currentTimeMillis();
6860        String shortMsg = crashInfo.exceptionClassName;
6861        String longMsg = crashInfo.exceptionMessage;
6862        String stackTrace = crashInfo.stackTrace;
6863        if (shortMsg != null && longMsg != null) {
6864            longMsg = shortMsg + ": " + longMsg;
6865        } else if (shortMsg != null) {
6866            longMsg = shortMsg;
6867        }
6868
6869        AppErrorResult result = new AppErrorResult();
6870        synchronized (this) {
6871            if (mController != null) {
6872                try {
6873                    String name = r != null ? r.processName : null;
6874                    int pid = r != null ? r.pid : Binder.getCallingPid();
6875                    if (!mController.appCrashed(name, pid,
6876                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
6877                        Slog.w(TAG, "Force-killing crashed app " + name
6878                                + " at watcher's request");
6879                        Process.killProcess(pid);
6880                        return;
6881                    }
6882                } catch (RemoteException e) {
6883                    mController = null;
6884                }
6885            }
6886
6887            final long origId = Binder.clearCallingIdentity();
6888
6889            // If this process is running instrumentation, finish it.
6890            if (r != null && r.instrumentationClass != null) {
6891                Slog.w(TAG, "Error in app " + r.processName
6892                      + " running instrumentation " + r.instrumentationClass + ":");
6893                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
6894                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
6895                Bundle info = new Bundle();
6896                info.putString("shortMsg", shortMsg);
6897                info.putString("longMsg", longMsg);
6898                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
6899                Binder.restoreCallingIdentity(origId);
6900                return;
6901            }
6902
6903            // If we can't identify the process or it's already exceeded its crash quota,
6904            // quit right away without showing a crash dialog.
6905            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
6906                Binder.restoreCallingIdentity(origId);
6907                return;
6908            }
6909
6910            Message msg = Message.obtain();
6911            msg.what = SHOW_ERROR_MSG;
6912            HashMap data = new HashMap();
6913            data.put("result", result);
6914            data.put("app", r);
6915            msg.obj = data;
6916            mHandler.sendMessage(msg);
6917
6918            Binder.restoreCallingIdentity(origId);
6919        }
6920
6921        int res = result.get();
6922
6923        Intent appErrorIntent = null;
6924        synchronized (this) {
6925            if (r != null) {
6926                mProcessCrashTimes.put(r.info.processName, r.info.uid,
6927                        SystemClock.uptimeMillis());
6928            }
6929            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
6930                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
6931            }
6932        }
6933
6934        if (appErrorIntent != null) {
6935            try {
6936                mContext.startActivity(appErrorIntent);
6937            } catch (ActivityNotFoundException e) {
6938                Slog.w(TAG, "bug report receiver dissappeared", e);
6939            }
6940        }
6941    }
6942
6943    Intent createAppErrorIntentLocked(ProcessRecord r,
6944            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
6945        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
6946        if (report == null) {
6947            return null;
6948        }
6949        Intent result = new Intent(Intent.ACTION_APP_ERROR);
6950        result.setComponent(r.errorReportReceiver);
6951        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
6952        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
6953        return result;
6954    }
6955
6956    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
6957            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
6958        if (r.errorReportReceiver == null) {
6959            return null;
6960        }
6961
6962        if (!r.crashing && !r.notResponding) {
6963            return null;
6964        }
6965
6966        ApplicationErrorReport report = new ApplicationErrorReport();
6967        report.packageName = r.info.packageName;
6968        report.installerPackageName = r.errorReportReceiver.getPackageName();
6969        report.processName = r.processName;
6970        report.time = timeMillis;
6971        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
6972
6973        if (r.crashing) {
6974            report.type = ApplicationErrorReport.TYPE_CRASH;
6975            report.crashInfo = crashInfo;
6976        } else if (r.notResponding) {
6977            report.type = ApplicationErrorReport.TYPE_ANR;
6978            report.anrInfo = new ApplicationErrorReport.AnrInfo();
6979
6980            report.anrInfo.activity = r.notRespondingReport.tag;
6981            report.anrInfo.cause = r.notRespondingReport.shortMsg;
6982            report.anrInfo.info = r.notRespondingReport.longMsg;
6983        }
6984
6985        return report;
6986    }
6987
6988    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
6989        // assume our apps are happy - lazy create the list
6990        List<ActivityManager.ProcessErrorStateInfo> errList = null;
6991
6992        synchronized (this) {
6993
6994            // iterate across all processes
6995            for (int i=mLruProcesses.size()-1; i>=0; i--) {
6996                ProcessRecord app = mLruProcesses.get(i);
6997                if ((app.thread != null) && (app.crashing || app.notResponding)) {
6998                    // This one's in trouble, so we'll generate a report for it
6999                    // crashes are higher priority (in case there's a crash *and* an anr)
7000                    ActivityManager.ProcessErrorStateInfo report = null;
7001                    if (app.crashing) {
7002                        report = app.crashingReport;
7003                    } else if (app.notResponding) {
7004                        report = app.notRespondingReport;
7005                    }
7006
7007                    if (report != null) {
7008                        if (errList == null) {
7009                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7010                        }
7011                        errList.add(report);
7012                    } else {
7013                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
7014                                " crashing = " + app.crashing +
7015                                " notResponding = " + app.notResponding);
7016                    }
7017                }
7018            }
7019        }
7020
7021        return errList;
7022    }
7023
7024    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7025        // Lazy instantiation of list
7026        List<ActivityManager.RunningAppProcessInfo> runList = null;
7027        synchronized (this) {
7028            // Iterate across all processes
7029            for (int i=mLruProcesses.size()-1; i>=0; i--) {
7030                ProcessRecord app = mLruProcesses.get(i);
7031                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7032                    // Generate process state info for running application
7033                    ActivityManager.RunningAppProcessInfo currApp =
7034                        new ActivityManager.RunningAppProcessInfo(app.processName,
7035                                app.pid, app.getPackageList());
7036                    currApp.uid = app.info.uid;
7037                    if (mHeavyWeightProcess == app) {
7038                        currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
7039                    }
7040                    if (app.persistent) {
7041                        currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7042                    }
7043                    int adj = app.curAdj;
7044                    if (adj >= EMPTY_APP_ADJ) {
7045                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7046                    } else if (adj >= HIDDEN_APP_MIN_ADJ) {
7047                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7048                        currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
7049                    } else if (adj >= HOME_APP_ADJ) {
7050                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7051                        currApp.lru = 0;
7052                    } else if (adj >= SECONDARY_SERVER_ADJ) {
7053                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7054                    } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
7055                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7056                    } else if (adj >= PERCEPTIBLE_APP_ADJ) {
7057                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7058                    } else if (adj >= VISIBLE_APP_ADJ) {
7059                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7060                    } else {
7061                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7062                    }
7063                    currApp.importanceReasonCode = app.adjTypeCode;
7064                    if (app.adjSource instanceof ProcessRecord) {
7065                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
7066                    } else if (app.adjSource instanceof ActivityRecord) {
7067                        ActivityRecord r = (ActivityRecord)app.adjSource;
7068                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7069                    }
7070                    if (app.adjTarget instanceof ComponentName) {
7071                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7072                    }
7073                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
7074                    //        + " lru=" + currApp.lru);
7075                    if (runList == null) {
7076                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7077                    }
7078                    runList.add(currApp);
7079                }
7080            }
7081        }
7082        return runList;
7083    }
7084
7085    public List<ApplicationInfo> getRunningExternalApplications() {
7086        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7087        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7088        if (runningApps != null && runningApps.size() > 0) {
7089            Set<String> extList = new HashSet<String>();
7090            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7091                if (app.pkgList != null) {
7092                    for (String pkg : app.pkgList) {
7093                        extList.add(pkg);
7094                    }
7095                }
7096            }
7097            IPackageManager pm = AppGlobals.getPackageManager();
7098            for (String pkg : extList) {
7099                try {
7100                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7101                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7102                        retList.add(info);
7103                    }
7104                } catch (RemoteException e) {
7105                }
7106            }
7107        }
7108        return retList;
7109    }
7110
7111    @Override
7112    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
7113        if (checkCallingPermission(android.Manifest.permission.DUMP)
7114                != PackageManager.PERMISSION_GRANTED) {
7115            pw.println("Permission Denial: can't dump ActivityManager from from pid="
7116                    + Binder.getCallingPid()
7117                    + ", uid=" + Binder.getCallingUid()
7118                    + " without permission "
7119                    + android.Manifest.permission.DUMP);
7120            return;
7121        }
7122
7123        boolean dumpAll = false;
7124
7125        int opti = 0;
7126        while (opti < args.length) {
7127            String opt = args[opti];
7128            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7129                break;
7130            }
7131            opti++;
7132            if ("-a".equals(opt)) {
7133                dumpAll = true;
7134            } else if ("-h".equals(opt)) {
7135                pw.println("Activity manager dump options:");
7136                pw.println("  [-a] [-h] [cmd] ...");
7137                pw.println("  cmd may be one of:");
7138                pw.println("    a[ctivities]: activity stack state");
7139                pw.println("    b[roadcasts]: broadcast state");
7140                pw.println("    i[ntents]: pending intent state");
7141                pw.println("    p[rocesses]: process state");
7142                pw.println("    o[om]: out of memory management");
7143                pw.println("    prov[iders]: content provider state");
7144                pw.println("    s[ervices]: service state");
7145                pw.println("    service [name]: service client-side state");
7146                return;
7147            } else {
7148                pw.println("Unknown argument: " + opt + "; use -h for help");
7149            }
7150        }
7151
7152        // Is the caller requesting to dump a particular piece of data?
7153        if (opti < args.length) {
7154            String cmd = args[opti];
7155            opti++;
7156            if ("activities".equals(cmd) || "a".equals(cmd)) {
7157                synchronized (this) {
7158                    dumpActivitiesLocked(fd, pw, args, opti, true, true);
7159                }
7160                return;
7161            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7162                synchronized (this) {
7163                    dumpBroadcastsLocked(fd, pw, args, opti, true);
7164                }
7165                return;
7166            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7167                synchronized (this) {
7168                    dumpPendingIntentsLocked(fd, pw, args, opti, true);
7169                }
7170                return;
7171            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7172                synchronized (this) {
7173                    dumpProcessesLocked(fd, pw, args, opti, true);
7174                }
7175                return;
7176            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7177                synchronized (this) {
7178                    dumpOomLocked(fd, pw, args, opti, true);
7179                }
7180                return;
7181            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7182                synchronized (this) {
7183                    dumpProvidersLocked(fd, pw, args, opti, true);
7184                }
7185                return;
7186            } else if ("service".equals(cmd)) {
7187                dumpService(fd, pw, args, opti, dumpAll);
7188                return;
7189            } else if ("services".equals(cmd) || "s".equals(cmd)) {
7190                synchronized (this) {
7191                    dumpServicesLocked(fd, pw, args, opti, true);
7192                }
7193                return;
7194            }
7195        }
7196
7197        // No piece of data specified, dump everything.
7198        synchronized (this) {
7199            boolean needSep;
7200            if (dumpAll) {
7201                pw.println("Providers in Current Activity Manager State:");
7202            }
7203            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
7204            if (needSep) {
7205                pw.println(" ");
7206            }
7207            if (dumpAll) {
7208                pw.println("-------------------------------------------------------------------------------");
7209                pw.println("Broadcasts in Current Activity Manager State:");
7210            }
7211            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7212            if (needSep) {
7213                pw.println(" ");
7214            }
7215            if (dumpAll) {
7216                pw.println("-------------------------------------------------------------------------------");
7217                pw.println("Services in Current Activity Manager State:");
7218            }
7219            needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll);
7220            if (needSep) {
7221                pw.println(" ");
7222            }
7223            if (dumpAll) {
7224                pw.println("-------------------------------------------------------------------------------");
7225                pw.println("PendingIntents in Current Activity Manager State:");
7226            }
7227            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
7228            if (needSep) {
7229                pw.println(" ");
7230            }
7231            if (dumpAll) {
7232                pw.println("-------------------------------------------------------------------------------");
7233                pw.println("Activities in Current Activity Manager State:");
7234            }
7235            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, !dumpAll);
7236            if (needSep) {
7237                pw.println(" ");
7238            }
7239            if (dumpAll) {
7240                pw.println("-------------------------------------------------------------------------------");
7241                pw.println("Processes in Current Activity Manager State:");
7242            }
7243            dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7244        }
7245    }
7246
7247    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7248            int opti, boolean dumpAll, boolean needHeader) {
7249        if (needHeader) {
7250            pw.println("  Activity stack:");
7251        }
7252        dumpHistoryList(pw, mMainStack.mHistory, "  ", "Hist", true);
7253        pw.println(" ");
7254        pw.println("  Running activities (most recent first):");
7255        dumpHistoryList(pw, mMainStack.mLRUActivities, "  ", "Run", false);
7256        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
7257            pw.println(" ");
7258            pw.println("  Activities waiting for another to become visible:");
7259            dumpHistoryList(pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false);
7260        }
7261        if (mMainStack.mStoppingActivities.size() > 0) {
7262            pw.println(" ");
7263            pw.println("  Activities waiting to stop:");
7264            dumpHistoryList(pw, mMainStack.mStoppingActivities, "  ", "Stop", false);
7265        }
7266        if (mMainStack.mFinishingActivities.size() > 0) {
7267            pw.println(" ");
7268            pw.println("  Activities waiting to finish:");
7269            dumpHistoryList(pw, mMainStack.mFinishingActivities, "  ", "Fin", false);
7270        }
7271
7272        pw.println(" ");
7273        pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
7274        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
7275        pw.println("  mFocusedActivity: " + mFocusedActivity);
7276        pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7277
7278        if (dumpAll && mRecentTasks.size() > 0) {
7279            pw.println(" ");
7280            pw.println("Recent tasks in Current Activity Manager State:");
7281
7282            final int N = mRecentTasks.size();
7283            for (int i=0; i<N; i++) {
7284                TaskRecord tr = mRecentTasks.get(i);
7285                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
7286                        pw.println(tr);
7287                mRecentTasks.get(i).dump(pw, "    ");
7288            }
7289        }
7290
7291        pw.println(" ");
7292        pw.println("  mCurTask: " + mCurTask);
7293
7294        return true;
7295    }
7296
7297    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7298            int opti, boolean dumpAll) {
7299        boolean needSep = false;
7300        int numPers = 0;
7301
7302        if (dumpAll) {
7303            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7304                final int NA = procs.size();
7305                for (int ia=0; ia<NA; ia++) {
7306                    if (!needSep) {
7307                        pw.println("  All known processes:");
7308                        needSep = true;
7309                    }
7310                    ProcessRecord r = procs.valueAt(ia);
7311                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
7312                        pw.print(" UID "); pw.print(procs.keyAt(ia));
7313                        pw.print(" "); pw.println(r);
7314                    r.dump(pw, "    ");
7315                    if (r.persistent) {
7316                        numPers++;
7317                    }
7318                }
7319            }
7320        }
7321
7322        if (mLruProcesses.size() > 0) {
7323            if (needSep) pw.println(" ");
7324            needSep = true;
7325            pw.println("  Running processes (most recent first):");
7326            dumpProcessOomList(pw, this, mLruProcesses, "    ",
7327                    "Proc", "PERS", false);
7328            needSep = true;
7329        }
7330
7331        synchronized (mPidsSelfLocked) {
7332            if (mPidsSelfLocked.size() > 0) {
7333                if (needSep) pw.println(" ");
7334                needSep = true;
7335                pw.println("  PID mappings:");
7336                for (int i=0; i<mPidsSelfLocked.size(); i++) {
7337                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7338                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7339                }
7340            }
7341        }
7342
7343        if (mForegroundProcesses.size() > 0) {
7344            if (needSep) pw.println(" ");
7345            needSep = true;
7346            pw.println("  Foreground Processes:");
7347            for (int i=0; i<mForegroundProcesses.size(); i++) {
7348                pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
7349                        pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
7350            }
7351        }
7352
7353        if (mPersistentStartingProcesses.size() > 0) {
7354            if (needSep) pw.println(" ");
7355            needSep = true;
7356            pw.println("  Persisent processes that are starting:");
7357            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
7358                    "Starting Norm", "Restarting PERS");
7359        }
7360
7361        if (mStartingProcesses.size() > 0) {
7362            if (needSep) pw.println(" ");
7363            needSep = true;
7364            pw.println("  Processes that are starting:");
7365            dumpProcessList(pw, this, mStartingProcesses, "    ",
7366                    "Starting Norm", "Starting PERS");
7367        }
7368
7369        if (mRemovedProcesses.size() > 0) {
7370            if (needSep) pw.println(" ");
7371            needSep = true;
7372            pw.println("  Processes that are being removed:");
7373            dumpProcessList(pw, this, mRemovedProcesses, "    ",
7374                    "Removed Norm", "Removed PERS");
7375        }
7376
7377        if (mProcessesOnHold.size() > 0) {
7378            if (needSep) pw.println(" ");
7379            needSep = true;
7380            pw.println("  Processes that are on old until the system is ready:");
7381            dumpProcessList(pw, this, mProcessesOnHold, "    ",
7382                    "OnHold Norm", "OnHold PERS");
7383        }
7384
7385        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
7386
7387        if (mProcessCrashTimes.getMap().size() > 0) {
7388            if (needSep) pw.println(" ");
7389            needSep = true;
7390            pw.println("  Time since processes crashed:");
7391            long now = SystemClock.uptimeMillis();
7392            for (Map.Entry<String, SparseArray<Long>> procs
7393                    : mProcessCrashTimes.getMap().entrySet()) {
7394                SparseArray<Long> uids = procs.getValue();
7395                final int N = uids.size();
7396                for (int i=0; i<N; i++) {
7397                    pw.print("    Process "); pw.print(procs.getKey());
7398                            pw.print(" uid "); pw.print(uids.keyAt(i));
7399                            pw.print(": last crashed ");
7400                            pw.print((now-uids.valueAt(i)));
7401                            pw.println(" ms ago");
7402                }
7403            }
7404        }
7405
7406        if (mBadProcesses.getMap().size() > 0) {
7407            if (needSep) pw.println(" ");
7408            needSep = true;
7409            pw.println("  Bad processes:");
7410            for (Map.Entry<String, SparseArray<Long>> procs
7411                    : mBadProcesses.getMap().entrySet()) {
7412                SparseArray<Long> uids = procs.getValue();
7413                final int N = uids.size();
7414                for (int i=0; i<N; i++) {
7415                    pw.print("    Bad process "); pw.print(procs.getKey());
7416                            pw.print(" uid "); pw.print(uids.keyAt(i));
7417                            pw.print(": crashed at time ");
7418                            pw.println(uids.valueAt(i));
7419                }
7420            }
7421        }
7422
7423        pw.println(" ");
7424        pw.println("  mHomeProcess: " + mHomeProcess);
7425        if (mHeavyWeightProcess != null) {
7426            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
7427        }
7428        pw.println("  mConfiguration: " + mConfiguration);
7429        pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
7430        pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
7431        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
7432                || mOrigWaitForDebugger) {
7433            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
7434                    + " mDebugTransient=" + mDebugTransient
7435                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
7436        }
7437        if (mAlwaysFinishActivities || mController != null) {
7438            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
7439                    + " mController=" + mController);
7440        }
7441        if (dumpAll) {
7442            pw.println("  Total persistent processes: " + numPers);
7443            pw.println("  mStartRunning=" + mStartRunning
7444                    + " mProcessesReady=" + mProcessesReady
7445                    + " mSystemReady=" + mSystemReady);
7446            pw.println("  mBooting=" + mBooting
7447                    + " mBooted=" + mBooted
7448                    + " mFactoryTest=" + mFactoryTest);
7449            pw.print("  mLastPowerCheckRealtime=");
7450                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
7451                    pw.println("");
7452            pw.print("  mLastPowerCheckUptime=");
7453                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
7454                    pw.println("");
7455            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
7456            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
7457            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
7458        }
7459
7460        return true;
7461    }
7462
7463    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
7464            int opti, boolean needSep, boolean dumpAll) {
7465        if (mProcessesToGc.size() > 0) {
7466            if (needSep) pw.println(" ");
7467            needSep = true;
7468            pw.println("  Processes that are waiting to GC:");
7469            long now = SystemClock.uptimeMillis();
7470            for (int i=0; i<mProcessesToGc.size(); i++) {
7471                ProcessRecord proc = mProcessesToGc.get(i);
7472                pw.print("    Process "); pw.println(proc);
7473                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
7474                        pw.print(", last gced=");
7475                        pw.print(now-proc.lastRequestedGc);
7476                        pw.print(" ms ago, last lowMem=");
7477                        pw.print(now-proc.lastLowMemory);
7478                        pw.println(" ms ago");
7479
7480            }
7481        }
7482        return needSep;
7483    }
7484
7485    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7486            int opti, boolean dumpAll) {
7487        boolean needSep = false;
7488
7489        if (mLruProcesses.size() > 0) {
7490            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
7491
7492            Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
7493                @Override
7494                public int compare(ProcessRecord object1, ProcessRecord object2) {
7495                    if (object1.setAdj != object2.setAdj) {
7496                        return object1.setAdj > object2.setAdj ? -1 : 1;
7497                    }
7498                    if (object1.setSchedGroup != object2.setSchedGroup) {
7499                        return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
7500                    }
7501                    if (object1.keeping != object2.keeping) {
7502                        return object1.keeping ? -1 : 1;
7503                    }
7504                    if (object1.pid != object2.pid) {
7505                        return object1.pid > object2.pid ? -1 : 1;
7506                    }
7507                    return 0;
7508                }
7509            };
7510
7511            Collections.sort(procs, comparator);
7512
7513            if (needSep) pw.println(" ");
7514            needSep = true;
7515            pw.println("  Process OOM control:");
7516            dumpProcessOomList(pw, this, procs, "    ",
7517                    "Proc", "PERS", true);
7518            needSep = true;
7519        }
7520
7521        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
7522
7523        pw.println(" ");
7524        pw.println("  mHomeProcess: " + mHomeProcess);
7525        if (mHeavyWeightProcess != null) {
7526            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
7527        }
7528
7529        return true;
7530    }
7531
7532    /**
7533     * There are three ways to call this:
7534     *  - no service specified: dump all the services
7535     *  - a flattened component name that matched an existing service was specified as the
7536     *    first arg: dump that one service
7537     *  - the first arg isn't the flattened component name of an existing service:
7538     *    dump all services whose component contains the first arg as a substring
7539     */
7540    protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args,
7541            int opti, boolean dumpAll) {
7542        String[] newArgs;
7543        String componentNameString;
7544        ServiceRecord r;
7545        if (opti >= args.length) {
7546            componentNameString = null;
7547            newArgs = EMPTY_STRING_ARRAY;
7548            r = null;
7549        } else {
7550            componentNameString = args[opti];
7551            opti++;
7552            ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
7553            synchronized (this) {
7554                r = componentName != null ? mServices.get(componentName) : null;
7555            }
7556            newArgs = new String[args.length - opti];
7557            if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7558        }
7559
7560        if (r != null) {
7561            dumpService(fd, pw, r, newArgs, dumpAll);
7562        } else {
7563            ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
7564            synchronized (this) {
7565                for (ServiceRecord r1 : mServices.values()) {
7566                    if (componentNameString == null
7567                            || r1.name.flattenToString().contains(componentNameString)) {
7568                        services.add(r1);
7569                    }
7570                }
7571            }
7572            for (int i=0; i<services.size(); i++) {
7573                dumpService(fd, pw, services.get(i), newArgs, dumpAll);
7574            }
7575        }
7576    }
7577
7578    /**
7579     * Invokes IApplicationThread.dumpService() on the thread of the specified service if
7580     * there is a thread associated with the service.
7581     */
7582    private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args,
7583            boolean dumpAll) {
7584        pw.println("  Service " + r.name.flattenToString());
7585        if (dumpAll) {
7586            synchronized (this) {
7587                pw.print("  * "); pw.println(r);
7588                r.dump(pw, "    ");
7589            }
7590            pw.println("");
7591        }
7592        if (r.app != null && r.app.thread != null) {
7593            try {
7594                // flush anything that is already in the PrintWriter since the thread is going
7595                // to write to the file descriptor directly
7596                pw.flush();
7597                r.app.thread.dumpService(fd, r, args);
7598                pw.print("\n");
7599                pw.flush();
7600            } catch (RemoteException e) {
7601                pw.println("got a RemoteException while dumping the service");
7602            }
7603        }
7604    }
7605
7606    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7607            int opti, boolean dumpAll) {
7608        boolean needSep = false;
7609
7610        if (dumpAll) {
7611            if (mRegisteredReceivers.size() > 0) {
7612                pw.println(" ");
7613                pw.println("  Registered Receivers:");
7614                Iterator it = mRegisteredReceivers.values().iterator();
7615                while (it.hasNext()) {
7616                    ReceiverList r = (ReceiverList)it.next();
7617                    pw.print("  * "); pw.println(r);
7618                    r.dump(pw, "    ");
7619                }
7620            }
7621
7622            pw.println(" ");
7623            pw.println("Receiver Resolver Table:");
7624            mReceiverResolver.dump(pw, null, "  ", null, false);
7625            needSep = true;
7626        }
7627
7628        if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
7629                || mPendingBroadcast != null) {
7630            if (mParallelBroadcasts.size() > 0) {
7631                pw.println(" ");
7632                pw.println("  Active broadcasts:");
7633            }
7634            for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
7635                pw.println("  Broadcast #" + i + ":");
7636                mParallelBroadcasts.get(i).dump(pw, "    ");
7637            }
7638            if (mOrderedBroadcasts.size() > 0) {
7639                pw.println(" ");
7640                pw.println("  Active ordered broadcasts:");
7641            }
7642            for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
7643                pw.println("  Serialized Broadcast #" + i + ":");
7644                mOrderedBroadcasts.get(i).dump(pw, "    ");
7645            }
7646            pw.println(" ");
7647            pw.println("  Pending broadcast:");
7648            if (mPendingBroadcast != null) {
7649                mPendingBroadcast.dump(pw, "    ");
7650            } else {
7651                pw.println("    (null)");
7652            }
7653            needSep = true;
7654        }
7655
7656        if (dumpAll) {
7657            pw.println(" ");
7658            pw.println("  Historical broadcasts:");
7659            for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
7660                BroadcastRecord r = mBroadcastHistory[i];
7661                if (r == null) {
7662                    break;
7663                }
7664                pw.println("  Historical Broadcast #" + i + ":");
7665                r.dump(pw, "    ");
7666            }
7667            needSep = true;
7668        }
7669
7670        if (mStickyBroadcasts != null) {
7671            pw.println(" ");
7672            pw.println("  Sticky broadcasts:");
7673            StringBuilder sb = new StringBuilder(128);
7674            for (Map.Entry<String, ArrayList<Intent>> ent
7675                    : mStickyBroadcasts.entrySet()) {
7676                pw.print("  * Sticky action "); pw.print(ent.getKey());
7677                        pw.println(":");
7678                ArrayList<Intent> intents = ent.getValue();
7679                final int N = intents.size();
7680                for (int i=0; i<N; i++) {
7681                    sb.setLength(0);
7682                    sb.append("    Intent: ");
7683                    intents.get(i).toShortString(sb, true, false);
7684                    pw.println(sb.toString());
7685                    Bundle bundle = intents.get(i).getExtras();
7686                    if (bundle != null) {
7687                        pw.print("      ");
7688                        pw.println(bundle.toString());
7689                    }
7690                }
7691            }
7692            needSep = true;
7693        }
7694
7695        if (dumpAll) {
7696            pw.println(" ");
7697            pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
7698            pw.println("  mHandler:");
7699            mHandler.dump(new PrintWriterPrinter(pw), "    ");
7700            needSep = true;
7701        }
7702
7703        return needSep;
7704    }
7705
7706    boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7707            int opti, boolean dumpAll) {
7708        boolean needSep = false;
7709
7710        if (dumpAll) {
7711            if (mServices.size() > 0) {
7712                pw.println("  Active services:");
7713                Iterator<ServiceRecord> it = mServices.values().iterator();
7714                while (it.hasNext()) {
7715                    ServiceRecord r = it.next();
7716                    pw.print("  * "); pw.println(r);
7717                    r.dump(pw, "    ");
7718                }
7719                needSep = true;
7720            }
7721        }
7722
7723        if (mPendingServices.size() > 0) {
7724            if (needSep) pw.println(" ");
7725            pw.println("  Pending services:");
7726            for (int i=0; i<mPendingServices.size(); i++) {
7727                ServiceRecord r = mPendingServices.get(i);
7728                pw.print("  * Pending "); pw.println(r);
7729                r.dump(pw, "    ");
7730            }
7731            needSep = true;
7732        }
7733
7734        if (mRestartingServices.size() > 0) {
7735            if (needSep) pw.println(" ");
7736            pw.println("  Restarting services:");
7737            for (int i=0; i<mRestartingServices.size(); i++) {
7738                ServiceRecord r = mRestartingServices.get(i);
7739                pw.print("  * Restarting "); pw.println(r);
7740                r.dump(pw, "    ");
7741            }
7742            needSep = true;
7743        }
7744
7745        if (mStoppingServices.size() > 0) {
7746            if (needSep) pw.println(" ");
7747            pw.println("  Stopping services:");
7748            for (int i=0; i<mStoppingServices.size(); i++) {
7749                ServiceRecord r = mStoppingServices.get(i);
7750                pw.print("  * Stopping "); pw.println(r);
7751                r.dump(pw, "    ");
7752            }
7753            needSep = true;
7754        }
7755
7756        if (dumpAll) {
7757            if (mServiceConnections.size() > 0) {
7758                if (needSep) pw.println(" ");
7759                pw.println("  Connection bindings to services:");
7760                Iterator<ArrayList<ConnectionRecord>> it
7761                        = mServiceConnections.values().iterator();
7762                while (it.hasNext()) {
7763                    ArrayList<ConnectionRecord> r = it.next();
7764                    for (int i=0; i<r.size(); i++) {
7765                        pw.print("  * "); pw.println(r.get(i));
7766                        r.get(i).dump(pw, "    ");
7767                    }
7768                }
7769                needSep = true;
7770            }
7771        }
7772
7773        return needSep;
7774    }
7775
7776    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7777            int opti, boolean dumpAll) {
7778        boolean needSep = false;
7779
7780        if (dumpAll) {
7781            if (mProvidersByClass.size() > 0) {
7782                if (needSep) pw.println(" ");
7783                pw.println("  Published content providers (by class):");
7784                Iterator<Map.Entry<String, ContentProviderRecord>> it
7785                        = mProvidersByClass.entrySet().iterator();
7786                while (it.hasNext()) {
7787                    Map.Entry<String, ContentProviderRecord> e = it.next();
7788                    ContentProviderRecord r = e.getValue();
7789                    pw.print("  * "); pw.println(r);
7790                    r.dump(pw, "    ");
7791                }
7792                needSep = true;
7793            }
7794
7795            if (mProvidersByName.size() > 0) {
7796                pw.println(" ");
7797                pw.println("  Authority to provider mappings:");
7798                Iterator<Map.Entry<String, ContentProviderRecord>> it
7799                        = mProvidersByName.entrySet().iterator();
7800                while (it.hasNext()) {
7801                    Map.Entry<String, ContentProviderRecord> e = it.next();
7802                    ContentProviderRecord r = e.getValue();
7803                    pw.print("  "); pw.print(e.getKey()); pw.print(": ");
7804                            pw.println(r);
7805                }
7806                needSep = true;
7807            }
7808        }
7809
7810        if (mLaunchingProviders.size() > 0) {
7811            if (needSep) pw.println(" ");
7812            pw.println("  Launching content providers:");
7813            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
7814                pw.print("  Launching #"); pw.print(i); pw.print(": ");
7815                        pw.println(mLaunchingProviders.get(i));
7816            }
7817            needSep = true;
7818        }
7819
7820        if (mGrantedUriPermissions.size() > 0) {
7821            pw.println();
7822            pw.println("Granted Uri Permissions:");
7823            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
7824                int uid = mGrantedUriPermissions.keyAt(i);
7825                HashMap<Uri, UriPermission> perms
7826                        = mGrantedUriPermissions.valueAt(i);
7827                pw.print("  * UID "); pw.print(uid);
7828                        pw.println(" holds:");
7829                for (UriPermission perm : perms.values()) {
7830                    pw.print("    "); pw.println(perm);
7831                    perm.dump(pw, "      ");
7832                }
7833            }
7834            needSep = true;
7835        }
7836
7837        return needSep;
7838    }
7839
7840    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7841            int opti, boolean dumpAll) {
7842        boolean needSep = false;
7843
7844        if (dumpAll) {
7845            if (this.mIntentSenderRecords.size() > 0) {
7846                Iterator<WeakReference<PendingIntentRecord>> it
7847                        = mIntentSenderRecords.values().iterator();
7848                while (it.hasNext()) {
7849                    WeakReference<PendingIntentRecord> ref = it.next();
7850                    PendingIntentRecord rec = ref != null ? ref.get(): null;
7851                    needSep = true;
7852                    if (rec != null) {
7853                        pw.print("  * "); pw.println(rec);
7854                        rec.dump(pw, "    ");
7855                    } else {
7856                        pw.print("  * "); pw.print(ref);
7857                    }
7858                }
7859            }
7860        }
7861
7862        return needSep;
7863    }
7864
7865    private static final void dumpHistoryList(PrintWriter pw, List list,
7866            String prefix, String label, boolean complete) {
7867        TaskRecord lastTask = null;
7868        for (int i=list.size()-1; i>=0; i--) {
7869            ActivityRecord r = (ActivityRecord)list.get(i);
7870            final boolean full = complete || !r.inHistory;
7871            if (lastTask != r.task) {
7872                lastTask = r.task;
7873                pw.print(prefix);
7874                pw.print(full ? "* " : "  ");
7875                pw.println(lastTask);
7876                if (full) {
7877                    lastTask.dump(pw, prefix + "  ");
7878                }
7879            }
7880            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
7881            pw.print(" #"); pw.print(i); pw.print(": ");
7882            pw.println(r);
7883            if (full) {
7884                r.dump(pw, prefix + "      ");
7885            }
7886        }
7887    }
7888
7889    private static String buildOomTag(String prefix, String space, int val, int base) {
7890        if (val == base) {
7891            if (space == null) return prefix;
7892            return prefix + "  ";
7893        }
7894        return prefix + "+" + Integer.toString(val-base);
7895    }
7896
7897    private static final int dumpProcessList(PrintWriter pw,
7898            ActivityManagerService service, List list,
7899            String prefix, String normalLabel, String persistentLabel) {
7900        int numPers = 0;
7901        final int N = list.size()-1;
7902        for (int i=N; i>=0; i--) {
7903            ProcessRecord r = (ProcessRecord)list.get(i);
7904            pw.println(String.format("%s%s #%2d: %s",
7905                    prefix, (r.persistent ? persistentLabel : normalLabel),
7906                    i, r.toString()));
7907            if (r.persistent) {
7908                numPers++;
7909            }
7910        }
7911        return numPers;
7912    }
7913
7914    private static final void dumpProcessOomList(PrintWriter pw,
7915            ActivityManagerService service, List<ProcessRecord> list,
7916            String prefix, String normalLabel, String persistentLabel,
7917            boolean inclDetails) {
7918
7919        final long curRealtime = SystemClock.elapsedRealtime();
7920        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
7921        final long curUptime = SystemClock.uptimeMillis();
7922        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
7923
7924        final int N = list.size()-1;
7925        for (int i=N; i>=0; i--) {
7926            ProcessRecord r = list.get(i);
7927            String oomAdj;
7928            if (r.setAdj >= EMPTY_APP_ADJ) {
7929                oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
7930            } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
7931                oomAdj = buildOomTag("bak", "  ", r.setAdj, HIDDEN_APP_MIN_ADJ);
7932            } else if (r.setAdj >= HOME_APP_ADJ) {
7933                oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
7934            } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
7935                oomAdj = buildOomTag("svc", "  ", r.setAdj, SECONDARY_SERVER_ADJ);
7936            } else if (r.setAdj >= BACKUP_APP_ADJ) {
7937                oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
7938            } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
7939                oomAdj = buildOomTag("hvy  ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
7940            } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
7941                oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
7942            } else if (r.setAdj >= VISIBLE_APP_ADJ) {
7943                oomAdj = buildOomTag("vis  ", null, r.setAdj, VISIBLE_APP_ADJ);
7944            } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
7945                oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
7946            } else if (r.setAdj >= CORE_SERVER_ADJ) {
7947                oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
7948            } else if (r.setAdj >= SYSTEM_ADJ) {
7949                oomAdj = buildOomTag("sys  ", null, r.setAdj, SYSTEM_ADJ);
7950            } else {
7951                oomAdj = Integer.toString(r.setAdj);
7952            }
7953            String schedGroup;
7954            switch (r.setSchedGroup) {
7955                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
7956                    schedGroup = "B";
7957                    break;
7958                case Process.THREAD_GROUP_DEFAULT:
7959                    schedGroup = "F";
7960                    break;
7961                default:
7962                    schedGroup = Integer.toString(r.setSchedGroup);
7963                    break;
7964            }
7965            pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
7966                    prefix, (r.persistent ? persistentLabel : normalLabel),
7967                    N-i, oomAdj, schedGroup, r.toShortString(), r.adjType));
7968            if (r.adjSource != null || r.adjTarget != null) {
7969                pw.print(prefix);
7970                pw.print("          ");
7971                if (r.adjTarget instanceof ComponentName) {
7972                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
7973                } else if (r.adjTarget != null) {
7974                    pw.print(r.adjTarget.toString());
7975                } else {
7976                    pw.print("{null}");
7977                }
7978                pw.print("<=");
7979                if (r.adjSource instanceof ProcessRecord) {
7980                    pw.print("Proc{");
7981                    pw.print(((ProcessRecord)r.adjSource).toShortString());
7982                    pw.println("}");
7983                } else if (r.adjSource != null) {
7984                    pw.println(r.adjSource.toString());
7985                } else {
7986                    pw.println("{null}");
7987                }
7988            }
7989            if (inclDetails) {
7990                pw.print(prefix);
7991                pw.print("    ");
7992                pw.print("oom: max="); pw.print(r.maxAdj);
7993                pw.print(" hidden="); pw.print(r.hiddenAdj);
7994                pw.print(" curRaw="); pw.print(r.curRawAdj);
7995                pw.print(" setRaw="); pw.print(r.setRawAdj);
7996                pw.print(" cur="); pw.print(r.curAdj);
7997                pw.print(" set="); pw.println(r.setAdj);
7998                pw.print(prefix);
7999                pw.print("    ");
8000                pw.print("keeping="); pw.print(r.keeping);
8001                pw.print(" hidden="); pw.print(r.hidden);
8002                pw.print(" empty="); pw.println(r.empty);
8003
8004                if (!r.keeping) {
8005                    if (r.lastWakeTime != 0) {
8006                        long wtime;
8007                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8008                        synchronized (stats) {
8009                            wtime = stats.getProcessWakeTime(r.info.uid,
8010                                    r.pid, curRealtime);
8011                        }
8012                        long timeUsed = wtime - r.lastWakeTime;
8013                        pw.print(prefix);
8014                        pw.print("    ");
8015                        pw.print("keep awake over ");
8016                        TimeUtils.formatDuration(realtimeSince, pw);
8017                        pw.print(" used ");
8018                        TimeUtils.formatDuration(timeUsed, pw);
8019                        pw.print(" (");
8020                        pw.print((timeUsed*100)/realtimeSince);
8021                        pw.println("%)");
8022                    }
8023                    if (r.lastCpuTime != 0) {
8024                        long timeUsed = r.curCpuTime - r.lastCpuTime;
8025                        pw.print(prefix);
8026                        pw.print("    ");
8027                        pw.print("run cpu over ");
8028                        TimeUtils.formatDuration(uptimeSince, pw);
8029                        pw.print(" used ");
8030                        TimeUtils.formatDuration(timeUsed, pw);
8031                        pw.print(" (");
8032                        pw.print((timeUsed*100)/uptimeSince);
8033                        pw.println("%)");
8034                    }
8035                }
8036            }
8037        }
8038    }
8039
8040    static final void dumpApplicationMemoryUsage(FileDescriptor fd,
8041            PrintWriter pw, List list, String prefix, String[] args) {
8042        final boolean isCheckinRequest = scanArgs(args, "--checkin");
8043        long uptime = SystemClock.uptimeMillis();
8044        long realtime = SystemClock.elapsedRealtime();
8045
8046        if (isCheckinRequest) {
8047            // short checkin version
8048            pw.println(uptime + "," + realtime);
8049            pw.flush();
8050        } else {
8051            pw.println("Applications Memory Usage (kB):");
8052            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8053        }
8054        for (int i = list.size() - 1 ; i >= 0 ; i--) {
8055            ProcessRecord r = (ProcessRecord)list.get(i);
8056            if (r.thread != null) {
8057                if (!isCheckinRequest) {
8058                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
8059                    pw.flush();
8060                }
8061                try {
8062                    r.thread.asBinder().dump(fd, args);
8063                } catch (RemoteException e) {
8064                    if (!isCheckinRequest) {
8065                        pw.println("Got RemoteException!");
8066                        pw.flush();
8067                    }
8068                }
8069            }
8070        }
8071    }
8072
8073    /**
8074     * Searches array of arguments for the specified string
8075     * @param args array of argument strings
8076     * @param value value to search for
8077     * @return true if the value is contained in the array
8078     */
8079    private static boolean scanArgs(String[] args, String value) {
8080        if (args != null) {
8081            for (String arg : args) {
8082                if (value.equals(arg)) {
8083                    return true;
8084                }
8085            }
8086        }
8087        return false;
8088    }
8089
8090    private final void killServicesLocked(ProcessRecord app,
8091            boolean allowRestart) {
8092        // Report disconnected services.
8093        if (false) {
8094            // XXX we are letting the client link to the service for
8095            // death notifications.
8096            if (app.services.size() > 0) {
8097                Iterator<ServiceRecord> it = app.services.iterator();
8098                while (it.hasNext()) {
8099                    ServiceRecord r = it.next();
8100                    if (r.connections.size() > 0) {
8101                        Iterator<ArrayList<ConnectionRecord>> jt
8102                                = r.connections.values().iterator();
8103                        while (jt.hasNext()) {
8104                            ArrayList<ConnectionRecord> cl = jt.next();
8105                            for (int i=0; i<cl.size(); i++) {
8106                                ConnectionRecord c = cl.get(i);
8107                                if (c.binding.client != app) {
8108                                    try {
8109                                        //c.conn.connected(r.className, null);
8110                                    } catch (Exception e) {
8111                                        // todo: this should be asynchronous!
8112                                        Slog.w(TAG, "Exception thrown disconnected servce "
8113                                              + r.shortName
8114                                              + " from app " + app.processName, e);
8115                                    }
8116                                }
8117                            }
8118                        }
8119                    }
8120                }
8121            }
8122        }
8123
8124        // Clean up any connections this application has to other services.
8125        if (app.connections.size() > 0) {
8126            Iterator<ConnectionRecord> it = app.connections.iterator();
8127            while (it.hasNext()) {
8128                ConnectionRecord r = it.next();
8129                removeConnectionLocked(r, app, null);
8130            }
8131        }
8132        app.connections.clear();
8133
8134        if (app.services.size() != 0) {
8135            // Any services running in the application need to be placed
8136            // back in the pending list.
8137            Iterator<ServiceRecord> it = app.services.iterator();
8138            while (it.hasNext()) {
8139                ServiceRecord sr = it.next();
8140                synchronized (sr.stats.getBatteryStats()) {
8141                    sr.stats.stopLaunchedLocked();
8142                }
8143                sr.app = null;
8144                sr.executeNesting = 0;
8145                if (mStoppingServices.remove(sr)) {
8146                    if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
8147                }
8148
8149                boolean hasClients = sr.bindings.size() > 0;
8150                if (hasClients) {
8151                    Iterator<IntentBindRecord> bindings
8152                            = sr.bindings.values().iterator();
8153                    while (bindings.hasNext()) {
8154                        IntentBindRecord b = bindings.next();
8155                        if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
8156                                + ": shouldUnbind=" + b.hasBound);
8157                        b.binder = null;
8158                        b.requested = b.received = b.hasBound = false;
8159                    }
8160                }
8161
8162                if (sr.crashCount >= 2) {
8163                    Slog.w(TAG, "Service crashed " + sr.crashCount
8164                            + " times, stopping: " + sr);
8165                    EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
8166                            sr.crashCount, sr.shortName, app.pid);
8167                    bringDownServiceLocked(sr, true);
8168                } else if (!allowRestart) {
8169                    bringDownServiceLocked(sr, true);
8170                } else {
8171                    boolean canceled = scheduleServiceRestartLocked(sr, true);
8172
8173                    // Should the service remain running?  Note that in the
8174                    // extreme case of so many attempts to deliver a command
8175                    // that it failed, that we also will stop it here.
8176                    if (sr.startRequested && (sr.stopIfKilled || canceled)) {
8177                        if (sr.pendingStarts.size() == 0) {
8178                            sr.startRequested = false;
8179                            if (!hasClients) {
8180                                // Whoops, no reason to restart!
8181                                bringDownServiceLocked(sr, true);
8182                            }
8183                        }
8184                    }
8185                }
8186            }
8187
8188            if (!allowRestart) {
8189                app.services.clear();
8190            }
8191        }
8192
8193        // Make sure we have no more records on the stopping list.
8194        int i = mStoppingServices.size();
8195        while (i > 0) {
8196            i--;
8197            ServiceRecord sr = mStoppingServices.get(i);
8198            if (sr.app == app) {
8199                mStoppingServices.remove(i);
8200                if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
8201            }
8202        }
8203
8204        app.executingServices.clear();
8205    }
8206
8207    private final void removeDyingProviderLocked(ProcessRecord proc,
8208            ContentProviderRecord cpr) {
8209        synchronized (cpr) {
8210            cpr.launchingApp = null;
8211            cpr.notifyAll();
8212        }
8213
8214        mProvidersByClass.remove(cpr.info.name);
8215        String names[] = cpr.info.authority.split(";");
8216        for (int j = 0; j < names.length; j++) {
8217            mProvidersByName.remove(names[j]);
8218        }
8219
8220        Iterator<ProcessRecord> cit = cpr.clients.iterator();
8221        while (cit.hasNext()) {
8222            ProcessRecord capp = cit.next();
8223            if (!capp.persistent && capp.thread != null
8224                    && capp.pid != 0
8225                    && capp.pid != MY_PID) {
8226                Slog.i(TAG, "Kill " + capp.processName
8227                        + " (pid " + capp.pid + "): provider " + cpr.info.name
8228                        + " in dying process " + proc.processName);
8229                EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
8230                        capp.processName, capp.setAdj, "dying provider " + proc.processName);
8231                Process.killProcess(capp.pid);
8232            }
8233        }
8234
8235        mLaunchingProviders.remove(cpr);
8236    }
8237
8238    /**
8239     * Main code for cleaning up a process when it has gone away.  This is
8240     * called both as a result of the process dying, or directly when stopping
8241     * a process when running in single process mode.
8242     */
8243    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
8244            boolean restarting, int index) {
8245        if (index >= 0) {
8246            mLruProcesses.remove(index);
8247        }
8248
8249        mProcessesToGc.remove(app);
8250
8251        // Dismiss any open dialogs.
8252        if (app.crashDialog != null) {
8253            app.crashDialog.dismiss();
8254            app.crashDialog = null;
8255        }
8256        if (app.anrDialog != null) {
8257            app.anrDialog.dismiss();
8258            app.anrDialog = null;
8259        }
8260        if (app.waitDialog != null) {
8261            app.waitDialog.dismiss();
8262            app.waitDialog = null;
8263        }
8264
8265        app.crashing = false;
8266        app.notResponding = false;
8267
8268        app.resetPackageList();
8269        app.thread = null;
8270        app.forcingToForeground = null;
8271        app.foregroundServices = false;
8272
8273        killServicesLocked(app, true);
8274
8275        boolean restart = false;
8276
8277        int NL = mLaunchingProviders.size();
8278
8279        // Remove published content providers.
8280        if (!app.pubProviders.isEmpty()) {
8281            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
8282            while (it.hasNext()) {
8283                ContentProviderRecord cpr = it.next();
8284                cpr.provider = null;
8285                cpr.app = null;
8286
8287                // See if someone is waiting for this provider...  in which
8288                // case we don't remove it, but just let it restart.
8289                int i = 0;
8290                if (!app.bad) {
8291                    for (; i<NL; i++) {
8292                        if (mLaunchingProviders.get(i) == cpr) {
8293                            restart = true;
8294                            break;
8295                        }
8296                    }
8297                } else {
8298                    i = NL;
8299                }
8300
8301                if (i >= NL) {
8302                    removeDyingProviderLocked(app, cpr);
8303                    NL = mLaunchingProviders.size();
8304                }
8305            }
8306            app.pubProviders.clear();
8307        }
8308
8309        // Take care of any launching providers waiting for this process.
8310        if (checkAppInLaunchingProvidersLocked(app, false)) {
8311            restart = true;
8312        }
8313
8314        // Unregister from connected content providers.
8315        if (!app.conProviders.isEmpty()) {
8316            Iterator it = app.conProviders.keySet().iterator();
8317            while (it.hasNext()) {
8318                ContentProviderRecord cpr = (ContentProviderRecord)it.next();
8319                cpr.clients.remove(app);
8320            }
8321            app.conProviders.clear();
8322        }
8323
8324        // At this point there may be remaining entries in mLaunchingProviders
8325        // where we were the only one waiting, so they are no longer of use.
8326        // Look for these and clean up if found.
8327        // XXX Commented out for now.  Trying to figure out a way to reproduce
8328        // the actual situation to identify what is actually going on.
8329        if (false) {
8330            for (int i=0; i<NL; i++) {
8331                ContentProviderRecord cpr = (ContentProviderRecord)
8332                        mLaunchingProviders.get(i);
8333                if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
8334                    synchronized (cpr) {
8335                        cpr.launchingApp = null;
8336                        cpr.notifyAll();
8337                    }
8338                }
8339            }
8340        }
8341
8342        skipCurrentReceiverLocked(app);
8343
8344        // Unregister any receivers.
8345        if (app.receivers.size() > 0) {
8346            Iterator<ReceiverList> it = app.receivers.iterator();
8347            while (it.hasNext()) {
8348                removeReceiverLocked(it.next());
8349            }
8350            app.receivers.clear();
8351        }
8352
8353        // If the app is undergoing backup, tell the backup manager about it
8354        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
8355            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
8356            try {
8357                IBackupManager bm = IBackupManager.Stub.asInterface(
8358                        ServiceManager.getService(Context.BACKUP_SERVICE));
8359                bm.agentDisconnected(app.info.packageName);
8360            } catch (RemoteException e) {
8361                // can't happen; backup manager is local
8362            }
8363        }
8364
8365        // If the caller is restarting this app, then leave it in its
8366        // current lists and let the caller take care of it.
8367        if (restarting) {
8368            return;
8369        }
8370
8371        if (!app.persistent) {
8372            if (DEBUG_PROCESSES) Slog.v(TAG,
8373                    "Removing non-persistent process during cleanup: " + app);
8374            mProcessNames.remove(app.processName, app.info.uid);
8375            if (mHeavyWeightProcess == app) {
8376                mHeavyWeightProcess = null;
8377                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
8378            }
8379        } else if (!app.removed) {
8380            // This app is persistent, so we need to keep its record around.
8381            // If it is not already on the pending app list, add it there
8382            // and start a new process for it.
8383            app.thread = null;
8384            app.forcingToForeground = null;
8385            app.foregroundServices = false;
8386            if (mPersistentStartingProcesses.indexOf(app) < 0) {
8387                mPersistentStartingProcesses.add(app);
8388                restart = true;
8389            }
8390        }
8391        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
8392                "Clean-up removing on hold: " + app);
8393        mProcessesOnHold.remove(app);
8394
8395        if (app == mHomeProcess) {
8396            mHomeProcess = null;
8397        }
8398
8399        if (restart) {
8400            // We have components that still need to be running in the
8401            // process, so re-launch it.
8402            mProcessNames.put(app.processName, app.info.uid, app);
8403            startProcessLocked(app, "restart", app.processName);
8404        } else if (app.pid > 0 && app.pid != MY_PID) {
8405            // Goodbye!
8406            synchronized (mPidsSelfLocked) {
8407                mPidsSelfLocked.remove(app.pid);
8408                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
8409            }
8410            app.setPid(0);
8411        }
8412    }
8413
8414    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
8415        // Look through the content providers we are waiting to have launched,
8416        // and if any run in this process then either schedule a restart of
8417        // the process or kill the client waiting for it if this process has
8418        // gone bad.
8419        int NL = mLaunchingProviders.size();
8420        boolean restart = false;
8421        for (int i=0; i<NL; i++) {
8422            ContentProviderRecord cpr = mLaunchingProviders.get(i);
8423            if (cpr.launchingApp == app) {
8424                if (!alwaysBad && !app.bad) {
8425                    restart = true;
8426                } else {
8427                    removeDyingProviderLocked(app, cpr);
8428                    NL = mLaunchingProviders.size();
8429                }
8430            }
8431        }
8432        return restart;
8433    }
8434
8435    // =========================================================
8436    // SERVICES
8437    // =========================================================
8438
8439    ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
8440        ActivityManager.RunningServiceInfo info =
8441            new ActivityManager.RunningServiceInfo();
8442        info.service = r.name;
8443        if (r.app != null) {
8444            info.pid = r.app.pid;
8445        }
8446        info.uid = r.appInfo.uid;
8447        info.process = r.processName;
8448        info.foreground = r.isForeground;
8449        info.activeSince = r.createTime;
8450        info.started = r.startRequested;
8451        info.clientCount = r.connections.size();
8452        info.crashCount = r.crashCount;
8453        info.lastActivityTime = r.lastActivity;
8454        if (r.isForeground) {
8455            info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
8456        }
8457        if (r.startRequested) {
8458            info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
8459        }
8460        if (r.app != null && r.app.pid == MY_PID) {
8461            info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
8462        }
8463        if (r.app != null && r.app.persistent) {
8464            info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
8465        }
8466
8467        for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
8468            for (int i=0; i<connl.size(); i++) {
8469                ConnectionRecord conn = connl.get(i);
8470                if (conn.clientLabel != 0) {
8471                    info.clientPackage = conn.binding.client.info.packageName;
8472                    info.clientLabel = conn.clientLabel;
8473                    return info;
8474                }
8475            }
8476        }
8477        return info;
8478    }
8479
8480    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
8481            int flags) {
8482        synchronized (this) {
8483            ArrayList<ActivityManager.RunningServiceInfo> res
8484                    = new ArrayList<ActivityManager.RunningServiceInfo>();
8485
8486            if (mServices.size() > 0) {
8487                Iterator<ServiceRecord> it = mServices.values().iterator();
8488                while (it.hasNext() && res.size() < maxNum) {
8489                    res.add(makeRunningServiceInfoLocked(it.next()));
8490                }
8491            }
8492
8493            for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
8494                ServiceRecord r = mRestartingServices.get(i);
8495                ActivityManager.RunningServiceInfo info =
8496                        makeRunningServiceInfoLocked(r);
8497                info.restarting = r.nextRestartTime;
8498                res.add(info);
8499            }
8500
8501            return res;
8502        }
8503    }
8504
8505    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
8506        synchronized (this) {
8507            ServiceRecord r = mServices.get(name);
8508            if (r != null) {
8509                for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
8510                    for (int i=0; i<conn.size(); i++) {
8511                        if (conn.get(i).clientIntent != null) {
8512                            return conn.get(i).clientIntent;
8513                        }
8514                    }
8515                }
8516            }
8517        }
8518        return null;
8519    }
8520
8521    private final ServiceRecord findServiceLocked(ComponentName name,
8522            IBinder token) {
8523        ServiceRecord r = mServices.get(name);
8524        return r == token ? r : null;
8525    }
8526
8527    private final class ServiceLookupResult {
8528        final ServiceRecord record;
8529        final String permission;
8530
8531        ServiceLookupResult(ServiceRecord _record, String _permission) {
8532            record = _record;
8533            permission = _permission;
8534        }
8535    };
8536
8537    private ServiceLookupResult findServiceLocked(Intent service,
8538            String resolvedType) {
8539        ServiceRecord r = null;
8540        if (service.getComponent() != null) {
8541            r = mServices.get(service.getComponent());
8542        }
8543        if (r == null) {
8544            Intent.FilterComparison filter = new Intent.FilterComparison(service);
8545            r = mServicesByIntent.get(filter);
8546        }
8547
8548        if (r == null) {
8549            try {
8550                ResolveInfo rInfo =
8551                    AppGlobals.getPackageManager().resolveService(
8552                            service, resolvedType, 0);
8553                ServiceInfo sInfo =
8554                    rInfo != null ? rInfo.serviceInfo : null;
8555                if (sInfo == null) {
8556                    return null;
8557                }
8558
8559                ComponentName name = new ComponentName(
8560                        sInfo.applicationInfo.packageName, sInfo.name);
8561                r = mServices.get(name);
8562            } catch (RemoteException ex) {
8563                // pm is in same process, this will never happen.
8564            }
8565        }
8566        if (r != null) {
8567            int callingPid = Binder.getCallingPid();
8568            int callingUid = Binder.getCallingUid();
8569            if (checkComponentPermission(r.permission,
8570                    callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
8571                    != PackageManager.PERMISSION_GRANTED) {
8572                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
8573                        + " from pid=" + callingPid
8574                        + ", uid=" + callingUid
8575                        + " requires " + r.permission);
8576                return new ServiceLookupResult(null, r.permission);
8577            }
8578            return new ServiceLookupResult(r, null);
8579        }
8580        return null;
8581    }
8582
8583    private class ServiceRestarter implements Runnable {
8584        private ServiceRecord mService;
8585
8586        void setService(ServiceRecord service) {
8587            mService = service;
8588        }
8589
8590        public void run() {
8591            synchronized(ActivityManagerService.this) {
8592                performServiceRestartLocked(mService);
8593            }
8594        }
8595    }
8596
8597    private ServiceLookupResult retrieveServiceLocked(Intent service,
8598            String resolvedType, int callingPid, int callingUid) {
8599        ServiceRecord r = null;
8600        if (service.getComponent() != null) {
8601            r = mServices.get(service.getComponent());
8602        }
8603        Intent.FilterComparison filter = new Intent.FilterComparison(service);
8604        r = mServicesByIntent.get(filter);
8605        if (r == null) {
8606            try {
8607                ResolveInfo rInfo =
8608                    AppGlobals.getPackageManager().resolveService(
8609                            service, resolvedType, STOCK_PM_FLAGS);
8610                ServiceInfo sInfo =
8611                    rInfo != null ? rInfo.serviceInfo : null;
8612                if (sInfo == null) {
8613                    Slog.w(TAG, "Unable to start service " + service +
8614                          ": not found");
8615                    return null;
8616                }
8617
8618                ComponentName name = new ComponentName(
8619                        sInfo.applicationInfo.packageName, sInfo.name);
8620                r = mServices.get(name);
8621                if (r == null) {
8622                    filter = new Intent.FilterComparison(service.cloneFilter());
8623                    ServiceRestarter res = new ServiceRestarter();
8624                    BatteryStatsImpl.Uid.Pkg.Serv ss = null;
8625                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8626                    synchronized (stats) {
8627                        ss = stats.getServiceStatsLocked(
8628                                sInfo.applicationInfo.uid, sInfo.packageName,
8629                                sInfo.name);
8630                    }
8631                    r = new ServiceRecord(this, ss, name, filter, sInfo, res);
8632                    res.setService(r);
8633                    mServices.put(name, r);
8634                    mServicesByIntent.put(filter, r);
8635
8636                    // Make sure this component isn't in the pending list.
8637                    int N = mPendingServices.size();
8638                    for (int i=0; i<N; i++) {
8639                        ServiceRecord pr = mPendingServices.get(i);
8640                        if (pr.name.equals(name)) {
8641                            mPendingServices.remove(i);
8642                            i--;
8643                            N--;
8644                        }
8645                    }
8646                }
8647            } catch (RemoteException ex) {
8648                // pm is in same process, this will never happen.
8649            }
8650        }
8651        if (r != null) {
8652            if (checkComponentPermission(r.permission,
8653                    callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
8654                    != PackageManager.PERMISSION_GRANTED) {
8655                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
8656                        + " from pid=" + Binder.getCallingPid()
8657                        + ", uid=" + Binder.getCallingUid()
8658                        + " requires " + r.permission);
8659                return new ServiceLookupResult(null, r.permission);
8660            }
8661            return new ServiceLookupResult(r, null);
8662        }
8663        return null;
8664    }
8665
8666    private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
8667        if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
8668                + why + " of " + r + " in app " + r.app);
8669        else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
8670                + why + " of " + r.shortName);
8671        long now = SystemClock.uptimeMillis();
8672        if (r.executeNesting == 0 && r.app != null) {
8673            if (r.app.executingServices.size() == 0) {
8674                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
8675                msg.obj = r.app;
8676                mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
8677            }
8678            r.app.executingServices.add(r);
8679        }
8680        r.executeNesting++;
8681        r.executingStart = now;
8682    }
8683
8684    private final void sendServiceArgsLocked(ServiceRecord r,
8685            boolean oomAdjusted) {
8686        final int N = r.pendingStarts.size();
8687        if (N == 0) {
8688            return;
8689        }
8690
8691        while (r.pendingStarts.size() > 0) {
8692            try {
8693                ServiceRecord.StartItem si = r.pendingStarts.remove(0);
8694                if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
8695                        + r + " " + r.intent + " args=" + si.intent);
8696                if (si.intent == null) {
8697                    // If somehow we got a dummy start at the front, then
8698                    // just drop it here.
8699                    continue;
8700                }
8701                si.deliveredTime = SystemClock.uptimeMillis();
8702                r.deliveredStarts.add(si);
8703                si.deliveryCount++;
8704                if (si.targetPermissionUid >= 0) {
8705                    grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
8706                            r.packageName, si.intent, si.getUriPermissionsLocked());
8707                }
8708                bumpServiceExecutingLocked(r, "start");
8709                if (!oomAdjusted) {
8710                    oomAdjusted = true;
8711                    updateOomAdjLocked(r.app);
8712                }
8713                int flags = 0;
8714                if (si.deliveryCount > 0) {
8715                    flags |= Service.START_FLAG_RETRY;
8716                }
8717                if (si.doneExecutingCount > 0) {
8718                    flags |= Service.START_FLAG_REDELIVERY;
8719                }
8720                r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent);
8721            } catch (RemoteException e) {
8722                // Remote process gone...  we'll let the normal cleanup take
8723                // care of this.
8724                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
8725                break;
8726            } catch (Exception e) {
8727                Slog.w(TAG, "Unexpected exception", e);
8728                break;
8729            }
8730        }
8731    }
8732
8733    private final boolean requestServiceBindingLocked(ServiceRecord r,
8734            IntentBindRecord i, boolean rebind) {
8735        if (r.app == null || r.app.thread == null) {
8736            // If service is not currently running, can't yet bind.
8737            return false;
8738        }
8739        if ((!i.requested || rebind) && i.apps.size() > 0) {
8740            try {
8741                bumpServiceExecutingLocked(r, "bind");
8742                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
8743                if (!rebind) {
8744                    i.requested = true;
8745                }
8746                i.hasBound = true;
8747                i.doRebind = false;
8748            } catch (RemoteException e) {
8749                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
8750                return false;
8751            }
8752        }
8753        return true;
8754    }
8755
8756    private final void requestServiceBindingsLocked(ServiceRecord r) {
8757        Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
8758        while (bindings.hasNext()) {
8759            IntentBindRecord i = bindings.next();
8760            if (!requestServiceBindingLocked(r, i, false)) {
8761                break;
8762            }
8763        }
8764    }
8765
8766    private final void realStartServiceLocked(ServiceRecord r,
8767            ProcessRecord app) throws RemoteException {
8768        if (app.thread == null) {
8769            throw new RemoteException();
8770        }
8771
8772        r.app = app;
8773        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
8774
8775        app.services.add(r);
8776        bumpServiceExecutingLocked(r, "create");
8777        updateLruProcessLocked(app, true, true);
8778
8779        boolean created = false;
8780        try {
8781            mStringBuilder.setLength(0);
8782            r.intent.getIntent().toShortString(mStringBuilder, false, true);
8783            EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
8784                    System.identityHashCode(r), r.shortName,
8785                    mStringBuilder.toString(), r.app.pid);
8786            synchronized (r.stats.getBatteryStats()) {
8787                r.stats.startLaunchedLocked();
8788            }
8789            ensurePackageDexOpt(r.serviceInfo.packageName);
8790            app.thread.scheduleCreateService(r, r.serviceInfo);
8791            r.postNotification();
8792            created = true;
8793        } finally {
8794            if (!created) {
8795                app.services.remove(r);
8796                scheduleServiceRestartLocked(r, false);
8797            }
8798        }
8799
8800        requestServiceBindingsLocked(r);
8801
8802        // If the service is in the started state, and there are no
8803        // pending arguments, then fake up one so its onStartCommand() will
8804        // be called.
8805        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
8806            r.lastStartId++;
8807            if (r.lastStartId < 1) {
8808                r.lastStartId = 1;
8809            }
8810            r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId, null, -1));
8811        }
8812
8813        sendServiceArgsLocked(r, true);
8814    }
8815
8816    private final boolean scheduleServiceRestartLocked(ServiceRecord r,
8817            boolean allowCancel) {
8818        boolean canceled = false;
8819
8820        final long now = SystemClock.uptimeMillis();
8821        long minDuration = SERVICE_RESTART_DURATION;
8822        long resetTime = SERVICE_RESET_RUN_DURATION;
8823
8824        // Any delivered but not yet finished starts should be put back
8825        // on the pending list.
8826        final int N = r.deliveredStarts.size();
8827        if (N > 0) {
8828            for (int i=N-1; i>=0; i--) {
8829                ServiceRecord.StartItem si = r.deliveredStarts.get(i);
8830                si.removeUriPermissionsLocked();
8831                if (si.intent == null) {
8832                    // We'll generate this again if needed.
8833                } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
8834                        && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
8835                    r.pendingStarts.add(0, si);
8836                    long dur = SystemClock.uptimeMillis() - si.deliveredTime;
8837                    dur *= 2;
8838                    if (minDuration < dur) minDuration = dur;
8839                    if (resetTime < dur) resetTime = dur;
8840                } else {
8841                    Slog.w(TAG, "Canceling start item " + si.intent + " in service "
8842                            + r.name);
8843                    canceled = true;
8844                }
8845            }
8846            r.deliveredStarts.clear();
8847        }
8848
8849        r.totalRestartCount++;
8850        if (r.restartDelay == 0) {
8851            r.restartCount++;
8852            r.restartDelay = minDuration;
8853        } else {
8854            // If it has been a "reasonably long time" since the service
8855            // was started, then reset our restart duration back to
8856            // the beginning, so we don't infinitely increase the duration
8857            // on a service that just occasionally gets killed (which is
8858            // a normal case, due to process being killed to reclaim memory).
8859            if (now > (r.restartTime+resetTime)) {
8860                r.restartCount = 1;
8861                r.restartDelay = minDuration;
8862            } else {
8863                r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
8864                if (r.restartDelay < minDuration) {
8865                    r.restartDelay = minDuration;
8866                }
8867            }
8868        }
8869
8870        r.nextRestartTime = now + r.restartDelay;
8871
8872        // Make sure that we don't end up restarting a bunch of services
8873        // all at the same time.
8874        boolean repeat;
8875        do {
8876            repeat = false;
8877            for (int i=mRestartingServices.size()-1; i>=0; i--) {
8878                ServiceRecord r2 = mRestartingServices.get(i);
8879                if (r2 != r && r.nextRestartTime
8880                        >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
8881                        && r.nextRestartTime
8882                        < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
8883                    r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
8884                    r.restartDelay = r.nextRestartTime - now;
8885                    repeat = true;
8886                    break;
8887                }
8888            }
8889        } while (repeat);
8890
8891        if (!mRestartingServices.contains(r)) {
8892            mRestartingServices.add(r);
8893        }
8894
8895        r.cancelNotification();
8896
8897        mHandler.removeCallbacks(r.restarter);
8898        mHandler.postAtTime(r.restarter, r.nextRestartTime);
8899        r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
8900        Slog.w(TAG, "Scheduling restart of crashed service "
8901                + r.shortName + " in " + r.restartDelay + "ms");
8902        EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
8903                r.shortName, r.restartDelay);
8904
8905        return canceled;
8906    }
8907
8908    final void performServiceRestartLocked(ServiceRecord r) {
8909        if (!mRestartingServices.contains(r)) {
8910            return;
8911        }
8912        bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
8913    }
8914
8915    private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
8916        if (r.restartDelay == 0) {
8917            return false;
8918        }
8919        r.resetRestartCounter();
8920        mRestartingServices.remove(r);
8921        mHandler.removeCallbacks(r.restarter);
8922        return true;
8923    }
8924
8925    private final boolean bringUpServiceLocked(ServiceRecord r,
8926            int intentFlags, boolean whileRestarting) {
8927        //Slog.i(TAG, "Bring up service:");
8928        //r.dump("  ");
8929
8930        if (r.app != null && r.app.thread != null) {
8931            sendServiceArgsLocked(r, false);
8932            return true;
8933        }
8934
8935        if (!whileRestarting && r.restartDelay > 0) {
8936            // If waiting for a restart, then do nothing.
8937            return true;
8938        }
8939
8940        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
8941
8942        // We are now bringing the service up, so no longer in the
8943        // restarting state.
8944        mRestartingServices.remove(r);
8945
8946        final String appName = r.processName;
8947        ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
8948        if (app != null && app.thread != null) {
8949            try {
8950                realStartServiceLocked(r, app);
8951                return true;
8952            } catch (RemoteException e) {
8953                Slog.w(TAG, "Exception when starting service " + r.shortName, e);
8954            }
8955
8956            // If a dead object exception was thrown -- fall through to
8957            // restart the application.
8958        }
8959
8960        // Not running -- get it started, and enqueue this service record
8961        // to be executed when the app comes up.
8962        if (startProcessLocked(appName, r.appInfo, true, intentFlags,
8963                "service", r.name, false) == null) {
8964            Slog.w(TAG, "Unable to launch app "
8965                    + r.appInfo.packageName + "/"
8966                    + r.appInfo.uid + " for service "
8967                    + r.intent.getIntent() + ": process is bad");
8968            bringDownServiceLocked(r, true);
8969            return false;
8970        }
8971
8972        if (!mPendingServices.contains(r)) {
8973            mPendingServices.add(r);
8974        }
8975
8976        return true;
8977    }
8978
8979    private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
8980        //Slog.i(TAG, "Bring down service:");
8981        //r.dump("  ");
8982
8983        // Does it still need to run?
8984        if (!force && r.startRequested) {
8985            return;
8986        }
8987        if (r.connections.size() > 0) {
8988            if (!force) {
8989                // XXX should probably keep a count of the number of auto-create
8990                // connections directly in the service.
8991                Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
8992                while (it.hasNext()) {
8993                    ArrayList<ConnectionRecord> cr = it.next();
8994                    for (int i=0; i<cr.size(); i++) {
8995                        if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
8996                            return;
8997                        }
8998                    }
8999                }
9000            }
9001
9002            // Report to all of the connections that the service is no longer
9003            // available.
9004            Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
9005            while (it.hasNext()) {
9006                ArrayList<ConnectionRecord> c = it.next();
9007                for (int i=0; i<c.size(); i++) {
9008                    try {
9009                        c.get(i).conn.connected(r.name, null);
9010                    } catch (Exception e) {
9011                        Slog.w(TAG, "Failure disconnecting service " + r.name +
9012                              " to connection " + c.get(i).conn.asBinder() +
9013                              " (in " + c.get(i).binding.client.processName + ")", e);
9014                    }
9015                }
9016            }
9017        }
9018
9019        // Tell the service that it has been unbound.
9020        if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
9021            Iterator<IntentBindRecord> it = r.bindings.values().iterator();
9022            while (it.hasNext()) {
9023                IntentBindRecord ibr = it.next();
9024                if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
9025                        + ": hasBound=" + ibr.hasBound);
9026                if (r.app != null && r.app.thread != null && ibr.hasBound) {
9027                    try {
9028                        bumpServiceExecutingLocked(r, "bring down unbind");
9029                        updateOomAdjLocked(r.app);
9030                        ibr.hasBound = false;
9031                        r.app.thread.scheduleUnbindService(r,
9032                                ibr.intent.getIntent());
9033                    } catch (Exception e) {
9034                        Slog.w(TAG, "Exception when unbinding service "
9035                                + r.shortName, e);
9036                        serviceDoneExecutingLocked(r, true);
9037                    }
9038                }
9039            }
9040        }
9041
9042        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
9043        EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
9044                System.identityHashCode(r), r.shortName,
9045                (r.app != null) ? r.app.pid : -1);
9046
9047        mServices.remove(r.name);
9048        mServicesByIntent.remove(r.intent);
9049        r.totalRestartCount = 0;
9050        unscheduleServiceRestartLocked(r);
9051
9052        // Also make sure it is not on the pending list.
9053        int N = mPendingServices.size();
9054        for (int i=0; i<N; i++) {
9055            if (mPendingServices.get(i) == r) {
9056                mPendingServices.remove(i);
9057                if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
9058                i--;
9059                N--;
9060            }
9061        }
9062
9063        r.cancelNotification();
9064        r.isForeground = false;
9065        r.foregroundId = 0;
9066        r.foregroundNoti = null;
9067
9068        // Clear start entries.
9069        r.clearDeliveredStartsLocked();
9070        r.pendingStarts.clear();
9071
9072        if (r.app != null) {
9073            synchronized (r.stats.getBatteryStats()) {
9074                r.stats.stopLaunchedLocked();
9075            }
9076            r.app.services.remove(r);
9077            if (r.app.thread != null) {
9078                try {
9079                    bumpServiceExecutingLocked(r, "stop");
9080                    mStoppingServices.add(r);
9081                    updateOomAdjLocked(r.app);
9082                    r.app.thread.scheduleStopService(r);
9083                } catch (Exception e) {
9084                    Slog.w(TAG, "Exception when stopping service "
9085                            + r.shortName, e);
9086                    serviceDoneExecutingLocked(r, true);
9087                }
9088                updateServiceForegroundLocked(r.app, false);
9089            } else {
9090                if (DEBUG_SERVICE) Slog.v(
9091                    TAG, "Removed service that has no process: " + r);
9092            }
9093        } else {
9094            if (DEBUG_SERVICE) Slog.v(
9095                TAG, "Removed service that is not running: " + r);
9096        }
9097
9098        if (r.bindings.size() > 0) {
9099            r.bindings.clear();
9100        }
9101
9102        if (r.restarter instanceof ServiceRestarter) {
9103           ((ServiceRestarter)r.restarter).setService(null);
9104        }
9105    }
9106
9107    ComponentName startServiceLocked(IApplicationThread caller,
9108            Intent service, String resolvedType,
9109            int callingPid, int callingUid) {
9110        synchronized(this) {
9111            if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
9112                    + " type=" + resolvedType + " args=" + service.getExtras());
9113
9114            if (caller != null) {
9115                final ProcessRecord callerApp = getRecordForAppLocked(caller);
9116                if (callerApp == null) {
9117                    throw new SecurityException(
9118                            "Unable to find app for caller " + caller
9119                            + " (pid=" + Binder.getCallingPid()
9120                            + ") when starting service " + service);
9121                }
9122            }
9123
9124            ServiceLookupResult res =
9125                retrieveServiceLocked(service, resolvedType,
9126                        callingPid, callingUid);
9127            if (res == null) {
9128                return null;
9129            }
9130            if (res.record == null) {
9131                return new ComponentName("!", res.permission != null
9132                        ? res.permission : "private to package");
9133            }
9134            ServiceRecord r = res.record;
9135            int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
9136                    callingUid, r.packageName, service);
9137            if (unscheduleServiceRestartLocked(r)) {
9138                if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
9139            }
9140            r.startRequested = true;
9141            r.callStart = false;
9142            r.lastStartId++;
9143            if (r.lastStartId < 1) {
9144                r.lastStartId = 1;
9145            }
9146            r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId,
9147                    service, targetPermissionUid));
9148            r.lastActivity = SystemClock.uptimeMillis();
9149            synchronized (r.stats.getBatteryStats()) {
9150                r.stats.startRunningLocked();
9151            }
9152            if (!bringUpServiceLocked(r, service.getFlags(), false)) {
9153                return new ComponentName("!", "Service process is bad");
9154            }
9155            return r.name;
9156        }
9157    }
9158
9159    public ComponentName startService(IApplicationThread caller, Intent service,
9160            String resolvedType) {
9161        // Refuse possible leaked file descriptors
9162        if (service != null && service.hasFileDescriptors() == true) {
9163            throw new IllegalArgumentException("File descriptors passed in Intent");
9164        }
9165
9166        synchronized(this) {
9167            final int callingPid = Binder.getCallingPid();
9168            final int callingUid = Binder.getCallingUid();
9169            final long origId = Binder.clearCallingIdentity();
9170            ComponentName res = startServiceLocked(caller, service,
9171                    resolvedType, callingPid, callingUid);
9172            Binder.restoreCallingIdentity(origId);
9173            return res;
9174        }
9175    }
9176
9177    ComponentName startServiceInPackage(int uid,
9178            Intent service, String resolvedType) {
9179        synchronized(this) {
9180            final long origId = Binder.clearCallingIdentity();
9181            ComponentName res = startServiceLocked(null, service,
9182                    resolvedType, -1, uid);
9183            Binder.restoreCallingIdentity(origId);
9184            return res;
9185        }
9186    }
9187
9188    public int stopService(IApplicationThread caller, Intent service,
9189            String resolvedType) {
9190        // Refuse possible leaked file descriptors
9191        if (service != null && service.hasFileDescriptors() == true) {
9192            throw new IllegalArgumentException("File descriptors passed in Intent");
9193        }
9194
9195        synchronized(this) {
9196            if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
9197                    + " type=" + resolvedType);
9198
9199            final ProcessRecord callerApp = getRecordForAppLocked(caller);
9200            if (caller != null && callerApp == null) {
9201                throw new SecurityException(
9202                        "Unable to find app for caller " + caller
9203                        + " (pid=" + Binder.getCallingPid()
9204                        + ") when stopping service " + service);
9205            }
9206
9207            // If this service is active, make sure it is stopped.
9208            ServiceLookupResult r = findServiceLocked(service, resolvedType);
9209            if (r != null) {
9210                if (r.record != null) {
9211                    synchronized (r.record.stats.getBatteryStats()) {
9212                        r.record.stats.stopRunningLocked();
9213                    }
9214                    r.record.startRequested = false;
9215                    r.record.callStart = false;
9216                    final long origId = Binder.clearCallingIdentity();
9217                    bringDownServiceLocked(r.record, false);
9218                    Binder.restoreCallingIdentity(origId);
9219                    return 1;
9220                }
9221                return -1;
9222            }
9223        }
9224
9225        return 0;
9226    }
9227
9228    public IBinder peekService(Intent service, String resolvedType) {
9229        // Refuse possible leaked file descriptors
9230        if (service != null && service.hasFileDescriptors() == true) {
9231            throw new IllegalArgumentException("File descriptors passed in Intent");
9232        }
9233
9234        IBinder ret = null;
9235
9236        synchronized(this) {
9237            ServiceLookupResult r = findServiceLocked(service, resolvedType);
9238
9239            if (r != null) {
9240                // r.record is null if findServiceLocked() failed the caller permission check
9241                if (r.record == null) {
9242                    throw new SecurityException(
9243                            "Permission Denial: Accessing service "
9244                            + " from pid=" + Binder.getCallingPid()
9245                            + ", uid=" + Binder.getCallingUid()
9246                            + " requires " + r.permission);
9247                }
9248                IntentBindRecord ib = r.record.bindings.get(r.record.intent);
9249                if (ib != null) {
9250                    ret = ib.binder;
9251                }
9252            }
9253        }
9254
9255        return ret;
9256    }
9257
9258    public boolean stopServiceToken(ComponentName className, IBinder token,
9259            int startId) {
9260        synchronized(this) {
9261            if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
9262                    + " " + token + " startId=" + startId);
9263            ServiceRecord r = findServiceLocked(className, token);
9264            if (r != null) {
9265                if (startId >= 0) {
9266                    // Asked to only stop if done with all work.  Note that
9267                    // to avoid leaks, we will take this as dropping all
9268                    // start items up to and including this one.
9269                    ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
9270                    if (si != null) {
9271                        while (r.deliveredStarts.size() > 0) {
9272                            ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
9273                            cur.removeUriPermissionsLocked();
9274                            if (cur == si) {
9275                                break;
9276                            }
9277                        }
9278                    }
9279
9280                    if (r.lastStartId != startId) {
9281                        return false;
9282                    }
9283
9284                    if (r.deliveredStarts.size() > 0) {
9285                        Slog.w(TAG, "stopServiceToken startId " + startId
9286                                + " is last, but have " + r.deliveredStarts.size()
9287                                + " remaining args");
9288                    }
9289                }
9290
9291                synchronized (r.stats.getBatteryStats()) {
9292                    r.stats.stopRunningLocked();
9293                    r.startRequested = false;
9294                    r.callStart = false;
9295                }
9296                final long origId = Binder.clearCallingIdentity();
9297                bringDownServiceLocked(r, false);
9298                Binder.restoreCallingIdentity(origId);
9299                return true;
9300            }
9301        }
9302        return false;
9303    }
9304
9305    public void setServiceForeground(ComponentName className, IBinder token,
9306            int id, Notification notification, boolean removeNotification) {
9307        final long origId = Binder.clearCallingIdentity();
9308        try {
9309        synchronized(this) {
9310            ServiceRecord r = findServiceLocked(className, token);
9311            if (r != null) {
9312                if (id != 0) {
9313                    if (notification == null) {
9314                        throw new IllegalArgumentException("null notification");
9315                    }
9316                    if (r.foregroundId != id) {
9317                        r.cancelNotification();
9318                        r.foregroundId = id;
9319                    }
9320                    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
9321                    r.foregroundNoti = notification;
9322                    r.isForeground = true;
9323                    r.postNotification();
9324                    if (r.app != null) {
9325                        updateServiceForegroundLocked(r.app, true);
9326                    }
9327                } else {
9328                    if (r.isForeground) {
9329                        r.isForeground = false;
9330                        if (r.app != null) {
9331                            updateLruProcessLocked(r.app, false, true);
9332                            updateServiceForegroundLocked(r.app, true);
9333                        }
9334                    }
9335                    if (removeNotification) {
9336                        r.cancelNotification();
9337                        r.foregroundId = 0;
9338                        r.foregroundNoti = null;
9339                    }
9340                }
9341            }
9342        }
9343        } finally {
9344            Binder.restoreCallingIdentity(origId);
9345        }
9346    }
9347
9348    public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
9349        boolean anyForeground = false;
9350        for (ServiceRecord sr : proc.services) {
9351            if (sr.isForeground) {
9352                anyForeground = true;
9353                break;
9354            }
9355        }
9356        if (anyForeground != proc.foregroundServices) {
9357            proc.foregroundServices = anyForeground;
9358            if (oomAdj) {
9359                updateOomAdjLocked();
9360            }
9361        }
9362    }
9363
9364    public int bindService(IApplicationThread caller, IBinder token,
9365            Intent service, String resolvedType,
9366            IServiceConnection connection, int flags) {
9367        // Refuse possible leaked file descriptors
9368        if (service != null && service.hasFileDescriptors() == true) {
9369            throw new IllegalArgumentException("File descriptors passed in Intent");
9370        }
9371
9372        synchronized(this) {
9373            if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
9374                    + " type=" + resolvedType + " conn=" + connection.asBinder()
9375                    + " flags=0x" + Integer.toHexString(flags));
9376            final ProcessRecord callerApp = getRecordForAppLocked(caller);
9377            if (callerApp == null) {
9378                throw new SecurityException(
9379                        "Unable to find app for caller " + caller
9380                        + " (pid=" + Binder.getCallingPid()
9381                        + ") when binding service " + service);
9382            }
9383
9384            ActivityRecord activity = null;
9385            if (token != null) {
9386                int aindex = mMainStack.indexOfTokenLocked(token);
9387                if (aindex < 0) {
9388                    Slog.w(TAG, "Binding with unknown activity: " + token);
9389                    return 0;
9390                }
9391                activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
9392            }
9393
9394            int clientLabel = 0;
9395            PendingIntent clientIntent = null;
9396
9397            if (callerApp.info.uid == Process.SYSTEM_UID) {
9398                // Hacky kind of thing -- allow system stuff to tell us
9399                // what they are, so we can report this elsewhere for
9400                // others to know why certain services are running.
9401                try {
9402                    clientIntent = (PendingIntent)service.getParcelableExtra(
9403                            Intent.EXTRA_CLIENT_INTENT);
9404                } catch (RuntimeException e) {
9405                }
9406                if (clientIntent != null) {
9407                    clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
9408                    if (clientLabel != 0) {
9409                        // There are no useful extras in the intent, trash them.
9410                        // System code calling with this stuff just needs to know
9411                        // this will happen.
9412                        service = service.cloneFilter();
9413                    }
9414                }
9415            }
9416
9417            ServiceLookupResult res =
9418                retrieveServiceLocked(service, resolvedType,
9419                        Binder.getCallingPid(), Binder.getCallingUid());
9420            if (res == null) {
9421                return 0;
9422            }
9423            if (res.record == null) {
9424                return -1;
9425            }
9426            ServiceRecord s = res.record;
9427
9428            final long origId = Binder.clearCallingIdentity();
9429
9430            if (unscheduleServiceRestartLocked(s)) {
9431                if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
9432                        + s);
9433            }
9434
9435            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
9436            ConnectionRecord c = new ConnectionRecord(b, activity,
9437                    connection, flags, clientLabel, clientIntent);
9438
9439            IBinder binder = connection.asBinder();
9440            ArrayList<ConnectionRecord> clist = s.connections.get(binder);
9441            if (clist == null) {
9442                clist = new ArrayList<ConnectionRecord>();
9443                s.connections.put(binder, clist);
9444            }
9445            clist.add(c);
9446            b.connections.add(c);
9447            if (activity != null) {
9448                if (activity.connections == null) {
9449                    activity.connections = new HashSet<ConnectionRecord>();
9450                }
9451                activity.connections.add(c);
9452            }
9453            b.client.connections.add(c);
9454            clist = mServiceConnections.get(binder);
9455            if (clist == null) {
9456                clist = new ArrayList<ConnectionRecord>();
9457                mServiceConnections.put(binder, clist);
9458            }
9459            clist.add(c);
9460
9461            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
9462                s.lastActivity = SystemClock.uptimeMillis();
9463                if (!bringUpServiceLocked(s, service.getFlags(), false)) {
9464                    return 0;
9465                }
9466            }
9467
9468            if (s.app != null) {
9469                // This could have made the service more important.
9470                updateOomAdjLocked(s.app);
9471            }
9472
9473            if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
9474                    + ": received=" + b.intent.received
9475                    + " apps=" + b.intent.apps.size()
9476                    + " doRebind=" + b.intent.doRebind);
9477
9478            if (s.app != null && b.intent.received) {
9479                // Service is already running, so we can immediately
9480                // publish the connection.
9481                try {
9482                    c.conn.connected(s.name, b.intent.binder);
9483                } catch (Exception e) {
9484                    Slog.w(TAG, "Failure sending service " + s.shortName
9485                            + " to connection " + c.conn.asBinder()
9486                            + " (in " + c.binding.client.processName + ")", e);
9487                }
9488
9489                // If this is the first app connected back to this binding,
9490                // and the service had previously asked to be told when
9491                // rebound, then do so.
9492                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
9493                    requestServiceBindingLocked(s, b.intent, true);
9494                }
9495            } else if (!b.intent.requested) {
9496                requestServiceBindingLocked(s, b.intent, false);
9497            }
9498
9499            Binder.restoreCallingIdentity(origId);
9500        }
9501
9502        return 1;
9503    }
9504
9505    void removeConnectionLocked(
9506        ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
9507        IBinder binder = c.conn.asBinder();
9508        AppBindRecord b = c.binding;
9509        ServiceRecord s = b.service;
9510        ArrayList<ConnectionRecord> clist = s.connections.get(binder);
9511        if (clist != null) {
9512            clist.remove(c);
9513            if (clist.size() == 0) {
9514                s.connections.remove(binder);
9515            }
9516        }
9517        b.connections.remove(c);
9518        if (c.activity != null && c.activity != skipAct) {
9519            if (c.activity.connections != null) {
9520                c.activity.connections.remove(c);
9521            }
9522        }
9523        if (b.client != skipApp) {
9524            b.client.connections.remove(c);
9525        }
9526        clist = mServiceConnections.get(binder);
9527        if (clist != null) {
9528            clist.remove(c);
9529            if (clist.size() == 0) {
9530                mServiceConnections.remove(binder);
9531            }
9532        }
9533
9534        if (b.connections.size() == 0) {
9535            b.intent.apps.remove(b.client);
9536        }
9537
9538        if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
9539                + ": shouldUnbind=" + b.intent.hasBound);
9540        if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
9541                && b.intent.hasBound) {
9542            try {
9543                bumpServiceExecutingLocked(s, "unbind");
9544                updateOomAdjLocked(s.app);
9545                b.intent.hasBound = false;
9546                // Assume the client doesn't want to know about a rebind;
9547                // we will deal with that later if it asks for one.
9548                b.intent.doRebind = false;
9549                s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
9550            } catch (Exception e) {
9551                Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
9552                serviceDoneExecutingLocked(s, true);
9553            }
9554        }
9555
9556        if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
9557            bringDownServiceLocked(s, false);
9558        }
9559    }
9560
9561    public boolean unbindService(IServiceConnection connection) {
9562        synchronized (this) {
9563            IBinder binder = connection.asBinder();
9564            if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
9565            ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
9566            if (clist == null) {
9567                Slog.w(TAG, "Unbind failed: could not find connection for "
9568                      + connection.asBinder());
9569                return false;
9570            }
9571
9572            final long origId = Binder.clearCallingIdentity();
9573
9574            while (clist.size() > 0) {
9575                ConnectionRecord r = clist.get(0);
9576                removeConnectionLocked(r, null, null);
9577
9578                if (r.binding.service.app != null) {
9579                    // This could have made the service less important.
9580                    updateOomAdjLocked(r.binding.service.app);
9581                }
9582            }
9583
9584            Binder.restoreCallingIdentity(origId);
9585        }
9586
9587        return true;
9588    }
9589
9590    public void publishService(IBinder token, Intent intent, IBinder service) {
9591        // Refuse possible leaked file descriptors
9592        if (intent != null && intent.hasFileDescriptors() == true) {
9593            throw new IllegalArgumentException("File descriptors passed in Intent");
9594        }
9595
9596        synchronized(this) {
9597            if (!(token instanceof ServiceRecord)) {
9598                throw new IllegalArgumentException("Invalid service token");
9599            }
9600            ServiceRecord r = (ServiceRecord)token;
9601
9602            final long origId = Binder.clearCallingIdentity();
9603
9604            if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
9605                    + " " + intent + ": " + service);
9606            if (r != null) {
9607                Intent.FilterComparison filter
9608                        = new Intent.FilterComparison(intent);
9609                IntentBindRecord b = r.bindings.get(filter);
9610                if (b != null && !b.received) {
9611                    b.binder = service;
9612                    b.requested = true;
9613                    b.received = true;
9614                    if (r.connections.size() > 0) {
9615                        Iterator<ArrayList<ConnectionRecord>> it
9616                                = r.connections.values().iterator();
9617                        while (it.hasNext()) {
9618                            ArrayList<ConnectionRecord> clist = it.next();
9619                            for (int i=0; i<clist.size(); i++) {
9620                                ConnectionRecord c = clist.get(i);
9621                                if (!filter.equals(c.binding.intent.intent)) {
9622                                    if (DEBUG_SERVICE) Slog.v(
9623                                            TAG, "Not publishing to: " + c);
9624                                    if (DEBUG_SERVICE) Slog.v(
9625                                            TAG, "Bound intent: " + c.binding.intent.intent);
9626                                    if (DEBUG_SERVICE) Slog.v(
9627                                            TAG, "Published intent: " + intent);
9628                                    continue;
9629                                }
9630                                if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
9631                                try {
9632                                    c.conn.connected(r.name, service);
9633                                } catch (Exception e) {
9634                                    Slog.w(TAG, "Failure sending service " + r.name +
9635                                          " to connection " + c.conn.asBinder() +
9636                                          " (in " + c.binding.client.processName + ")", e);
9637                                }
9638                            }
9639                        }
9640                    }
9641                }
9642
9643                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
9644
9645                Binder.restoreCallingIdentity(origId);
9646            }
9647        }
9648    }
9649
9650    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
9651        // Refuse possible leaked file descriptors
9652        if (intent != null && intent.hasFileDescriptors() == true) {
9653            throw new IllegalArgumentException("File descriptors passed in Intent");
9654        }
9655
9656        synchronized(this) {
9657            if (!(token instanceof ServiceRecord)) {
9658                throw new IllegalArgumentException("Invalid service token");
9659            }
9660            ServiceRecord r = (ServiceRecord)token;
9661
9662            final long origId = Binder.clearCallingIdentity();
9663
9664            if (r != null) {
9665                Intent.FilterComparison filter
9666                        = new Intent.FilterComparison(intent);
9667                IntentBindRecord b = r.bindings.get(filter);
9668                if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
9669                        + " at " + b + ": apps="
9670                        + (b != null ? b.apps.size() : 0));
9671                if (b != null) {
9672                    if (b.apps.size() > 0) {
9673                        // Applications have already bound since the last
9674                        // unbind, so just rebind right here.
9675                        requestServiceBindingLocked(r, b, true);
9676                    } else {
9677                        // Note to tell the service the next time there is
9678                        // a new client.
9679                        b.doRebind = true;
9680                    }
9681                }
9682
9683                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
9684
9685                Binder.restoreCallingIdentity(origId);
9686            }
9687        }
9688    }
9689
9690    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
9691        synchronized(this) {
9692            if (!(token instanceof ServiceRecord)) {
9693                throw new IllegalArgumentException("Invalid service token");
9694            }
9695            ServiceRecord r = (ServiceRecord)token;
9696            boolean inStopping = mStoppingServices.contains(token);
9697            if (r != null) {
9698                if (r != token) {
9699                    Slog.w(TAG, "Done executing service " + r.name
9700                          + " with incorrect token: given " + token
9701                          + ", expected " + r);
9702                    return;
9703                }
9704
9705                if (type == 1) {
9706                    // This is a call from a service start...  take care of
9707                    // book-keeping.
9708                    r.callStart = true;
9709                    switch (res) {
9710                        case Service.START_STICKY_COMPATIBILITY:
9711                        case Service.START_STICKY: {
9712                            // We are done with the associated start arguments.
9713                            r.findDeliveredStart(startId, true);
9714                            // Don't stop if killed.
9715                            r.stopIfKilled = false;
9716                            break;
9717                        }
9718                        case Service.START_NOT_STICKY: {
9719                            // We are done with the associated start arguments.
9720                            r.findDeliveredStart(startId, true);
9721                            if (r.lastStartId == startId) {
9722                                // There is no more work, and this service
9723                                // doesn't want to hang around if killed.
9724                                r.stopIfKilled = true;
9725                            }
9726                            break;
9727                        }
9728                        case Service.START_REDELIVER_INTENT: {
9729                            // We'll keep this item until they explicitly
9730                            // call stop for it, but keep track of the fact
9731                            // that it was delivered.
9732                            ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
9733                            if (si != null) {
9734                                si.deliveryCount = 0;
9735                                si.doneExecutingCount++;
9736                                // Don't stop if killed.
9737                                r.stopIfKilled = true;
9738                            }
9739                            break;
9740                        }
9741                        default:
9742                            throw new IllegalArgumentException(
9743                                    "Unknown service start result: " + res);
9744                    }
9745                    if (res == Service.START_STICKY_COMPATIBILITY) {
9746                        r.callStart = false;
9747                    }
9748                }
9749
9750                final long origId = Binder.clearCallingIdentity();
9751                serviceDoneExecutingLocked(r, inStopping);
9752                Binder.restoreCallingIdentity(origId);
9753            } else {
9754                Slog.w(TAG, "Done executing unknown service from pid "
9755                        + Binder.getCallingPid());
9756            }
9757        }
9758    }
9759
9760    public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
9761        if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
9762                + ": nesting=" + r.executeNesting
9763                + ", inStopping=" + inStopping + ", app=" + r.app);
9764        else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
9765        r.executeNesting--;
9766        if (r.executeNesting <= 0 && r.app != null) {
9767            if (DEBUG_SERVICE) Slog.v(TAG,
9768                    "Nesting at 0 of " + r.shortName);
9769            r.app.executingServices.remove(r);
9770            if (r.app.executingServices.size() == 0) {
9771                if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
9772                        "No more executingServices of " + r.shortName);
9773                mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
9774            }
9775            if (inStopping) {
9776                if (DEBUG_SERVICE) Slog.v(TAG,
9777                        "doneExecuting remove stopping " + r);
9778                mStoppingServices.remove(r);
9779                r.bindings.clear();
9780            }
9781            updateOomAdjLocked(r.app);
9782        }
9783    }
9784
9785    void serviceTimeout(ProcessRecord proc) {
9786        String anrMessage = null;
9787
9788        synchronized(this) {
9789            if (proc.executingServices.size() == 0 || proc.thread == null) {
9790                return;
9791            }
9792            long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
9793            Iterator<ServiceRecord> it = proc.executingServices.iterator();
9794            ServiceRecord timeout = null;
9795            long nextTime = 0;
9796            while (it.hasNext()) {
9797                ServiceRecord sr = it.next();
9798                if (sr.executingStart < maxTime) {
9799                    timeout = sr;
9800                    break;
9801                }
9802                if (sr.executingStart > nextTime) {
9803                    nextTime = sr.executingStart;
9804                }
9805            }
9806            if (timeout != null && mLruProcesses.contains(proc)) {
9807                Slog.w(TAG, "Timeout executing service: " + timeout);
9808                anrMessage = "Executing service " + timeout.shortName;
9809            } else {
9810                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9811                msg.obj = proc;
9812                mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
9813            }
9814        }
9815
9816        if (anrMessage != null) {
9817            appNotResponding(proc, null, null, anrMessage);
9818        }
9819    }
9820
9821    // =========================================================
9822    // BACKUP AND RESTORE
9823    // =========================================================
9824
9825    // Cause the target app to be launched if necessary and its backup agent
9826    // instantiated.  The backup agent will invoke backupAgentCreated() on the
9827    // activity manager to announce its creation.
9828    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
9829        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
9830        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
9831
9832        synchronized(this) {
9833            // !!! TODO: currently no check here that we're already bound
9834            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9835            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9836            synchronized (stats) {
9837                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
9838            }
9839
9840            BackupRecord r = new BackupRecord(ss, app, backupMode);
9841            ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
9842            // startProcessLocked() returns existing proc's record if it's already running
9843            ProcessRecord proc = startProcessLocked(app.processName, app,
9844                    false, 0, "backup", hostingName, false);
9845            if (proc == null) {
9846                Slog.e(TAG, "Unable to start backup agent process " + r);
9847                return false;
9848            }
9849
9850            r.app = proc;
9851            mBackupTarget = r;
9852            mBackupAppName = app.packageName;
9853
9854            // Try not to kill the process during backup
9855            updateOomAdjLocked(proc);
9856
9857            // If the process is already attached, schedule the creation of the backup agent now.
9858            // If it is not yet live, this will be done when it attaches to the framework.
9859            if (proc.thread != null) {
9860                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
9861                try {
9862                    proc.thread.scheduleCreateBackupAgent(app, backupMode);
9863                } catch (RemoteException e) {
9864                    // Will time out on the backup manager side
9865                }
9866            } else {
9867                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
9868            }
9869            // Invariants: at this point, the target app process exists and the application
9870            // is either already running or in the process of coming up.  mBackupTarget and
9871            // mBackupAppName describe the app, so that when it binds back to the AM we
9872            // know that it's scheduled for a backup-agent operation.
9873        }
9874
9875        return true;
9876    }
9877
9878    // A backup agent has just come up
9879    public void backupAgentCreated(String agentPackageName, IBinder agent) {
9880        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
9881                + " = " + agent);
9882
9883        synchronized(this) {
9884            if (!agentPackageName.equals(mBackupAppName)) {
9885                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
9886                return;
9887            }
9888        }
9889
9890        long oldIdent = Binder.clearCallingIdentity();
9891        try {
9892            IBackupManager bm = IBackupManager.Stub.asInterface(
9893                    ServiceManager.getService(Context.BACKUP_SERVICE));
9894            bm.agentConnected(agentPackageName, agent);
9895        } catch (RemoteException e) {
9896            // can't happen; the backup manager service is local
9897        } catch (Exception e) {
9898            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
9899            e.printStackTrace();
9900        } finally {
9901            Binder.restoreCallingIdentity(oldIdent);
9902        }
9903    }
9904
9905    // done with this agent
9906    public void unbindBackupAgent(ApplicationInfo appInfo) {
9907        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
9908        if (appInfo == null) {
9909            Slog.w(TAG, "unbind backup agent for null app");
9910            return;
9911        }
9912
9913        synchronized(this) {
9914            if (mBackupAppName == null) {
9915                Slog.w(TAG, "Unbinding backup agent with no active backup");
9916                return;
9917            }
9918
9919            if (!mBackupAppName.equals(appInfo.packageName)) {
9920                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
9921                return;
9922            }
9923
9924            ProcessRecord proc = mBackupTarget.app;
9925            mBackupTarget = null;
9926            mBackupAppName = null;
9927
9928            // Not backing this app up any more; reset its OOM adjustment
9929            updateOomAdjLocked(proc);
9930
9931            // If the app crashed during backup, 'thread' will be null here
9932            if (proc.thread != null) {
9933                try {
9934                    proc.thread.scheduleDestroyBackupAgent(appInfo);
9935                } catch (Exception e) {
9936                    Slog.e(TAG, "Exception when unbinding backup agent:");
9937                    e.printStackTrace();
9938                }
9939            }
9940        }
9941    }
9942    // =========================================================
9943    // BROADCASTS
9944    // =========================================================
9945
9946    private final List getStickiesLocked(String action, IntentFilter filter,
9947            List cur) {
9948        final ContentResolver resolver = mContext.getContentResolver();
9949        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
9950        if (list == null) {
9951            return cur;
9952        }
9953        int N = list.size();
9954        for (int i=0; i<N; i++) {
9955            Intent intent = list.get(i);
9956            if (filter.match(resolver, intent, true, TAG) >= 0) {
9957                if (cur == null) {
9958                    cur = new ArrayList<Intent>();
9959                }
9960                cur.add(intent);
9961            }
9962        }
9963        return cur;
9964    }
9965
9966    private final void scheduleBroadcastsLocked() {
9967        if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
9968                + mBroadcastsScheduled);
9969
9970        if (mBroadcastsScheduled) {
9971            return;
9972        }
9973        mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
9974        mBroadcastsScheduled = true;
9975    }
9976
9977    public Intent registerReceiver(IApplicationThread caller,
9978            IIntentReceiver receiver, IntentFilter filter, String permission) {
9979        synchronized(this) {
9980            ProcessRecord callerApp = null;
9981            if (caller != null) {
9982                callerApp = getRecordForAppLocked(caller);
9983                if (callerApp == null) {
9984                    throw new SecurityException(
9985                            "Unable to find app for caller " + caller
9986                            + " (pid=" + Binder.getCallingPid()
9987                            + ") when registering receiver " + receiver);
9988                }
9989            }
9990
9991            List allSticky = null;
9992
9993            // Look for any matching sticky broadcasts...
9994            Iterator actions = filter.actionsIterator();
9995            if (actions != null) {
9996                while (actions.hasNext()) {
9997                    String action = (String)actions.next();
9998                    allSticky = getStickiesLocked(action, filter, allSticky);
9999                }
10000            } else {
10001                allSticky = getStickiesLocked(null, filter, allSticky);
10002            }
10003
10004            // The first sticky in the list is returned directly back to
10005            // the client.
10006            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10007
10008            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
10009                    + ": " + sticky);
10010
10011            if (receiver == null) {
10012                return sticky;
10013            }
10014
10015            ReceiverList rl
10016                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10017            if (rl == null) {
10018                rl = new ReceiverList(this, callerApp,
10019                        Binder.getCallingPid(),
10020                        Binder.getCallingUid(), receiver);
10021                if (rl.app != null) {
10022                    rl.app.receivers.add(rl);
10023                } else {
10024                    try {
10025                        receiver.asBinder().linkToDeath(rl, 0);
10026                    } catch (RemoteException e) {
10027                        return sticky;
10028                    }
10029                    rl.linkedToDeath = true;
10030                }
10031                mRegisteredReceivers.put(receiver.asBinder(), rl);
10032            }
10033            BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
10034            rl.add(bf);
10035            if (!bf.debugCheck()) {
10036                Slog.w(TAG, "==> For Dynamic broadast");
10037            }
10038            mReceiverResolver.addFilter(bf);
10039
10040            // Enqueue broadcasts for all existing stickies that match
10041            // this filter.
10042            if (allSticky != null) {
10043                ArrayList receivers = new ArrayList();
10044                receivers.add(bf);
10045
10046                int N = allSticky.size();
10047                for (int i=0; i<N; i++) {
10048                    Intent intent = (Intent)allSticky.get(i);
10049                    BroadcastRecord r = new BroadcastRecord(intent, null,
10050                            null, -1, -1, null, receivers, null, 0, null, null,
10051                            false, true, true);
10052                    if (mParallelBroadcasts.size() == 0) {
10053                        scheduleBroadcastsLocked();
10054                    }
10055                    mParallelBroadcasts.add(r);
10056                }
10057            }
10058
10059            return sticky;
10060        }
10061    }
10062
10063    public void unregisterReceiver(IIntentReceiver receiver) {
10064        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
10065
10066        boolean doNext = false;
10067
10068        synchronized(this) {
10069            ReceiverList rl
10070                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10071            if (rl != null) {
10072                if (rl.curBroadcast != null) {
10073                    BroadcastRecord r = rl.curBroadcast;
10074                    doNext = finishReceiverLocked(
10075                        receiver.asBinder(), r.resultCode, r.resultData,
10076                        r.resultExtras, r.resultAbort, true);
10077                }
10078
10079                if (rl.app != null) {
10080                    rl.app.receivers.remove(rl);
10081                }
10082                removeReceiverLocked(rl);
10083                if (rl.linkedToDeath) {
10084                    rl.linkedToDeath = false;
10085                    rl.receiver.asBinder().unlinkToDeath(rl, 0);
10086                }
10087            }
10088        }
10089
10090        if (!doNext) {
10091            return;
10092        }
10093
10094        final long origId = Binder.clearCallingIdentity();
10095        processNextBroadcast(false);
10096        trimApplications();
10097        Binder.restoreCallingIdentity(origId);
10098    }
10099
10100    void removeReceiverLocked(ReceiverList rl) {
10101        mRegisteredReceivers.remove(rl.receiver.asBinder());
10102        int N = rl.size();
10103        for (int i=0; i<N; i++) {
10104            mReceiverResolver.removeFilter(rl.get(i));
10105        }
10106    }
10107
10108    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
10109        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10110            ProcessRecord r = mLruProcesses.get(i);
10111            if (r.thread != null) {
10112                try {
10113                    r.thread.dispatchPackageBroadcast(cmd, packages);
10114                } catch (RemoteException ex) {
10115                }
10116            }
10117        }
10118    }
10119
10120    private final int broadcastIntentLocked(ProcessRecord callerApp,
10121            String callerPackage, Intent intent, String resolvedType,
10122            IIntentReceiver resultTo, int resultCode, String resultData,
10123            Bundle map, String requiredPermission,
10124            boolean ordered, boolean sticky, int callingPid, int callingUid) {
10125        intent = new Intent(intent);
10126
10127        if (DEBUG_BROADCAST_LIGHT) Slog.v(
10128            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
10129            + " ordered=" + ordered);
10130        if ((resultTo != null) && !ordered) {
10131            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
10132        }
10133
10134        // Handle special intents: if this broadcast is from the package
10135        // manager about a package being removed, we need to remove all of
10136        // its activities from the history stack.
10137        final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals(
10138                intent.getAction());
10139        if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
10140                || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
10141                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
10142                || uidRemoved) {
10143            if (checkComponentPermission(
10144                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
10145                    callingPid, callingUid, -1)
10146                    == PackageManager.PERMISSION_GRANTED) {
10147                if (uidRemoved) {
10148                    final Bundle intentExtras = intent.getExtras();
10149                    final int uid = intentExtras != null
10150                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
10151                    if (uid >= 0) {
10152                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
10153                        synchronized (bs) {
10154                            bs.removeUidStatsLocked(uid);
10155                        }
10156                    }
10157                } else {
10158                    // If resources are unvailble just force stop all
10159                    // those packages and flush the attribute cache as well.
10160                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
10161                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
10162                        if (list != null && (list.length > 0)) {
10163                            for (String pkg : list) {
10164                                forceStopPackageLocked(pkg, -1, false, true, true);
10165                            }
10166                            sendPackageBroadcastLocked(
10167                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
10168                        }
10169                    } else {
10170                        Uri data = intent.getData();
10171                        String ssp;
10172                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
10173                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
10174                                forceStopPackageLocked(ssp,
10175                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
10176                            }
10177                            if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
10178                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
10179                                        new String[] {ssp});
10180                            }
10181                        }
10182                    }
10183                }
10184            } else {
10185                String msg = "Permission Denial: " + intent.getAction()
10186                        + " broadcast from " + callerPackage + " (pid=" + callingPid
10187                        + ", uid=" + callingUid + ")"
10188                        + " requires "
10189                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
10190                Slog.w(TAG, msg);
10191                throw new SecurityException(msg);
10192            }
10193        }
10194
10195        /*
10196         * If this is the time zone changed action, queue up a message that will reset the timezone
10197         * of all currently running processes. This message will get queued up before the broadcast
10198         * happens.
10199         */
10200        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
10201            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
10202        }
10203
10204        /*
10205         * Prevent non-system code (defined here to be non-persistent
10206         * processes) from sending protected broadcasts.
10207         */
10208        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
10209                || callingUid == Process.SHELL_UID || callingUid == 0) {
10210            // Always okay.
10211        } else if (callerApp == null || !callerApp.persistent) {
10212            try {
10213                if (AppGlobals.getPackageManager().isProtectedBroadcast(
10214                        intent.getAction())) {
10215                    String msg = "Permission Denial: not allowed to send broadcast "
10216                            + intent.getAction() + " from pid="
10217                            + callingPid + ", uid=" + callingUid;
10218                    Slog.w(TAG, msg);
10219                    throw new SecurityException(msg);
10220                }
10221            } catch (RemoteException e) {
10222                Slog.w(TAG, "Remote exception", e);
10223                return BROADCAST_SUCCESS;
10224            }
10225        }
10226
10227        // Add to the sticky list if requested.
10228        if (sticky) {
10229            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
10230                    callingPid, callingUid)
10231                    != PackageManager.PERMISSION_GRANTED) {
10232                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
10233                        + callingPid + ", uid=" + callingUid
10234                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
10235                Slog.w(TAG, msg);
10236                throw new SecurityException(msg);
10237            }
10238            if (requiredPermission != null) {
10239                Slog.w(TAG, "Can't broadcast sticky intent " + intent
10240                        + " and enforce permission " + requiredPermission);
10241                return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
10242            }
10243            if (intent.getComponent() != null) {
10244                throw new SecurityException(
10245                        "Sticky broadcasts can't target a specific component");
10246            }
10247            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
10248            if (list == null) {
10249                list = new ArrayList<Intent>();
10250                mStickyBroadcasts.put(intent.getAction(), list);
10251            }
10252            int N = list.size();
10253            int i;
10254            for (i=0; i<N; i++) {
10255                if (intent.filterEquals(list.get(i))) {
10256                    // This sticky already exists, replace it.
10257                    list.set(i, new Intent(intent));
10258                    break;
10259                }
10260            }
10261            if (i >= N) {
10262                list.add(new Intent(intent));
10263            }
10264        }
10265
10266        // Figure out who all will receive this broadcast.
10267        List receivers = null;
10268        List<BroadcastFilter> registeredReceivers = null;
10269        try {
10270            if (intent.getComponent() != null) {
10271                // Broadcast is going to one specific receiver class...
10272                ActivityInfo ai = AppGlobals.getPackageManager().
10273                    getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
10274                if (ai != null) {
10275                    receivers = new ArrayList();
10276                    ResolveInfo ri = new ResolveInfo();
10277                    ri.activityInfo = ai;
10278                    receivers.add(ri);
10279                }
10280            } else {
10281                // Need to resolve the intent to interested receivers...
10282                if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
10283                         == 0) {
10284                    receivers =
10285                        AppGlobals.getPackageManager().queryIntentReceivers(
10286                                intent, resolvedType, STOCK_PM_FLAGS);
10287                }
10288                registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
10289            }
10290        } catch (RemoteException ex) {
10291            // pm is in same process, this will never happen.
10292        }
10293
10294        final boolean replacePending =
10295                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
10296
10297        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
10298                + " replacePending=" + replacePending);
10299
10300        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
10301        if (!ordered && NR > 0) {
10302            // If we are not serializing this broadcast, then send the
10303            // registered receivers separately so they don't wait for the
10304            // components to be launched.
10305            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
10306                    callerPackage, callingPid, callingUid, requiredPermission,
10307                    registeredReceivers, resultTo, resultCode, resultData, map,
10308                    ordered, sticky, false);
10309            if (DEBUG_BROADCAST) Slog.v(
10310                    TAG, "Enqueueing parallel broadcast " + r
10311                    + ": prev had " + mParallelBroadcasts.size());
10312            boolean replaced = false;
10313            if (replacePending) {
10314                for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
10315                    if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
10316                        if (DEBUG_BROADCAST) Slog.v(TAG,
10317                                "***** DROPPING PARALLEL: " + intent);
10318                        mParallelBroadcasts.set(i, r);
10319                        replaced = true;
10320                        break;
10321                    }
10322                }
10323            }
10324            if (!replaced) {
10325                mParallelBroadcasts.add(r);
10326                scheduleBroadcastsLocked();
10327            }
10328            registeredReceivers = null;
10329            NR = 0;
10330        }
10331
10332        // Merge into one list.
10333        int ir = 0;
10334        if (receivers != null) {
10335            // A special case for PACKAGE_ADDED: do not allow the package
10336            // being added to see this broadcast.  This prevents them from
10337            // using this as a back door to get run as soon as they are
10338            // installed.  Maybe in the future we want to have a special install
10339            // broadcast or such for apps, but we'd like to deliberately make
10340            // this decision.
10341            String skipPackages[] = null;
10342            if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
10343                    || intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
10344                    || intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
10345                Uri data = intent.getData();
10346                if (data != null) {
10347                    String pkgName = data.getSchemeSpecificPart();
10348                    if (pkgName != null) {
10349                        skipPackages = new String[] { pkgName };
10350                    }
10351                }
10352            } else if (intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
10353                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
10354            }
10355            if (skipPackages != null && (skipPackages.length > 0)) {
10356                for (String skipPackage : skipPackages) {
10357                    if (skipPackage != null) {
10358                        int NT = receivers.size();
10359                        for (int it=0; it<NT; it++) {
10360                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
10361                            if (curt.activityInfo.packageName.equals(skipPackage)) {
10362                                receivers.remove(it);
10363                                it--;
10364                                NT--;
10365                            }
10366                        }
10367                    }
10368                }
10369            }
10370
10371            int NT = receivers != null ? receivers.size() : 0;
10372            int it = 0;
10373            ResolveInfo curt = null;
10374            BroadcastFilter curr = null;
10375            while (it < NT && ir < NR) {
10376                if (curt == null) {
10377                    curt = (ResolveInfo)receivers.get(it);
10378                }
10379                if (curr == null) {
10380                    curr = registeredReceivers.get(ir);
10381                }
10382                if (curr.getPriority() >= curt.priority) {
10383                    // Insert this broadcast record into the final list.
10384                    receivers.add(it, curr);
10385                    ir++;
10386                    curr = null;
10387                    it++;
10388                    NT++;
10389                } else {
10390                    // Skip to the next ResolveInfo in the final list.
10391                    it++;
10392                    curt = null;
10393                }
10394            }
10395        }
10396        while (ir < NR) {
10397            if (receivers == null) {
10398                receivers = new ArrayList();
10399            }
10400            receivers.add(registeredReceivers.get(ir));
10401            ir++;
10402        }
10403
10404        if ((receivers != null && receivers.size() > 0)
10405                || resultTo != null) {
10406            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
10407                    callerPackage, callingPid, callingUid, requiredPermission,
10408                    receivers, resultTo, resultCode, resultData, map, ordered,
10409                    sticky, false);
10410            if (DEBUG_BROADCAST) Slog.v(
10411                    TAG, "Enqueueing ordered broadcast " + r
10412                    + ": prev had " + mOrderedBroadcasts.size());
10413            if (DEBUG_BROADCAST) {
10414                int seq = r.intent.getIntExtra("seq", -1);
10415                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
10416            }
10417            boolean replaced = false;
10418            if (replacePending) {
10419                for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
10420                    if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
10421                        if (DEBUG_BROADCAST) Slog.v(TAG,
10422                                "***** DROPPING ORDERED: " + intent);
10423                        mOrderedBroadcasts.set(i, r);
10424                        replaced = true;
10425                        break;
10426                    }
10427                }
10428            }
10429            if (!replaced) {
10430                mOrderedBroadcasts.add(r);
10431                scheduleBroadcastsLocked();
10432            }
10433        }
10434
10435        return BROADCAST_SUCCESS;
10436    }
10437
10438    final Intent verifyBroadcastLocked(Intent intent) {
10439        // Refuse possible leaked file descriptors
10440        if (intent != null && intent.hasFileDescriptors() == true) {
10441            throw new IllegalArgumentException("File descriptors passed in Intent");
10442        }
10443
10444        int flags = intent.getFlags();
10445
10446        if (!mProcessesReady) {
10447            // if the caller really truly claims to know what they're doing, go
10448            // ahead and allow the broadcast without launching any receivers
10449            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
10450                intent = new Intent(intent);
10451                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10452            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
10453                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
10454                        + " before boot completion");
10455                throw new IllegalStateException("Cannot broadcast before boot completed");
10456            }
10457        }
10458
10459        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
10460            throw new IllegalArgumentException(
10461                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
10462        }
10463
10464        return intent;
10465    }
10466
10467    public final int broadcastIntent(IApplicationThread caller,
10468            Intent intent, String resolvedType, IIntentReceiver resultTo,
10469            int resultCode, String resultData, Bundle map,
10470            String requiredPermission, boolean serialized, boolean sticky) {
10471        synchronized(this) {
10472            intent = verifyBroadcastLocked(intent);
10473
10474            final ProcessRecord callerApp = getRecordForAppLocked(caller);
10475            final int callingPid = Binder.getCallingPid();
10476            final int callingUid = Binder.getCallingUid();
10477            final long origId = Binder.clearCallingIdentity();
10478            int res = broadcastIntentLocked(callerApp,
10479                    callerApp != null ? callerApp.info.packageName : null,
10480                    intent, resolvedType, resultTo,
10481                    resultCode, resultData, map, requiredPermission, serialized,
10482                    sticky, callingPid, callingUid);
10483            Binder.restoreCallingIdentity(origId);
10484            return res;
10485        }
10486    }
10487
10488    int broadcastIntentInPackage(String packageName, int uid,
10489            Intent intent, String resolvedType, IIntentReceiver resultTo,
10490            int resultCode, String resultData, Bundle map,
10491            String requiredPermission, boolean serialized, boolean sticky) {
10492        synchronized(this) {
10493            intent = verifyBroadcastLocked(intent);
10494
10495            final long origId = Binder.clearCallingIdentity();
10496            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
10497                    resultTo, resultCode, resultData, map, requiredPermission,
10498                    serialized, sticky, -1, uid);
10499            Binder.restoreCallingIdentity(origId);
10500            return res;
10501        }
10502    }
10503
10504    public final void unbroadcastIntent(IApplicationThread caller,
10505            Intent intent) {
10506        // Refuse possible leaked file descriptors
10507        if (intent != null && intent.hasFileDescriptors() == true) {
10508            throw new IllegalArgumentException("File descriptors passed in Intent");
10509        }
10510
10511        synchronized(this) {
10512            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
10513                    != PackageManager.PERMISSION_GRANTED) {
10514                String msg = "Permission Denial: unbroadcastIntent() from pid="
10515                        + Binder.getCallingPid()
10516                        + ", uid=" + Binder.getCallingUid()
10517                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
10518                Slog.w(TAG, msg);
10519                throw new SecurityException(msg);
10520            }
10521            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
10522            if (list != null) {
10523                int N = list.size();
10524                int i;
10525                for (i=0; i<N; i++) {
10526                    if (intent.filterEquals(list.get(i))) {
10527                        list.remove(i);
10528                        break;
10529                    }
10530                }
10531            }
10532        }
10533    }
10534
10535    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
10536            String resultData, Bundle resultExtras, boolean resultAbort,
10537            boolean explicit) {
10538        if (mOrderedBroadcasts.size() == 0) {
10539            if (explicit) {
10540                Slog.w(TAG, "finishReceiver called but no pending broadcasts");
10541            }
10542            return false;
10543        }
10544        BroadcastRecord r = mOrderedBroadcasts.get(0);
10545        if (r.receiver == null) {
10546            if (explicit) {
10547                Slog.w(TAG, "finishReceiver called but none active");
10548            }
10549            return false;
10550        }
10551        if (r.receiver != receiver) {
10552            Slog.w(TAG, "finishReceiver called but active receiver is different");
10553            return false;
10554        }
10555        int state = r.state;
10556        r.state = r.IDLE;
10557        if (state == r.IDLE) {
10558            if (explicit) {
10559                Slog.w(TAG, "finishReceiver called but state is IDLE");
10560            }
10561        }
10562        r.receiver = null;
10563        r.intent.setComponent(null);
10564        if (r.curApp != null) {
10565            r.curApp.curReceiver = null;
10566        }
10567        if (r.curFilter != null) {
10568            r.curFilter.receiverList.curBroadcast = null;
10569        }
10570        r.curFilter = null;
10571        r.curApp = null;
10572        r.curComponent = null;
10573        r.curReceiver = null;
10574        mPendingBroadcast = null;
10575
10576        r.resultCode = resultCode;
10577        r.resultData = resultData;
10578        r.resultExtras = resultExtras;
10579        r.resultAbort = resultAbort;
10580
10581        // We will process the next receiver right now if this is finishing
10582        // an app receiver (which is always asynchronous) or after we have
10583        // come back from calling a receiver.
10584        return state == BroadcastRecord.APP_RECEIVE
10585                || state == BroadcastRecord.CALL_DONE_RECEIVE;
10586    }
10587
10588    public void finishReceiver(IBinder who, int resultCode, String resultData,
10589            Bundle resultExtras, boolean resultAbort) {
10590        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
10591
10592        // Refuse possible leaked file descriptors
10593        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
10594            throw new IllegalArgumentException("File descriptors passed in Bundle");
10595        }
10596
10597        boolean doNext;
10598
10599        final long origId = Binder.clearCallingIdentity();
10600
10601        synchronized(this) {
10602            doNext = finishReceiverLocked(
10603                who, resultCode, resultData, resultExtras, resultAbort, true);
10604        }
10605
10606        if (doNext) {
10607            processNextBroadcast(false);
10608        }
10609        trimApplications();
10610
10611        Binder.restoreCallingIdentity(origId);
10612    }
10613
10614    private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
10615        if (r.nextReceiver > 0) {
10616            Object curReceiver = r.receivers.get(r.nextReceiver-1);
10617            if (curReceiver instanceof BroadcastFilter) {
10618                BroadcastFilter bf = (BroadcastFilter) curReceiver;
10619                EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
10620                        System.identityHashCode(r),
10621                        r.intent.getAction(),
10622                        r.nextReceiver - 1,
10623                        System.identityHashCode(bf));
10624            } else {
10625                EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
10626                        System.identityHashCode(r),
10627                        r.intent.getAction(),
10628                        r.nextReceiver - 1,
10629                        ((ResolveInfo)curReceiver).toString());
10630            }
10631        } else {
10632            Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
10633                    + r);
10634            EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
10635                    System.identityHashCode(r),
10636                    r.intent.getAction(),
10637                    r.nextReceiver,
10638                    "NONE");
10639        }
10640    }
10641
10642    private final void setBroadcastTimeoutLocked(long timeoutTime) {
10643        if (! mPendingBroadcastTimeoutMessage) {
10644            Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
10645            mHandler.sendMessageAtTime(msg, timeoutTime);
10646            mPendingBroadcastTimeoutMessage = true;
10647        }
10648    }
10649
10650    private final void cancelBroadcastTimeoutLocked() {
10651        if (mPendingBroadcastTimeoutMessage) {
10652            mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
10653            mPendingBroadcastTimeoutMessage = false;
10654        }
10655    }
10656
10657    private final void broadcastTimeoutLocked(boolean fromMsg) {
10658        if (fromMsg) {
10659            mPendingBroadcastTimeoutMessage = false;
10660        }
10661
10662        if (mOrderedBroadcasts.size() == 0) {
10663            return;
10664        }
10665
10666        long now = SystemClock.uptimeMillis();
10667        BroadcastRecord r = mOrderedBroadcasts.get(0);
10668        if (fromMsg) {
10669            if (mDidDexOpt) {
10670                // Delay timeouts until dexopt finishes.
10671                mDidDexOpt = false;
10672                long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
10673                setBroadcastTimeoutLocked(timeoutTime);
10674                return;
10675            }
10676            if (! mProcessesReady) {
10677                // Only process broadcast timeouts if the system is ready. That way
10678                // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
10679                // to do heavy lifting for system up.
10680                return;
10681            }
10682
10683            long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
10684            if (timeoutTime > now) {
10685                // We can observe premature timeouts because we do not cancel and reset the
10686                // broadcast timeout message after each receiver finishes.  Instead, we set up
10687                // an initial timeout then kick it down the road a little further as needed
10688                // when it expires.
10689                if (DEBUG_BROADCAST) Slog.v(TAG,
10690                        "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
10691                        + timeoutTime);
10692                setBroadcastTimeoutLocked(timeoutTime);
10693                return;
10694            }
10695        }
10696
10697        Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
10698                + ", started " + (now - r.receiverTime) + "ms ago");
10699        r.receiverTime = now;
10700        r.anrCount++;
10701
10702        // Current receiver has passed its expiration date.
10703        if (r.nextReceiver <= 0) {
10704            Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
10705            return;
10706        }
10707
10708        ProcessRecord app = null;
10709        String anrMessage = null;
10710
10711        Object curReceiver = r.receivers.get(r.nextReceiver-1);
10712        Slog.w(TAG, "Receiver during timeout: " + curReceiver);
10713        logBroadcastReceiverDiscardLocked(r);
10714        if (curReceiver instanceof BroadcastFilter) {
10715            BroadcastFilter bf = (BroadcastFilter)curReceiver;
10716            if (bf.receiverList.pid != 0
10717                    && bf.receiverList.pid != MY_PID) {
10718                synchronized (this.mPidsSelfLocked) {
10719                    app = this.mPidsSelfLocked.get(
10720                            bf.receiverList.pid);
10721                }
10722            }
10723        } else {
10724            app = r.curApp;
10725        }
10726
10727        if (app != null) {
10728            anrMessage = "Broadcast of " + r.intent.toString();
10729        }
10730
10731        if (mPendingBroadcast == r) {
10732            mPendingBroadcast = null;
10733        }
10734
10735        // Move on to the next receiver.
10736        finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
10737                r.resultExtras, r.resultAbort, true);
10738        scheduleBroadcastsLocked();
10739
10740        if (anrMessage != null) {
10741            // Post the ANR to the handler since we do not want to process ANRs while
10742            // potentially holding our lock.
10743            mHandler.post(new AppNotResponding(app, anrMessage));
10744        }
10745    }
10746
10747    private final void processCurBroadcastLocked(BroadcastRecord r,
10748            ProcessRecord app) throws RemoteException {
10749        if (DEBUG_BROADCAST)  Slog.v(TAG,
10750                "Process cur broadcast " + r + " for app " + app);
10751        if (app.thread == null) {
10752            throw new RemoteException();
10753        }
10754        r.receiver = app.thread.asBinder();
10755        r.curApp = app;
10756        app.curReceiver = r;
10757        updateLruProcessLocked(app, true, true);
10758
10759        // Tell the application to launch this receiver.
10760        r.intent.setComponent(r.curComponent);
10761
10762        boolean started = false;
10763        try {
10764            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
10765                    "Delivering to component " + r.curComponent
10766                    + ": " + r);
10767            ensurePackageDexOpt(r.intent.getComponent().getPackageName());
10768            app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
10769                    r.resultCode, r.resultData, r.resultExtras, r.ordered);
10770            if (DEBUG_BROADCAST)  Slog.v(TAG,
10771                    "Process cur broadcast " + r + " DELIVERED for app " + app);
10772            started = true;
10773        } finally {
10774            if (!started) {
10775                if (DEBUG_BROADCAST)  Slog.v(TAG,
10776                        "Process cur broadcast " + r + ": NOT STARTED!");
10777                r.receiver = null;
10778                r.curApp = null;
10779                app.curReceiver = null;
10780            }
10781        }
10782
10783    }
10784
10785    static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
10786            Intent intent, int resultCode, String data, Bundle extras,
10787            boolean ordered, boolean sticky) throws RemoteException {
10788        // Send the intent to the receiver asynchronously using one-way binder calls.
10789        if (app != null && app.thread != null) {
10790            // If we have an app thread, do the call through that so it is
10791            // correctly ordered with other one-way calls.
10792            app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
10793                    data, extras, ordered, sticky);
10794        } else {
10795            receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
10796        }
10797    }
10798
10799    private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
10800            BroadcastFilter filter, boolean ordered) {
10801        boolean skip = false;
10802        if (filter.requiredPermission != null) {
10803            int perm = checkComponentPermission(filter.requiredPermission,
10804                    r.callingPid, r.callingUid, -1);
10805            if (perm != PackageManager.PERMISSION_GRANTED) {
10806                Slog.w(TAG, "Permission Denial: broadcasting "
10807                        + r.intent.toString()
10808                        + " from " + r.callerPackage + " (pid="
10809                        + r.callingPid + ", uid=" + r.callingUid + ")"
10810                        + " requires " + filter.requiredPermission
10811                        + " due to registered receiver " + filter);
10812                skip = true;
10813            }
10814        }
10815        if (r.requiredPermission != null) {
10816            int perm = checkComponentPermission(r.requiredPermission,
10817                    filter.receiverList.pid, filter.receiverList.uid, -1);
10818            if (perm != PackageManager.PERMISSION_GRANTED) {
10819                Slog.w(TAG, "Permission Denial: receiving "
10820                        + r.intent.toString()
10821                        + " to " + filter.receiverList.app
10822                        + " (pid=" + filter.receiverList.pid
10823                        + ", uid=" + filter.receiverList.uid + ")"
10824                        + " requires " + r.requiredPermission
10825                        + " due to sender " + r.callerPackage
10826                        + " (uid " + r.callingUid + ")");
10827                skip = true;
10828            }
10829        }
10830
10831        if (!skip) {
10832            // If this is not being sent as an ordered broadcast, then we
10833            // don't want to touch the fields that keep track of the current
10834            // state of ordered broadcasts.
10835            if (ordered) {
10836                r.receiver = filter.receiverList.receiver.asBinder();
10837                r.curFilter = filter;
10838                filter.receiverList.curBroadcast = r;
10839                r.state = BroadcastRecord.CALL_IN_RECEIVE;
10840                if (filter.receiverList.app != null) {
10841                    // Bump hosting application to no longer be in background
10842                    // scheduling class.  Note that we can't do that if there
10843                    // isn't an app...  but we can only be in that case for
10844                    // things that directly call the IActivityManager API, which
10845                    // are already core system stuff so don't matter for this.
10846                    r.curApp = filter.receiverList.app;
10847                    filter.receiverList.app.curReceiver = r;
10848                    updateOomAdjLocked();
10849                }
10850            }
10851            try {
10852                if (DEBUG_BROADCAST_LIGHT) {
10853                    int seq = r.intent.getIntExtra("seq", -1);
10854                    Slog.i(TAG, "Delivering to " + filter
10855                            + " (seq=" + seq + "): " + r);
10856                }
10857                performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
10858                    new Intent(r.intent), r.resultCode,
10859                    r.resultData, r.resultExtras, r.ordered, r.initialSticky);
10860                if (ordered) {
10861                    r.state = BroadcastRecord.CALL_DONE_RECEIVE;
10862                }
10863            } catch (RemoteException e) {
10864                Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
10865                if (ordered) {
10866                    r.receiver = null;
10867                    r.curFilter = null;
10868                    filter.receiverList.curBroadcast = null;
10869                    if (filter.receiverList.app != null) {
10870                        filter.receiverList.app.curReceiver = null;
10871                    }
10872                }
10873            }
10874        }
10875    }
10876
10877    private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
10878        if (r.callingUid < 0) {
10879            // This was from a registerReceiver() call; ignore it.
10880            return;
10881        }
10882        System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
10883                MAX_BROADCAST_HISTORY-1);
10884        r.finishTime = SystemClock.uptimeMillis();
10885        mBroadcastHistory[0] = r;
10886    }
10887
10888    private final void processNextBroadcast(boolean fromMsg) {
10889        synchronized(this) {
10890            BroadcastRecord r;
10891
10892            if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
10893                    + mParallelBroadcasts.size() + " broadcasts, "
10894                    + mOrderedBroadcasts.size() + " ordered broadcasts");
10895
10896            updateCpuStats();
10897
10898            if (fromMsg) {
10899                mBroadcastsScheduled = false;
10900            }
10901
10902            // First, deliver any non-serialized broadcasts right away.
10903            while (mParallelBroadcasts.size() > 0) {
10904                r = mParallelBroadcasts.remove(0);
10905                r.dispatchTime = SystemClock.uptimeMillis();
10906                final int N = r.receivers.size();
10907                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
10908                        + r);
10909                for (int i=0; i<N; i++) {
10910                    Object target = r.receivers.get(i);
10911                    if (DEBUG_BROADCAST)  Slog.v(TAG,
10912                            "Delivering non-ordered to registered "
10913                            + target + ": " + r);
10914                    deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
10915                }
10916                addBroadcastToHistoryLocked(r);
10917                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
10918                        + r);
10919            }
10920
10921            // Now take care of the next serialized one...
10922
10923            // If we are waiting for a process to come up to handle the next
10924            // broadcast, then do nothing at this point.  Just in case, we
10925            // check that the process we're waiting for still exists.
10926            if (mPendingBroadcast != null) {
10927                if (DEBUG_BROADCAST_LIGHT) {
10928                    Slog.v(TAG, "processNextBroadcast: waiting for "
10929                            + mPendingBroadcast.curApp);
10930                }
10931
10932                boolean isDead;
10933                synchronized (mPidsSelfLocked) {
10934                    isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
10935                }
10936                if (!isDead) {
10937                    // It's still alive, so keep waiting
10938                    return;
10939                } else {
10940                    Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
10941                            + " died before responding to broadcast");
10942                    mPendingBroadcast.state = BroadcastRecord.IDLE;
10943                    mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
10944                    mPendingBroadcast = null;
10945                }
10946            }
10947
10948            boolean looped = false;
10949
10950            do {
10951                if (mOrderedBroadcasts.size() == 0) {
10952                    // No more broadcasts pending, so all done!
10953                    scheduleAppGcsLocked();
10954                    if (looped) {
10955                        // If we had finished the last ordered broadcast, then
10956                        // make sure all processes have correct oom and sched
10957                        // adjustments.
10958                        updateOomAdjLocked();
10959                    }
10960                    return;
10961                }
10962                r = mOrderedBroadcasts.get(0);
10963                boolean forceReceive = false;
10964
10965                // Ensure that even if something goes awry with the timeout
10966                // detection, we catch "hung" broadcasts here, discard them,
10967                // and continue to make progress.
10968                //
10969                // This is only done if the system is ready so that PRE_BOOT_COMPLETED
10970                // receivers don't get executed with timeouts. They're intended for
10971                // one time heavy lifting after system upgrades and can take
10972                // significant amounts of time.
10973                int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
10974                if (mProcessesReady && r.dispatchTime > 0) {
10975                    long now = SystemClock.uptimeMillis();
10976                    if ((numReceivers > 0) &&
10977                            (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
10978                        Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
10979                                + " now=" + now
10980                                + " dispatchTime=" + r.dispatchTime
10981                                + " startTime=" + r.receiverTime
10982                                + " intent=" + r.intent
10983                                + " numReceivers=" + numReceivers
10984                                + " nextReceiver=" + r.nextReceiver
10985                                + " state=" + r.state);
10986                        broadcastTimeoutLocked(false); // forcibly finish this broadcast
10987                        forceReceive = true;
10988                        r.state = BroadcastRecord.IDLE;
10989                    }
10990                }
10991
10992                if (r.state != BroadcastRecord.IDLE) {
10993                    if (DEBUG_BROADCAST) Slog.d(TAG,
10994                            "processNextBroadcast() called when not idle (state="
10995                            + r.state + ")");
10996                    return;
10997                }
10998
10999                if (r.receivers == null || r.nextReceiver >= numReceivers
11000                        || r.resultAbort || forceReceive) {
11001                    // No more receivers for this broadcast!  Send the final
11002                    // result if requested...
11003                    if (r.resultTo != null) {
11004                        try {
11005                            if (DEBUG_BROADCAST) {
11006                                int seq = r.intent.getIntExtra("seq", -1);
11007                                Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
11008                                        + " seq=" + seq + " app=" + r.callerApp);
11009                            }
11010                            performReceiveLocked(r.callerApp, r.resultTo,
11011                                new Intent(r.intent), r.resultCode,
11012                                r.resultData, r.resultExtras, false, false);
11013                            // Set this to null so that the reference
11014                            // (local and remote) isnt kept in the mBroadcastHistory.
11015                            r.resultTo = null;
11016                        } catch (RemoteException e) {
11017                            Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
11018                        }
11019                    }
11020
11021                    if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
11022                    cancelBroadcastTimeoutLocked();
11023
11024                    if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
11025                            + r);
11026
11027                    // ... and on to the next...
11028                    addBroadcastToHistoryLocked(r);
11029                    mOrderedBroadcasts.remove(0);
11030                    r = null;
11031                    looped = true;
11032                    continue;
11033                }
11034            } while (r == null);
11035
11036            // Get the next receiver...
11037            int recIdx = r.nextReceiver++;
11038
11039            // Keep track of when this receiver started, and make sure there
11040            // is a timeout message pending to kill it if need be.
11041            r.receiverTime = SystemClock.uptimeMillis();
11042            if (recIdx == 0) {
11043                r.dispatchTime = r.receiverTime;
11044
11045                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
11046                        + r);
11047            }
11048            if (! mPendingBroadcastTimeoutMessage) {
11049                long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11050                if (DEBUG_BROADCAST) Slog.v(TAG,
11051                        "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
11052                setBroadcastTimeoutLocked(timeoutTime);
11053            }
11054
11055            Object nextReceiver = r.receivers.get(recIdx);
11056            if (nextReceiver instanceof BroadcastFilter) {
11057                // Simple case: this is a registered receiver who gets
11058                // a direct call.
11059                BroadcastFilter filter = (BroadcastFilter)nextReceiver;
11060                if (DEBUG_BROADCAST)  Slog.v(TAG,
11061                        "Delivering ordered to registered "
11062                        + filter + ": " + r);
11063                deliverToRegisteredReceiverLocked(r, filter, r.ordered);
11064                if (r.receiver == null || !r.ordered) {
11065                    // The receiver has already finished, so schedule to
11066                    // process the next one.
11067                    if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
11068                            + r.ordered + " receiver=" + r.receiver);
11069                    r.state = BroadcastRecord.IDLE;
11070                    scheduleBroadcastsLocked();
11071                }
11072                return;
11073            }
11074
11075            // Hard case: need to instantiate the receiver, possibly
11076            // starting its application process to host it.
11077
11078            ResolveInfo info =
11079                (ResolveInfo)nextReceiver;
11080
11081            boolean skip = false;
11082            int perm = checkComponentPermission(info.activityInfo.permission,
11083                    r.callingPid, r.callingUid,
11084                    info.activityInfo.exported
11085                            ? -1 : info.activityInfo.applicationInfo.uid);
11086            if (perm != PackageManager.PERMISSION_GRANTED) {
11087                Slog.w(TAG, "Permission Denial: broadcasting "
11088                        + r.intent.toString()
11089                        + " from " + r.callerPackage + " (pid=" + r.callingPid
11090                        + ", uid=" + r.callingUid + ")"
11091                        + " requires " + info.activityInfo.permission
11092                        + " due to receiver " + info.activityInfo.packageName
11093                        + "/" + info.activityInfo.name);
11094                skip = true;
11095            }
11096            if (r.callingUid != Process.SYSTEM_UID &&
11097                r.requiredPermission != null) {
11098                try {
11099                    perm = AppGlobals.getPackageManager().
11100                            checkPermission(r.requiredPermission,
11101                                    info.activityInfo.applicationInfo.packageName);
11102                } catch (RemoteException e) {
11103                    perm = PackageManager.PERMISSION_DENIED;
11104                }
11105                if (perm != PackageManager.PERMISSION_GRANTED) {
11106                    Slog.w(TAG, "Permission Denial: receiving "
11107                            + r.intent + " to "
11108                            + info.activityInfo.applicationInfo.packageName
11109                            + " requires " + r.requiredPermission
11110                            + " due to sender " + r.callerPackage
11111                            + " (uid " + r.callingUid + ")");
11112                    skip = true;
11113                }
11114            }
11115            if (r.curApp != null && r.curApp.crashing) {
11116                // If the target process is crashing, just skip it.
11117                if (DEBUG_BROADCAST)  Slog.v(TAG,
11118                        "Skipping deliver ordered " + r + " to " + r.curApp
11119                        + ": process crashing");
11120                skip = true;
11121            }
11122
11123            if (skip) {
11124                if (DEBUG_BROADCAST)  Slog.v(TAG,
11125                        "Skipping delivery of ordered " + r + " for whatever reason");
11126                r.receiver = null;
11127                r.curFilter = null;
11128                r.state = BroadcastRecord.IDLE;
11129                scheduleBroadcastsLocked();
11130                return;
11131            }
11132
11133            r.state = BroadcastRecord.APP_RECEIVE;
11134            String targetProcess = info.activityInfo.processName;
11135            r.curComponent = new ComponentName(
11136                    info.activityInfo.applicationInfo.packageName,
11137                    info.activityInfo.name);
11138            r.curReceiver = info.activityInfo;
11139
11140            // Is this receiver's application already running?
11141            ProcessRecord app = getProcessRecordLocked(targetProcess,
11142                    info.activityInfo.applicationInfo.uid);
11143            if (app != null && app.thread != null) {
11144                try {
11145                    processCurBroadcastLocked(r, app);
11146                    return;
11147                } catch (RemoteException e) {
11148                    Slog.w(TAG, "Exception when sending broadcast to "
11149                          + r.curComponent, e);
11150                }
11151
11152                // If a dead object exception was thrown -- fall through to
11153                // restart the application.
11154            }
11155
11156            // Not running -- get it started, to be executed when the app comes up.
11157            if (DEBUG_BROADCAST)  Slog.v(TAG,
11158                    "Need to start app " + targetProcess + " for broadcast " + r);
11159            if ((r.curApp=startProcessLocked(targetProcess,
11160                    info.activityInfo.applicationInfo, true,
11161                    r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
11162                    "broadcast", r.curComponent,
11163                    (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
11164                            == null) {
11165                // Ah, this recipient is unavailable.  Finish it if necessary,
11166                // and mark the broadcast record as ready for the next.
11167                Slog.w(TAG, "Unable to launch app "
11168                        + info.activityInfo.applicationInfo.packageName + "/"
11169                        + info.activityInfo.applicationInfo.uid + " for broadcast "
11170                        + r.intent + ": process is bad");
11171                logBroadcastReceiverDiscardLocked(r);
11172                finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11173                        r.resultExtras, r.resultAbort, true);
11174                scheduleBroadcastsLocked();
11175                r.state = BroadcastRecord.IDLE;
11176                return;
11177            }
11178
11179            mPendingBroadcast = r;
11180            mPendingBroadcastRecvIndex = recIdx;
11181        }
11182    }
11183
11184    // =========================================================
11185    // INSTRUMENTATION
11186    // =========================================================
11187
11188    public boolean startInstrumentation(ComponentName className,
11189            String profileFile, int flags, Bundle arguments,
11190            IInstrumentationWatcher watcher) {
11191        // Refuse possible leaked file descriptors
11192        if (arguments != null && arguments.hasFileDescriptors()) {
11193            throw new IllegalArgumentException("File descriptors passed in Bundle");
11194        }
11195
11196        synchronized(this) {
11197            InstrumentationInfo ii = null;
11198            ApplicationInfo ai = null;
11199            try {
11200                ii = mContext.getPackageManager().getInstrumentationInfo(
11201                    className, STOCK_PM_FLAGS);
11202                ai = mContext.getPackageManager().getApplicationInfo(
11203                    ii.targetPackage, STOCK_PM_FLAGS);
11204            } catch (PackageManager.NameNotFoundException e) {
11205            }
11206            if (ii == null) {
11207                reportStartInstrumentationFailure(watcher, className,
11208                        "Unable to find instrumentation info for: " + className);
11209                return false;
11210            }
11211            if (ai == null) {
11212                reportStartInstrumentationFailure(watcher, className,
11213                        "Unable to find instrumentation target package: " + ii.targetPackage);
11214                return false;
11215            }
11216
11217            int match = mContext.getPackageManager().checkSignatures(
11218                    ii.targetPackage, ii.packageName);
11219            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11220                String msg = "Permission Denial: starting instrumentation "
11221                        + className + " from pid="
11222                        + Binder.getCallingPid()
11223                        + ", uid=" + Binder.getCallingPid()
11224                        + " not allowed because package " + ii.packageName
11225                        + " does not have a signature matching the target "
11226                        + ii.targetPackage;
11227                reportStartInstrumentationFailure(watcher, className, msg);
11228                throw new SecurityException(msg);
11229            }
11230
11231            final long origId = Binder.clearCallingIdentity();
11232            forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
11233            ProcessRecord app = addAppLocked(ai);
11234            app.instrumentationClass = className;
11235            app.instrumentationInfo = ai;
11236            app.instrumentationProfileFile = profileFile;
11237            app.instrumentationArguments = arguments;
11238            app.instrumentationWatcher = watcher;
11239            app.instrumentationResultClass = className;
11240            Binder.restoreCallingIdentity(origId);
11241        }
11242
11243        return true;
11244    }
11245
11246    /**
11247     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11248     * error to the logs, but if somebody is watching, send the report there too.  This enables
11249     * the "am" command to report errors with more information.
11250     *
11251     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11252     * @param cn The component name of the instrumentation.
11253     * @param report The error report.
11254     */
11255    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11256            ComponentName cn, String report) {
11257        Slog.w(TAG, report);
11258        try {
11259            if (watcher != null) {
11260                Bundle results = new Bundle();
11261                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11262                results.putString("Error", report);
11263                watcher.instrumentationStatus(cn, -1, results);
11264            }
11265        } catch (RemoteException e) {
11266            Slog.w(TAG, e);
11267        }
11268    }
11269
11270    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11271        if (app.instrumentationWatcher != null) {
11272            try {
11273                // NOTE:  IInstrumentationWatcher *must* be oneway here
11274                app.instrumentationWatcher.instrumentationFinished(
11275                    app.instrumentationClass,
11276                    resultCode,
11277                    results);
11278            } catch (RemoteException e) {
11279            }
11280        }
11281        app.instrumentationWatcher = null;
11282        app.instrumentationClass = null;
11283        app.instrumentationInfo = null;
11284        app.instrumentationProfileFile = null;
11285        app.instrumentationArguments = null;
11286
11287        forceStopPackageLocked(app.processName, -1, false, false, true);
11288    }
11289
11290    public void finishInstrumentation(IApplicationThread target,
11291            int resultCode, Bundle results) {
11292        // Refuse possible leaked file descriptors
11293        if (results != null && results.hasFileDescriptors()) {
11294            throw new IllegalArgumentException("File descriptors passed in Intent");
11295        }
11296
11297        synchronized(this) {
11298            ProcessRecord app = getRecordForAppLocked(target);
11299            if (app == null) {
11300                Slog.w(TAG, "finishInstrumentation: no app for " + target);
11301                return;
11302            }
11303            final long origId = Binder.clearCallingIdentity();
11304            finishInstrumentationLocked(app, resultCode, results);
11305            Binder.restoreCallingIdentity(origId);
11306        }
11307    }
11308
11309    // =========================================================
11310    // CONFIGURATION
11311    // =========================================================
11312
11313    public ConfigurationInfo getDeviceConfigurationInfo() {
11314        ConfigurationInfo config = new ConfigurationInfo();
11315        synchronized (this) {
11316            config.reqTouchScreen = mConfiguration.touchscreen;
11317            config.reqKeyboardType = mConfiguration.keyboard;
11318            config.reqNavigation = mConfiguration.navigation;
11319            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11320                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
11321                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11322            }
11323            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11324                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
11325                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11326            }
11327            config.reqGlEsVersion = GL_ES_VERSION;
11328        }
11329        return config;
11330    }
11331
11332    public Configuration getConfiguration() {
11333        Configuration ci;
11334        synchronized(this) {
11335            ci = new Configuration(mConfiguration);
11336        }
11337        return ci;
11338    }
11339
11340    public void updateConfiguration(Configuration values) {
11341        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11342                "updateConfiguration()");
11343
11344        synchronized(this) {
11345            if (values == null && mWindowManager != null) {
11346                // sentinel: fetch the current configuration from the window manager
11347                values = mWindowManager.computeNewConfiguration();
11348            }
11349
11350            final long origId = Binder.clearCallingIdentity();
11351            updateConfigurationLocked(values, null);
11352            Binder.restoreCallingIdentity(origId);
11353        }
11354    }
11355
11356    /**
11357     * Do either or both things: (1) change the current configuration, and (2)
11358     * make sure the given activity is running with the (now) current
11359     * configuration.  Returns true if the activity has been left running, or
11360     * false if <var>starting</var> is being destroyed to match the new
11361     * configuration.
11362     */
11363    public boolean updateConfigurationLocked(Configuration values,
11364            ActivityRecord starting) {
11365        int changes = 0;
11366
11367        boolean kept = true;
11368
11369        if (values != null) {
11370            Configuration newConfig = new Configuration(mConfiguration);
11371            changes = newConfig.updateFrom(values);
11372            if (changes != 0) {
11373                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
11374                    Slog.i(TAG, "Updating configuration to: " + values);
11375                }
11376
11377                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
11378
11379                if (values.locale != null) {
11380                    saveLocaleLocked(values.locale,
11381                                     !values.locale.equals(mConfiguration.locale),
11382                                     values.userSetLocale);
11383                }
11384
11385                mConfigurationSeq++;
11386                if (mConfigurationSeq <= 0) {
11387                    mConfigurationSeq = 1;
11388                }
11389                newConfig.seq = mConfigurationSeq;
11390                mConfiguration = newConfig;
11391                Slog.i(TAG, "Config changed: " + newConfig);
11392
11393                AttributeCache ac = AttributeCache.instance();
11394                if (ac != null) {
11395                    ac.updateConfiguration(mConfiguration);
11396                }
11397
11398                if (Settings.System.hasInterestingConfigurationChanges(changes)) {
11399                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11400                    msg.obj = new Configuration(mConfiguration);
11401                    mHandler.sendMessage(msg);
11402                }
11403
11404                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11405                    ProcessRecord app = mLruProcesses.get(i);
11406                    try {
11407                        if (app.thread != null) {
11408                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
11409                                    + app.processName + " new config " + mConfiguration);
11410                            app.thread.scheduleConfigurationChanged(mConfiguration);
11411                        }
11412                    } catch (Exception e) {
11413                    }
11414                }
11415                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
11416                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11417                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
11418                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11419                        null, false, false, MY_PID, Process.SYSTEM_UID);
11420                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
11421                    broadcastIntentLocked(null, null,
11422                            new Intent(Intent.ACTION_LOCALE_CHANGED),
11423                            null, null, 0, null, null,
11424                            null, false, false, MY_PID, Process.SYSTEM_UID);
11425                }
11426            }
11427        }
11428
11429        if (changes != 0 && starting == null) {
11430            // If the configuration changed, and the caller is not already
11431            // in the process of starting an activity, then find the top
11432            // activity to check if its configuration needs to change.
11433            starting = mMainStack.topRunningActivityLocked(null);
11434        }
11435
11436        if (starting != null) {
11437            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
11438            if (kept) {
11439                // If this didn't result in the starting activity being
11440                // destroyed, then we need to make sure at this point that all
11441                // other activities are made visible.
11442                if (DEBUG_SWITCH) Slog.i(TAG, "Config didn't destroy " + starting
11443                        + ", ensuring others are correct.");
11444                mMainStack.ensureActivitiesVisibleLocked(starting, changes);
11445            }
11446        }
11447
11448        if (values != null && mWindowManager != null) {
11449            mWindowManager.setNewConfiguration(mConfiguration);
11450        }
11451
11452        return kept;
11453    }
11454
11455    /**
11456     * Save the locale.  You must be inside a synchronized (this) block.
11457     */
11458    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
11459        if(isDiff) {
11460            SystemProperties.set("user.language", l.getLanguage());
11461            SystemProperties.set("user.region", l.getCountry());
11462        }
11463
11464        if(isPersist) {
11465            SystemProperties.set("persist.sys.language", l.getLanguage());
11466            SystemProperties.set("persist.sys.country", l.getCountry());
11467            SystemProperties.set("persist.sys.localevar", l.getVariant());
11468        }
11469    }
11470
11471    // =========================================================
11472    // LIFETIME MANAGEMENT
11473    // =========================================================
11474
11475    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
11476            ProcessRecord TOP_APP, boolean recursed) {
11477        if (mAdjSeq == app.adjSeq) {
11478            // This adjustment has already been computed.  If we are calling
11479            // from the top, we may have already computed our adjustment with
11480            // an earlier hidden adjustment that isn't really for us... if
11481            // so, use the new hidden adjustment.
11482            if (!recursed && app.hidden) {
11483                app.curAdj = hiddenAdj;
11484            }
11485            return app.curAdj;
11486        }
11487
11488        if (app.thread == null) {
11489            app.adjSeq = mAdjSeq;
11490            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
11491            return (app.curAdj=EMPTY_APP_ADJ);
11492        }
11493
11494        if (app.maxAdj <= FOREGROUND_APP_ADJ) {
11495            // The max adjustment doesn't allow this app to be anything
11496            // below foreground, so it is not worth doing work for it.
11497            app.adjType = "fixed";
11498            app.adjSeq = mAdjSeq;
11499            app.curRawAdj = app.maxAdj;
11500            app.keeping = true;
11501            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
11502            return (app.curAdj=app.maxAdj);
11503       }
11504
11505        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
11506        app.adjSource = null;
11507        app.adjTarget = null;
11508        app.keeping = false;
11509        app.empty = false;
11510        app.hidden = false;
11511
11512        // Determine the importance of the process, starting with most
11513        // important to least, and assign an appropriate OOM adjustment.
11514        int adj;
11515        int schedGroup;
11516        int N;
11517        if (app == TOP_APP) {
11518            // The last app on the list is the foreground app.
11519            adj = FOREGROUND_APP_ADJ;
11520            schedGroup = Process.THREAD_GROUP_DEFAULT;
11521            app.adjType = "top-activity";
11522        } else if (app.instrumentationClass != null) {
11523            // Don't want to kill running instrumentation.
11524            adj = FOREGROUND_APP_ADJ;
11525            schedGroup = Process.THREAD_GROUP_DEFAULT;
11526            app.adjType = "instrumentation";
11527        } else if (app.curReceiver != null ||
11528                (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
11529            // An app that is currently receiving a broadcast also
11530            // counts as being in the foreground.
11531            adj = FOREGROUND_APP_ADJ;
11532            schedGroup = Process.THREAD_GROUP_DEFAULT;
11533            app.adjType = "broadcast";
11534        } else if (app.executingServices.size() > 0) {
11535            // An app that is currently executing a service callback also
11536            // counts as being in the foreground.
11537            adj = FOREGROUND_APP_ADJ;
11538            schedGroup = Process.THREAD_GROUP_DEFAULT;
11539            app.adjType = "exec-service";
11540        } else if (app.foregroundServices) {
11541            // The user is aware of this app, so make it visible.
11542            adj = PERCEPTIBLE_APP_ADJ;
11543            schedGroup = Process.THREAD_GROUP_DEFAULT;
11544            app.adjType = "foreground-service";
11545        } else if (app.forcingToForeground != null) {
11546            // The user is aware of this app, so make it visible.
11547            adj = PERCEPTIBLE_APP_ADJ;
11548            schedGroup = Process.THREAD_GROUP_DEFAULT;
11549            app.adjType = "force-foreground";
11550            app.adjSource = app.forcingToForeground;
11551        } else if (app == mHeavyWeightProcess) {
11552            // We don't want to kill the current heavy-weight process.
11553            adj = HEAVY_WEIGHT_APP_ADJ;
11554            schedGroup = Process.THREAD_GROUP_DEFAULT;
11555            app.adjType = "heavy";
11556        } else if (app == mHomeProcess) {
11557            // This process is hosting what we currently consider to be the
11558            // home app, so we don't want to let it go into the background.
11559            adj = HOME_APP_ADJ;
11560            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
11561            app.adjType = "home";
11562        } else if ((N=app.activities.size()) != 0) {
11563            // This app is in the background with paused activities.
11564            app.hidden = true;
11565            adj = hiddenAdj;
11566            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
11567            app.adjType = "bg-activities";
11568            N = app.activities.size();
11569            for (int j=0; j<N; j++) {
11570                if (app.activities.get(j).visible) {
11571                    // This app has a visible activity!
11572                    app.hidden = false;
11573                    adj = VISIBLE_APP_ADJ;
11574                    schedGroup = Process.THREAD_GROUP_DEFAULT;
11575                    app.adjType = "visible";
11576                    break;
11577                }
11578            }
11579        } else {
11580            // A very not-needed process.  If this is lower in the lru list,
11581            // we will push it in to the empty bucket.
11582            app.hidden = true;
11583            app.empty = true;
11584            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
11585            adj = hiddenAdj;
11586            app.adjType = "bg-empty";
11587        }
11588
11589        //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
11590
11591        // By default, we use the computed adjustment.  It may be changed if
11592        // there are applications dependent on our services or providers, but
11593        // this gives us a baseline and makes sure we don't get into an
11594        // infinite recursion.
11595        app.adjSeq = mAdjSeq;
11596        app.curRawAdj = adj;
11597
11598        if (mBackupTarget != null && app == mBackupTarget.app) {
11599            // If possible we want to avoid killing apps while they're being backed up
11600            if (adj > BACKUP_APP_ADJ) {
11601                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
11602                adj = BACKUP_APP_ADJ;
11603                app.adjType = "backup";
11604                app.hidden = false;
11605            }
11606        }
11607
11608        if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
11609                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
11610            final long now = SystemClock.uptimeMillis();
11611            // This process is more important if the top activity is
11612            // bound to the service.
11613            Iterator<ServiceRecord> jt = app.services.iterator();
11614            while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
11615                ServiceRecord s = jt.next();
11616                if (s.startRequested) {
11617                    if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
11618                        // This service has seen some activity within
11619                        // recent memory, so we will keep its process ahead
11620                        // of the background processes.
11621                        if (adj > SECONDARY_SERVER_ADJ) {
11622                            adj = SECONDARY_SERVER_ADJ;
11623                            app.adjType = "started-services";
11624                            app.hidden = false;
11625                        }
11626                    }
11627                    // If we have let the service slide into the background
11628                    // state, still have some text describing what it is doing
11629                    // even though the service no longer has an impact.
11630                    if (adj > SECONDARY_SERVER_ADJ) {
11631                        app.adjType = "started-bg-services";
11632                    }
11633                    // Don't kill this process because it is doing work; it
11634                    // has said it is doing work.
11635                    app.keeping = true;
11636                }
11637                if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
11638                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
11639                    Iterator<ArrayList<ConnectionRecord>> kt
11640                            = s.connections.values().iterator();
11641                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
11642                        ArrayList<ConnectionRecord> clist = kt.next();
11643                        for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
11644                            // XXX should compute this based on the max of
11645                            // all connected clients.
11646                            ConnectionRecord cr = clist.get(i);
11647                            if (cr.binding.client == app) {
11648                                // Binding to ourself is not interesting.
11649                                continue;
11650                            }
11651                            if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
11652                                ProcessRecord client = cr.binding.client;
11653                                int myHiddenAdj = hiddenAdj;
11654                                if (myHiddenAdj > client.hiddenAdj) {
11655                                    if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
11656                                        myHiddenAdj = client.hiddenAdj;
11657                                    } else {
11658                                        myHiddenAdj = VISIBLE_APP_ADJ;
11659                                    }
11660                                }
11661                                int clientAdj = computeOomAdjLocked(
11662                                    client, myHiddenAdj, TOP_APP, true);
11663                                if (adj > clientAdj) {
11664                                    adj = clientAdj >= VISIBLE_APP_ADJ
11665                                            ? clientAdj : VISIBLE_APP_ADJ;
11666                                    if (!client.hidden) {
11667                                        app.hidden = false;
11668                                    }
11669                                    if (client.keeping) {
11670                                        app.keeping = true;
11671                                    }
11672                                    app.adjType = "service";
11673                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
11674                                            .REASON_SERVICE_IN_USE;
11675                                    app.adjSource = cr.binding.client;
11676                                    app.adjTarget = s.name;
11677                                }
11678                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
11679                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
11680                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
11681                                    }
11682                                }
11683                            }
11684                            ActivityRecord a = cr.activity;
11685                            //if (a != null) {
11686                            //    Slog.i(TAG, "Connection to " + a ": state=" + a.state);
11687                            //}
11688                            if (a != null && adj > FOREGROUND_APP_ADJ &&
11689                                    (a.state == ActivityState.RESUMED
11690                                     || a.state == ActivityState.PAUSING)) {
11691                                adj = FOREGROUND_APP_ADJ;
11692                                schedGroup = Process.THREAD_GROUP_DEFAULT;
11693                                app.hidden = false;
11694                                app.adjType = "service";
11695                                app.adjTypeCode = ActivityManager.RunningAppProcessInfo
11696                                        .REASON_SERVICE_IN_USE;
11697                                app.adjSource = a;
11698                                app.adjTarget = s.name;
11699                            }
11700                        }
11701                    }
11702                }
11703            }
11704
11705            // Finally, if this process has active services running in it, we
11706            // would like to avoid killing it unless it would prevent the current
11707            // application from running.  By default we put the process in
11708            // with the rest of the background processes; as we scan through
11709            // its services we may bump it up from there.
11710            if (adj > hiddenAdj) {
11711                adj = hiddenAdj;
11712                app.hidden = false;
11713                app.adjType = "bg-services";
11714            }
11715        }
11716
11717        if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
11718                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
11719            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
11720            while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
11721                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
11722                ContentProviderRecord cpr = jt.next();
11723                if (cpr.clients.size() != 0) {
11724                    Iterator<ProcessRecord> kt = cpr.clients.iterator();
11725                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
11726                        ProcessRecord client = kt.next();
11727                        if (client == app) {
11728                            // Being our own client is not interesting.
11729                            continue;
11730                        }
11731                        int myHiddenAdj = hiddenAdj;
11732                        if (myHiddenAdj > client.hiddenAdj) {
11733                            if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
11734                                myHiddenAdj = client.hiddenAdj;
11735                            } else {
11736                                myHiddenAdj = FOREGROUND_APP_ADJ;
11737                            }
11738                        }
11739                        int clientAdj = computeOomAdjLocked(
11740                            client, myHiddenAdj, TOP_APP, true);
11741                        if (adj > clientAdj) {
11742                            adj = clientAdj > FOREGROUND_APP_ADJ
11743                                    ? clientAdj : FOREGROUND_APP_ADJ;
11744                            if (!client.hidden) {
11745                                app.hidden = false;
11746                            }
11747                            if (client.keeping) {
11748                                app.keeping = true;
11749                            }
11750                            app.adjType = "provider";
11751                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
11752                                    .REASON_PROVIDER_IN_USE;
11753                            app.adjSource = client;
11754                            app.adjTarget = cpr.name;
11755                        }
11756                        if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
11757                            schedGroup = Process.THREAD_GROUP_DEFAULT;
11758                        }
11759                    }
11760                }
11761                // If the provider has external (non-framework) process
11762                // dependencies, ensure that its adjustment is at least
11763                // FOREGROUND_APP_ADJ.
11764                if (cpr.externals != 0) {
11765                    if (adj > FOREGROUND_APP_ADJ) {
11766                        adj = FOREGROUND_APP_ADJ;
11767                        schedGroup = Process.THREAD_GROUP_DEFAULT;
11768                        app.hidden = false;
11769                        app.keeping = true;
11770                        app.adjType = "provider";
11771                        app.adjTarget = cpr.name;
11772                    }
11773                }
11774            }
11775        }
11776
11777        app.curRawAdj = adj;
11778
11779        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
11780        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
11781        if (adj > app.maxAdj) {
11782            adj = app.maxAdj;
11783            if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
11784                schedGroup = Process.THREAD_GROUP_DEFAULT;
11785            }
11786        }
11787        if (adj < HIDDEN_APP_MIN_ADJ) {
11788            app.keeping = true;
11789        }
11790
11791        app.curAdj = adj;
11792        app.curSchedGroup = schedGroup;
11793
11794        return adj;
11795    }
11796
11797    /**
11798     * Ask a given process to GC right now.
11799     */
11800    final void performAppGcLocked(ProcessRecord app) {
11801        try {
11802            app.lastRequestedGc = SystemClock.uptimeMillis();
11803            if (app.thread != null) {
11804                if (app.reportLowMemory) {
11805                    app.reportLowMemory = false;
11806                    app.thread.scheduleLowMemory();
11807                } else {
11808                    app.thread.processInBackground();
11809                }
11810            }
11811        } catch (Exception e) {
11812            // whatever.
11813        }
11814    }
11815
11816    /**
11817     * Returns true if things are idle enough to perform GCs.
11818     */
11819    private final boolean canGcNowLocked() {
11820        return mParallelBroadcasts.size() == 0
11821                && mOrderedBroadcasts.size() == 0
11822                && (mSleeping || (mMainStack.mResumedActivity != null &&
11823                        mMainStack.mResumedActivity.idle));
11824    }
11825
11826    /**
11827     * Perform GCs on all processes that are waiting for it, but only
11828     * if things are idle.
11829     */
11830    final void performAppGcsLocked() {
11831        final int N = mProcessesToGc.size();
11832        if (N <= 0) {
11833            return;
11834        }
11835        if (canGcNowLocked()) {
11836            while (mProcessesToGc.size() > 0) {
11837                ProcessRecord proc = mProcessesToGc.remove(0);
11838                if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
11839                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
11840                            <= SystemClock.uptimeMillis()) {
11841                        // To avoid spamming the system, we will GC processes one
11842                        // at a time, waiting a few seconds between each.
11843                        performAppGcLocked(proc);
11844                        scheduleAppGcsLocked();
11845                        return;
11846                    } else {
11847                        // It hasn't been long enough since we last GCed this
11848                        // process...  put it in the list to wait for its time.
11849                        addProcessToGcListLocked(proc);
11850                        break;
11851                    }
11852                }
11853            }
11854
11855            scheduleAppGcsLocked();
11856        }
11857    }
11858
11859    /**
11860     * If all looks good, perform GCs on all processes waiting for them.
11861     */
11862    final void performAppGcsIfAppropriateLocked() {
11863        if (canGcNowLocked()) {
11864            performAppGcsLocked();
11865            return;
11866        }
11867        // Still not idle, wait some more.
11868        scheduleAppGcsLocked();
11869    }
11870
11871    /**
11872     * Schedule the execution of all pending app GCs.
11873     */
11874    final void scheduleAppGcsLocked() {
11875        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
11876
11877        if (mProcessesToGc.size() > 0) {
11878            // Schedule a GC for the time to the next process.
11879            ProcessRecord proc = mProcessesToGc.get(0);
11880            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
11881
11882            long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
11883            long now = SystemClock.uptimeMillis();
11884            if (when < (now+GC_TIMEOUT)) {
11885                when = now + GC_TIMEOUT;
11886            }
11887            mHandler.sendMessageAtTime(msg, when);
11888        }
11889    }
11890
11891    /**
11892     * Add a process to the array of processes waiting to be GCed.  Keeps the
11893     * list in sorted order by the last GC time.  The process can't already be
11894     * on the list.
11895     */
11896    final void addProcessToGcListLocked(ProcessRecord proc) {
11897        boolean added = false;
11898        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
11899            if (mProcessesToGc.get(i).lastRequestedGc <
11900                    proc.lastRequestedGc) {
11901                added = true;
11902                mProcessesToGc.add(i+1, proc);
11903                break;
11904            }
11905        }
11906        if (!added) {
11907            mProcessesToGc.add(0, proc);
11908        }
11909    }
11910
11911    /**
11912     * Set up to ask a process to GC itself.  This will either do it
11913     * immediately, or put it on the list of processes to gc the next
11914     * time things are idle.
11915     */
11916    final void scheduleAppGcLocked(ProcessRecord app) {
11917        long now = SystemClock.uptimeMillis();
11918        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
11919            return;
11920        }
11921        if (!mProcessesToGc.contains(app)) {
11922            addProcessToGcListLocked(app);
11923            scheduleAppGcsLocked();
11924        }
11925    }
11926
11927    final void checkExcessivePowerUsageLocked(boolean doKills) {
11928        updateCpuStatsNow();
11929
11930        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11931        boolean doWakeKills = doKills;
11932        boolean doCpuKills = doKills;
11933        if (mLastPowerCheckRealtime == 0) {
11934            doWakeKills = false;
11935        }
11936        if (mLastPowerCheckUptime == 0) {
11937            doCpuKills = false;
11938        }
11939        if (stats.isScreenOn()) {
11940            doWakeKills = false;
11941        }
11942        final long curRealtime = SystemClock.elapsedRealtime();
11943        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
11944        final long curUptime = SystemClock.uptimeMillis();
11945        final long uptimeSince = curUptime - mLastPowerCheckUptime;
11946        mLastPowerCheckRealtime = curRealtime;
11947        mLastPowerCheckUptime = curUptime;
11948        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
11949            doWakeKills = false;
11950        }
11951        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
11952            doCpuKills = false;
11953        }
11954        int i = mLruProcesses.size();
11955        while (i > 0) {
11956            i--;
11957            ProcessRecord app = mLruProcesses.get(i);
11958            if (!app.keeping) {
11959                long wtime;
11960                synchronized (stats) {
11961                    wtime = stats.getProcessWakeTime(app.info.uid,
11962                            app.pid, curRealtime);
11963                }
11964                long wtimeUsed = wtime - app.lastWakeTime;
11965                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
11966                if (DEBUG_POWER) {
11967                    StringBuilder sb = new StringBuilder(128);
11968                    sb.append("Wake for ");
11969                    app.toShortString(sb);
11970                    sb.append(": over ");
11971                    TimeUtils.formatDuration(realtimeSince, sb);
11972                    sb.append(" used ");
11973                    TimeUtils.formatDuration(wtimeUsed, sb);
11974                    sb.append(" (");
11975                    sb.append((wtimeUsed*100)/realtimeSince);
11976                    sb.append("%)");
11977                    Slog.i(TAG, sb.toString());
11978                    sb.setLength(0);
11979                    sb.append("CPU for ");
11980                    app.toShortString(sb);
11981                    sb.append(": over ");
11982                    TimeUtils.formatDuration(uptimeSince, sb);
11983                    sb.append(" used ");
11984                    TimeUtils.formatDuration(cputimeUsed, sb);
11985                    sb.append(" (");
11986                    sb.append((cputimeUsed*100)/uptimeSince);
11987                    sb.append("%)");
11988                    Slog.i(TAG, sb.toString());
11989                }
11990                // If a process has held a wake lock for more
11991                // than 50% of the time during this period,
11992                // that sounds pad.  Kill!
11993                if (doWakeKills && realtimeSince > 0
11994                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
11995                    synchronized (stats) {
11996                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
11997                                realtimeSince, wtimeUsed);
11998                    }
11999                    Slog.w(TAG, "Excessive wake lock in " + app.processName
12000                            + " (pid " + app.pid + "): held " + wtimeUsed
12001                            + " during " + realtimeSince);
12002                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12003                            app.processName, app.setAdj, "excessive wake lock");
12004                    Process.killProcessQuiet(app.pid);
12005                } else if (doCpuKills && uptimeSince > 0
12006                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
12007                    synchronized (stats) {
12008                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12009                                uptimeSince, cputimeUsed);
12010                    }
12011                    Slog.w(TAG, "Excessive CPU in " + app.processName
12012                            + " (pid " + app.pid + "): used " + cputimeUsed
12013                            + " during " + uptimeSince);
12014                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12015                            app.processName, app.setAdj, "excessive cpu");
12016                    Process.killProcessQuiet(app.pid);
12017                } else {
12018                    app.lastWakeTime = wtime;
12019                    app.lastCpuTime = app.curCpuTime;
12020                }
12021            }
12022        }
12023    }
12024
12025    private final boolean updateOomAdjLocked(
12026        ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
12027        app.hiddenAdj = hiddenAdj;
12028
12029        if (app.thread == null) {
12030            return true;
12031        }
12032
12033        final boolean wasKeeping = app.keeping;
12034
12035        int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
12036
12037        if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
12038            if (app.curRawAdj != app.setRawAdj) {
12039                if (app.curRawAdj > FOREGROUND_APP_ADJ
12040                        && app.setRawAdj <= FOREGROUND_APP_ADJ) {
12041                    // If this app is transitioning from foreground to
12042                    // non-foreground, have it do a gc.
12043                    scheduleAppGcLocked(app);
12044                } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
12045                        && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
12046                    // Likewise do a gc when an app is moving in to the
12047                    // background (such as a service stopping).
12048                    scheduleAppGcLocked(app);
12049                }
12050
12051                if (wasKeeping && !app.keeping) {
12052                    // This app is no longer something we want to keep.  Note
12053                    // its current wake lock time to later know to kill it if
12054                    // it is not behaving well.
12055                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12056                    synchronized (stats) {
12057                        app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12058                                app.pid, SystemClock.elapsedRealtime());
12059                    }
12060                    app.lastCpuTime = app.curCpuTime;
12061                }
12062
12063                app.setRawAdj = app.curRawAdj;
12064            }
12065            if (adj != app.setAdj) {
12066                if (Process.setOomAdj(app.pid, adj)) {
12067                    if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
12068                        TAG, "Set app " + app.processName +
12069                        " oom adj to " + adj);
12070                    app.setAdj = adj;
12071                } else {
12072                    return false;
12073                }
12074            }
12075            if (app.setSchedGroup != app.curSchedGroup) {
12076                app.setSchedGroup = app.curSchedGroup;
12077                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
12078                        "Setting process group of " + app.processName
12079                        + " to " + app.curSchedGroup);
12080                if (true) {
12081                    long oldId = Binder.clearCallingIdentity();
12082                    try {
12083                        Process.setProcessGroup(app.pid, app.curSchedGroup);
12084                    } catch (Exception e) {
12085                        Slog.w(TAG, "Failed setting process group of " + app.pid
12086                                + " to " + app.curSchedGroup);
12087                        e.printStackTrace();
12088                    } finally {
12089                        Binder.restoreCallingIdentity(oldId);
12090                    }
12091                }
12092                if (false) {
12093                    if (app.thread != null) {
12094                        try {
12095                            app.thread.setSchedulingGroup(app.curSchedGroup);
12096                        } catch (RemoteException e) {
12097                        }
12098                    }
12099                }
12100            }
12101        }
12102
12103        return true;
12104    }
12105
12106    private final ActivityRecord resumedAppLocked() {
12107        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
12108        if (resumedActivity == null || resumedActivity.app == null) {
12109            resumedActivity = mMainStack.mPausingActivity;
12110            if (resumedActivity == null || resumedActivity.app == null) {
12111                resumedActivity = mMainStack.topRunningActivityLocked(null);
12112            }
12113        }
12114        return resumedActivity;
12115    }
12116
12117    private final boolean updateOomAdjLocked(ProcessRecord app) {
12118        final ActivityRecord TOP_ACT = resumedAppLocked();
12119        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12120        int curAdj = app.curAdj;
12121        final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
12122            && app.curAdj <= HIDDEN_APP_MAX_ADJ;
12123
12124        mAdjSeq++;
12125
12126        final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
12127        if (res) {
12128            final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
12129                && app.curAdj <= HIDDEN_APP_MAX_ADJ;
12130            if (nowHidden != wasHidden) {
12131                // Changed to/from hidden state, so apps after it in the LRU
12132                // list may also be changed.
12133                updateOomAdjLocked();
12134            }
12135        }
12136        return res;
12137    }
12138
12139    final boolean updateOomAdjLocked() {
12140        boolean didOomAdj = true;
12141        final ActivityRecord TOP_ACT = resumedAppLocked();
12142        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12143
12144        if (false) {
12145            RuntimeException e = new RuntimeException();
12146            e.fillInStackTrace();
12147            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
12148        }
12149
12150        mAdjSeq++;
12151
12152        // Let's determine how many processes we have running vs.
12153        // how many slots we have for background processes; we may want
12154        // to put multiple processes in a slot of there are enough of
12155        // them.
12156        int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
12157        int factor = (mLruProcesses.size()-4)/numSlots;
12158        if (factor < 1) factor = 1;
12159        int step = 0;
12160        int numHidden = 0;
12161
12162        // First try updating the OOM adjustment for each of the
12163        // application processes based on their current state.
12164        int i = mLruProcesses.size();
12165        int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
12166        while (i > 0) {
12167            i--;
12168            ProcessRecord app = mLruProcesses.get(i);
12169            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
12170            if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
12171                if (curHiddenAdj < EMPTY_APP_ADJ
12172                    && app.curAdj == curHiddenAdj) {
12173                    step++;
12174                    if (step >= factor) {
12175                        step = 0;
12176                        curHiddenAdj++;
12177                    }
12178                }
12179                if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
12180                    if (!app.killedBackground) {
12181                        numHidden++;
12182                        if (numHidden > MAX_HIDDEN_APPS) {
12183                            Slog.i(TAG, "No longer want " + app.processName
12184                                    + " (pid " + app.pid + "): hidden #" + numHidden);
12185                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12186                                    app.processName, app.setAdj, "too many background");
12187                            app.killedBackground = true;
12188                            Process.killProcessQuiet(app.pid);
12189                        }
12190                    }
12191                }
12192            } else {
12193                didOomAdj = false;
12194            }
12195        }
12196
12197        // If we return false, we will fall back on killing processes to
12198        // have a fixed limit.  Do this if a limit has been requested; else
12199        // only return false if one of the adjustments failed.
12200        return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
12201    }
12202
12203    final void trimApplications() {
12204        synchronized (this) {
12205            int i;
12206
12207            // First remove any unused application processes whose package
12208            // has been removed.
12209            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
12210                final ProcessRecord app = mRemovedProcesses.get(i);
12211                if (app.activities.size() == 0
12212                        && app.curReceiver == null && app.services.size() == 0) {
12213                    Slog.i(
12214                        TAG, "Exiting empty application process "
12215                        + app.processName + " ("
12216                        + (app.thread != null ? app.thread.asBinder() : null)
12217                        + ")\n");
12218                    if (app.pid > 0 && app.pid != MY_PID) {
12219                        Process.killProcess(app.pid);
12220                    } else {
12221                        try {
12222                            app.thread.scheduleExit();
12223                        } catch (Exception e) {
12224                            // Ignore exceptions.
12225                        }
12226                    }
12227                    cleanUpApplicationRecordLocked(app, false, -1);
12228                    mRemovedProcesses.remove(i);
12229
12230                    if (app.persistent) {
12231                        if (app.persistent) {
12232                            addAppLocked(app.info);
12233                        }
12234                    }
12235                }
12236            }
12237
12238            // Now try updating the OOM adjustment for each of the
12239            // application processes based on their current state.
12240            // If the setOomAdj() API is not supported, then go with our
12241            // back-up plan...
12242            if (!updateOomAdjLocked()) {
12243
12244                // Count how many processes are running services.
12245                int numServiceProcs = 0;
12246                for (i=mLruProcesses.size()-1; i>=0; i--) {
12247                    final ProcessRecord app = mLruProcesses.get(i);
12248
12249                    if (app.persistent || app.services.size() != 0
12250                            || app.curReceiver != null) {
12251                        // Don't count processes holding services against our
12252                        // maximum process count.
12253                        if (localLOGV) Slog.v(
12254                            TAG, "Not trimming app " + app + " with services: "
12255                            + app.services);
12256                        numServiceProcs++;
12257                    }
12258                }
12259
12260                int curMaxProcs = mProcessLimit;
12261                if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
12262                if (mAlwaysFinishActivities) {
12263                    curMaxProcs = 1;
12264                }
12265                curMaxProcs += numServiceProcs;
12266
12267                // Quit as many processes as we can to get down to the desired
12268                // process count.  First remove any processes that no longer
12269                // have activites running in them.
12270                for (   i=0;
12271                        i<mLruProcesses.size()
12272                            && mLruProcesses.size() > curMaxProcs;
12273                        i++) {
12274                    final ProcessRecord app = mLruProcesses.get(i);
12275                    // Quit an application only if it is not currently
12276                    // running any activities.
12277                    if (!app.persistent && app.activities.size() == 0
12278                            && app.curReceiver == null && app.services.size() == 0) {
12279                        Slog.i(
12280                            TAG, "Exiting empty application process "
12281                            + app.processName + " ("
12282                            + (app.thread != null ? app.thread.asBinder() : null)
12283                            + ")\n");
12284                        if (app.pid > 0 && app.pid != MY_PID) {
12285                            Process.killProcess(app.pid);
12286                        } else {
12287                            try {
12288                                app.thread.scheduleExit();
12289                            } catch (Exception e) {
12290                                // Ignore exceptions.
12291                            }
12292                        }
12293                        // todo: For now we assume the application is not buggy
12294                        // or evil, and will quit as a result of our request.
12295                        // Eventually we need to drive this off of the death
12296                        // notification, and kill the process if it takes too long.
12297                        cleanUpApplicationRecordLocked(app, false, i);
12298                        i--;
12299                    }
12300                }
12301
12302                // If we still have too many processes, now from the least
12303                // recently used process we start finishing activities.
12304                if (Config.LOGV) Slog.v(
12305                    TAG, "*** NOW HAVE " + mLruProcesses.size() +
12306                    " of " + curMaxProcs + " processes");
12307                for (   i=0;
12308                        i<mLruProcesses.size()
12309                            && mLruProcesses.size() > curMaxProcs;
12310                        i++) {
12311                    final ProcessRecord app = mLruProcesses.get(i);
12312                    // Quit the application only if we have a state saved for
12313                    // all of its activities.
12314                    boolean canQuit = !app.persistent && app.curReceiver == null
12315                        && app.services.size() == 0;
12316                    int NUMA = app.activities.size();
12317                    int j;
12318                    if (Config.LOGV) Slog.v(
12319                        TAG, "Looking to quit " + app.processName);
12320                    for (j=0; j<NUMA && canQuit; j++) {
12321                        ActivityRecord r = app.activities.get(j);
12322                        if (Config.LOGV) Slog.v(
12323                            TAG, "  " + r.intent.getComponent().flattenToShortString()
12324                            + ": frozen=" + r.haveState + ", visible=" + r.visible);
12325                        canQuit = (r.haveState || !r.stateNotNeeded)
12326                                && !r.visible && r.stopped;
12327                    }
12328                    if (canQuit) {
12329                        // Finish all of the activities, and then the app itself.
12330                        for (j=0; j<NUMA; j++) {
12331                            ActivityRecord r = app.activities.get(j);
12332                            if (!r.finishing) {
12333                                r.stack.destroyActivityLocked(r, false);
12334                            }
12335                            r.resultTo = null;
12336                        }
12337                        Slog.i(TAG, "Exiting application process "
12338                              + app.processName + " ("
12339                              + (app.thread != null ? app.thread.asBinder() : null)
12340                              + ")\n");
12341                        if (app.pid > 0 && app.pid != MY_PID) {
12342                            Process.killProcess(app.pid);
12343                        } else {
12344                            try {
12345                                app.thread.scheduleExit();
12346                            } catch (Exception e) {
12347                                // Ignore exceptions.
12348                            }
12349                        }
12350                        // todo: For now we assume the application is not buggy
12351                        // or evil, and will quit as a result of our request.
12352                        // Eventually we need to drive this off of the death
12353                        // notification, and kill the process if it takes too long.
12354                        cleanUpApplicationRecordLocked(app, false, i);
12355                        i--;
12356                        //dump();
12357                    }
12358                }
12359
12360            }
12361
12362            int curMaxActivities = MAX_ACTIVITIES;
12363            if (mAlwaysFinishActivities) {
12364                curMaxActivities = 1;
12365            }
12366
12367            // Finally, if there are too many activities now running, try to
12368            // finish as many as we can to get back down to the limit.
12369            for (   i=0;
12370                    i<mMainStack.mLRUActivities.size()
12371                        && mMainStack.mLRUActivities.size() > curMaxActivities;
12372                    i++) {
12373                final ActivityRecord r
12374                    = (ActivityRecord)mMainStack.mLRUActivities.get(i);
12375
12376                // We can finish this one if we have its icicle saved and
12377                // it is not persistent.
12378                if ((r.haveState || !r.stateNotNeeded) && !r.visible
12379                        && r.stopped && !r.finishing) {
12380                    final int origSize = mMainStack.mLRUActivities.size();
12381                    r.stack.destroyActivityLocked(r, true);
12382
12383                    // This will remove it from the LRU list, so keep
12384                    // our index at the same value.  Note that this check to
12385                    // see if the size changes is just paranoia -- if
12386                    // something unexpected happens, we don't want to end up
12387                    // in an infinite loop.
12388                    if (origSize > mMainStack.mLRUActivities.size()) {
12389                        i--;
12390                    }
12391                }
12392            }
12393        }
12394    }
12395
12396    /** This method sends the specified signal to each of the persistent apps */
12397    public void signalPersistentProcesses(int sig) throws RemoteException {
12398        if (sig != Process.SIGNAL_USR1) {
12399            throw new SecurityException("Only SIGNAL_USR1 is allowed");
12400        }
12401
12402        synchronized (this) {
12403            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
12404                    != PackageManager.PERMISSION_GRANTED) {
12405                throw new SecurityException("Requires permission "
12406                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
12407            }
12408
12409            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12410                ProcessRecord r = mLruProcesses.get(i);
12411                if (r.thread != null && r.persistent) {
12412                    Process.sendSignal(r.pid, sig);
12413                }
12414            }
12415        }
12416    }
12417
12418    public boolean profileControl(String process, boolean start,
12419            String path, ParcelFileDescriptor fd) throws RemoteException {
12420
12421        try {
12422            synchronized (this) {
12423                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
12424                // its own permission.
12425                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12426                        != PackageManager.PERMISSION_GRANTED) {
12427                    throw new SecurityException("Requires permission "
12428                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12429                }
12430
12431                if (start && fd == null) {
12432                    throw new IllegalArgumentException("null fd");
12433                }
12434
12435                ProcessRecord proc = null;
12436                try {
12437                    int pid = Integer.parseInt(process);
12438                    synchronized (mPidsSelfLocked) {
12439                        proc = mPidsSelfLocked.get(pid);
12440                    }
12441                } catch (NumberFormatException e) {
12442                }
12443
12444                if (proc == null) {
12445                    HashMap<String, SparseArray<ProcessRecord>> all
12446                            = mProcessNames.getMap();
12447                    SparseArray<ProcessRecord> procs = all.get(process);
12448                    if (procs != null && procs.size() > 0) {
12449                        proc = procs.valueAt(0);
12450                    }
12451                }
12452
12453                if (proc == null || proc.thread == null) {
12454                    throw new IllegalArgumentException("Unknown process: " + process);
12455                }
12456
12457                boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
12458                if (isSecure) {
12459                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12460                        throw new SecurityException("Process not debuggable: " + proc);
12461                    }
12462                }
12463
12464                proc.thread.profilerControl(start, path, fd);
12465                fd = null;
12466                return true;
12467            }
12468        } catch (RemoteException e) {
12469            throw new IllegalStateException("Process disappeared");
12470        } finally {
12471            if (fd != null) {
12472                try {
12473                    fd.close();
12474                } catch (IOException e) {
12475                }
12476            }
12477        }
12478    }
12479
12480    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
12481    public void monitor() {
12482        synchronized (this) { }
12483    }
12484}
12485