ActivityManagerService.java revision 599ca29986235e07f532c7b112507f6c39b5dba9
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.DialogInterface;
59import android.content.Intent;
60import android.content.IntentFilter;
61import android.content.IIntentReceiver;
62import android.content.IIntentSender;
63import android.content.IntentSender;
64import android.content.pm.ActivityInfo;
65import android.content.pm.ApplicationInfo;
66import android.content.pm.ConfigurationInfo;
67import android.content.pm.IPackageDataObserver;
68import android.content.pm.IPackageManager;
69import android.content.pm.InstrumentationInfo;
70import android.content.pm.PackageInfo;
71import android.content.pm.PackageManager;
72import android.content.pm.PathPermission;
73import android.content.pm.ProviderInfo;
74import android.content.pm.ResolveInfo;
75import android.content.pm.ServiceInfo;
76import android.content.pm.PackageManager.NameNotFoundException;
77import android.content.res.Configuration;
78import android.graphics.Bitmap;
79import android.net.Uri;
80import android.os.Binder;
81import android.os.Build;
82import android.os.Bundle;
83import android.os.Debug;
84import android.os.DropBoxManager;
85import android.os.Environment;
86import android.os.FileObserver;
87import android.os.FileUtils;
88import android.os.Handler;
89import android.os.IBinder;
90import android.os.IPermissionController;
91import android.os.Looper;
92import android.os.Message;
93import android.os.Parcel;
94import android.os.ParcelFileDescriptor;
95import android.os.Process;
96import android.os.RemoteCallbackList;
97import android.os.RemoteException;
98import android.os.ServiceManager;
99import android.os.StrictMode;
100import android.os.SystemClock;
101import android.os.SystemProperties;
102import android.provider.Settings;
103import android.util.Config;
104import android.util.EventLog;
105import android.util.Slog;
106import android.util.Log;
107import android.util.PrintWriterPrinter;
108import android.util.SparseArray;
109import android.util.TimeUtils;
110import android.view.Gravity;
111import android.view.LayoutInflater;
112import android.view.View;
113import android.view.WindowManager;
114import android.view.WindowManagerPolicy;
115
116import java.io.BufferedInputStream;
117import java.io.BufferedOutputStream;
118import java.io.DataInputStream;
119import java.io.DataOutputStream;
120import java.io.File;
121import java.io.FileDescriptor;
122import java.io.FileInputStream;
123import java.io.FileNotFoundException;
124import java.io.FileOutputStream;
125import java.io.IOException;
126import java.io.InputStreamReader;
127import java.io.PrintWriter;
128import java.lang.IllegalStateException;
129import java.lang.ref.WeakReference;
130import java.util.ArrayList;
131import java.util.Collections;
132import java.util.Comparator;
133import java.util.HashMap;
134import java.util.HashSet;
135import java.util.Iterator;
136import java.util.List;
137import java.util.Locale;
138import java.util.Map;
139import java.util.Set;
140import java.util.concurrent.atomic.AtomicBoolean;
141import java.util.concurrent.atomic.AtomicLong;
142
143public final class ActivityManagerService extends ActivityManagerNative
144        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
145    static final String TAG = "ActivityManager";
146    static final boolean DEBUG = false;
147    static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
148    static final boolean DEBUG_SWITCH = localLOGV || false;
149    static final boolean DEBUG_TASKS = localLOGV || false;
150    static final boolean DEBUG_PAUSE = localLOGV || false;
151    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
152    static final boolean DEBUG_TRANSITION = localLOGV || false;
153    static final boolean DEBUG_BROADCAST = localLOGV || false;
154    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
155    static final boolean DEBUG_SERVICE = localLOGV || false;
156    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
157    static final boolean DEBUG_VISBILITY = localLOGV || false;
158    static final boolean DEBUG_PROCESSES = localLOGV || false;
159    static final boolean DEBUG_PROVIDER = localLOGV || false;
160    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
161    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
162    static final boolean DEBUG_RESULTS = localLOGV || false;
163    static final boolean DEBUG_BACKUP = localLOGV || false;
164    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
165    static final boolean DEBUG_POWER = localLOGV || false;
166    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
167    static final boolean VALIDATE_TOKENS = false;
168    static final boolean SHOW_ACTIVITY_START_TIME = true;
169
170    // Control over CPU and battery monitoring.
171    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
172    static final boolean MONITOR_CPU_USAGE = true;
173    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
174    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
175    static final boolean MONITOR_THREAD_CPU_USAGE = false;
176
177    // The flags that are set for all calls we make to the package manager.
178    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
179
180    private static final String SYSTEM_SECURE = "ro.secure";
181
182    // This is the maximum number of application processes we would like
183    // to have running.  Due to the asynchronous nature of things, we can
184    // temporarily go beyond this limit.
185    static final int MAX_PROCESSES = 2;
186
187    // Set to false to leave processes running indefinitely, relying on
188    // the kernel killing them as resources are required.
189    static final boolean ENFORCE_PROCESS_LIMIT = false;
190
191    // This is the maximum number of activities that we would like to have
192    // running at a given time.
193    static final int MAX_ACTIVITIES = 20;
194
195    // Maximum number of recent tasks that we can remember.
196    static final int MAX_RECENT_TASKS = 20;
197
198    // Amount of time after a call to stopAppSwitches() during which we will
199    // prevent further untrusted switches from happening.
200    static final long APP_SWITCH_DELAY_TIME = 5*1000;
201
202    // How long we wait for a launched process to attach to the activity manager
203    // before we decide it's never going to come up for real.
204    static final int PROC_START_TIMEOUT = 10*1000;
205
206    // How long to wait after going idle before forcing apps to GC.
207    static final int GC_TIMEOUT = 5*1000;
208
209    // The minimum amount of time between successive GC requests for a process.
210    static final int GC_MIN_INTERVAL = 60*1000;
211
212    // The rate at which we check for apps using excessive power -- 15 mins.
213    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
214
215    // The minimum sample duration we will allow before deciding we have
216    // enough data on wake locks to start killing things.
217    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
218
219    // The minimum sample duration we will allow before deciding we have
220    // enough data on CPU usage to start killing things.
221    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
222
223    // How long we allow a receiver to run before giving up on it.
224    static final int BROADCAST_TIMEOUT = 10*1000;
225
226    // How long we wait for a service to finish executing.
227    static final int SERVICE_TIMEOUT = 20*1000;
228
229    // How long a service needs to be running until restarting its process
230    // is no longer considered to be a relaunch of the service.
231    static final int SERVICE_RESTART_DURATION = 5*1000;
232
233    // How long a service needs to be running until it will start back at
234    // SERVICE_RESTART_DURATION after being killed.
235    static final int SERVICE_RESET_RUN_DURATION = 60*1000;
236
237    // Multiplying factor to increase restart duration time by, for each time
238    // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
239    static final int SERVICE_RESTART_DURATION_FACTOR = 4;
240
241    // The minimum amount of time between restarting services that we allow.
242    // That is, when multiple services are restarting, we won't allow each
243    // to restart less than this amount of time from the last one.
244    static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
245
246    // Maximum amount of time for there to be no activity on a service before
247    // we consider it non-essential and allow its process to go on the
248    // LRU background list.
249    static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
250
251    // How long we wait until we timeout on key dispatching.
252    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
253
254    // The minimum time we allow between crashes, for us to consider this
255    // application to be bad and stop and its services and reject broadcasts.
256    static final int MIN_CRASH_INTERVAL = 60*1000;
257
258    // How long we wait until we timeout on key dispatching during instrumentation.
259    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
260
261    // OOM adjustments for processes in various states:
262
263    // This is a process without anything currently running in it.  Definitely
264    // the first to go! Value set in system/rootdir/init.rc on startup.
265    // This value is initalized in the constructor, careful when refering to
266    // this static variable externally.
267    static final int EMPTY_APP_ADJ;
268
269    // This is a process only hosting activities that are not visible,
270    // so it can be killed without any disruption. Value set in
271    // system/rootdir/init.rc on startup.
272    static final int HIDDEN_APP_MAX_ADJ;
273    static int HIDDEN_APP_MIN_ADJ;
274
275    // This is a process holding the home application -- we want to try
276    // avoiding killing it, even if it would normally be in the background,
277    // because the user interacts with it so much.
278    static final int HOME_APP_ADJ;
279
280    // This is a process currently hosting a backup operation.  Killing it
281    // is not entirely fatal but is generally a bad idea.
282    static final int BACKUP_APP_ADJ;
283
284    // This is a process holding a secondary server -- killing it will not
285    // have much of an impact as far as the user is concerned. Value set in
286    // system/rootdir/init.rc on startup.
287    static final int SECONDARY_SERVER_ADJ;
288
289    // This is a process with a heavy-weight application.  It is in the
290    // background, but we want to try to avoid killing it.  Value set in
291    // system/rootdir/init.rc on startup.
292    static final int HEAVY_WEIGHT_APP_ADJ;
293
294    // This is a process only hosting components that are perceptible to the
295    // user, and we really want to avoid killing them, but they are not
296    // immediately visible. An example is background music playback.  Value set in
297    // system/rootdir/init.rc on startup.
298    static final int PERCEPTIBLE_APP_ADJ;
299
300    // This is a process only hosting activities that are visible to the
301    // user, so we'd prefer they don't disappear. Value set in
302    // system/rootdir/init.rc on startup.
303    static final int VISIBLE_APP_ADJ;
304
305    // This is the process running the current foreground app.  We'd really
306    // rather not kill it! Value set in system/rootdir/init.rc on startup.
307    static final int FOREGROUND_APP_ADJ;
308
309    // This is a process running a core server, such as telephony.  Definitely
310    // don't want to kill it, but doing so is not completely fatal.
311    static final int CORE_SERVER_ADJ = -12;
312
313    // The system process runs at the default adjustment.
314    static final int SYSTEM_ADJ = -16;
315
316    // Memory pages are 4K.
317    static final int PAGE_SIZE = 4*1024;
318
319    // Corresponding memory levels for above adjustments.
320    static final int EMPTY_APP_MEM;
321    static final int HIDDEN_APP_MEM;
322    static final int HOME_APP_MEM;
323    static final int BACKUP_APP_MEM;
324    static final int SECONDARY_SERVER_MEM;
325    static final int HEAVY_WEIGHT_APP_MEM;
326    static final int PERCEPTIBLE_APP_MEM;
327    static final int VISIBLE_APP_MEM;
328    static final int FOREGROUND_APP_MEM;
329
330    // The minimum number of hidden apps we want to be able to keep around,
331    // without empty apps being able to push them out of memory.
332    static final int MIN_HIDDEN_APPS = 2;
333
334    // The maximum number of hidden processes we will keep around before
335    // killing them; this is just a control to not let us go too crazy with
336    // keeping around processes on devices with large amounts of RAM.
337    static final int MAX_HIDDEN_APPS = 15;
338
339    // We put empty content processes after any hidden processes that have
340    // been idle for less than 15 seconds.
341    static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
342
343    // We put empty content processes after any hidden processes that have
344    // been idle for less than 120 seconds.
345    static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
346
347    static int getIntProp(String name, boolean allowZero) {
348        String str = SystemProperties.get(name);
349        if (str == null) {
350            throw new IllegalArgumentException("Property not defined: " + name);
351        }
352        int val = Integer.valueOf(str);
353        if (val == 0 && !allowZero) {
354            throw new IllegalArgumentException("Property must not be zero: " + name);
355        }
356        return val;
357    }
358
359    static {
360        // These values are set in system/rootdir/init.rc on startup.
361        FOREGROUND_APP_ADJ = getIntProp("ro.FOREGROUND_APP_ADJ", true);
362        VISIBLE_APP_ADJ = getIntProp("ro.VISIBLE_APP_ADJ", true);
363        PERCEPTIBLE_APP_ADJ = getIntProp("ro.PERCEPTIBLE_APP_ADJ", true);
364        HEAVY_WEIGHT_APP_ADJ = getIntProp("ro.HEAVY_WEIGHT_APP_ADJ", true);
365        SECONDARY_SERVER_ADJ = getIntProp("ro.SECONDARY_SERVER_ADJ", true);
366        BACKUP_APP_ADJ = getIntProp("ro.BACKUP_APP_ADJ", true);
367        HOME_APP_ADJ = getIntProp("ro.HOME_APP_ADJ", true);
368        HIDDEN_APP_MIN_ADJ = getIntProp("ro.HIDDEN_APP_MIN_ADJ", true);
369        EMPTY_APP_ADJ = getIntProp("ro.EMPTY_APP_ADJ", true);
370        // These days we use the last empty slot for hidden apps as well.
371        HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ;
372        FOREGROUND_APP_MEM = getIntProp("ro.FOREGROUND_APP_MEM", false)*PAGE_SIZE;
373        VISIBLE_APP_MEM = getIntProp("ro.VISIBLE_APP_MEM", false)*PAGE_SIZE;
374        PERCEPTIBLE_APP_MEM = getIntProp("ro.PERCEPTIBLE_APP_MEM", false)*PAGE_SIZE;
375        HEAVY_WEIGHT_APP_MEM = getIntProp("ro.HEAVY_WEIGHT_APP_MEM", false)*PAGE_SIZE;
376        SECONDARY_SERVER_MEM = getIntProp("ro.SECONDARY_SERVER_MEM", false)*PAGE_SIZE;
377        BACKUP_APP_MEM = getIntProp("ro.BACKUP_APP_MEM", false)*PAGE_SIZE;
378        HOME_APP_MEM = getIntProp("ro.HOME_APP_MEM", false)*PAGE_SIZE;
379        HIDDEN_APP_MEM = getIntProp("ro.HIDDEN_APP_MEM", false)*PAGE_SIZE;
380        EMPTY_APP_MEM = getIntProp("ro.EMPTY_APP_MEM", false)*PAGE_SIZE;
381    }
382
383    static final int MY_PID = Process.myPid();
384
385    static final String[] EMPTY_STRING_ARRAY = new String[0];
386
387    public ActivityStack mMainStack;
388
389    /**
390     * Description of a request to start a new activity, which has been held
391     * due to app switches being disabled.
392     */
393    static class PendingActivityLaunch {
394        ActivityRecord r;
395        ActivityRecord sourceRecord;
396        Uri[] grantedUriPermissions;
397        int grantedMode;
398        boolean onlyIfNeeded;
399    }
400
401    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
402            = new ArrayList<PendingActivityLaunch>();
403
404    /**
405     * List of all active broadcasts that are to be executed immediately
406     * (without waiting for another broadcast to finish).  Currently this only
407     * contains broadcasts to registered receivers, to avoid spinning up
408     * a bunch of processes to execute IntentReceiver components.
409     */
410    final ArrayList<BroadcastRecord> mParallelBroadcasts
411            = new ArrayList<BroadcastRecord>();
412
413    /**
414     * List of all active broadcasts that are to be executed one at a time.
415     * The object at the top of the list is the currently activity broadcasts;
416     * those after it are waiting for the top to finish..
417     */
418    final ArrayList<BroadcastRecord> mOrderedBroadcasts
419            = new ArrayList<BroadcastRecord>();
420
421    /**
422     * Historical data of past broadcasts, for debugging.
423     */
424    static final int MAX_BROADCAST_HISTORY = 100;
425    final BroadcastRecord[] mBroadcastHistory
426            = new BroadcastRecord[MAX_BROADCAST_HISTORY];
427
428    /**
429     * Set when we current have a BROADCAST_INTENT_MSG in flight.
430     */
431    boolean mBroadcastsScheduled = false;
432
433    /**
434     * Activity we have told the window manager to have key focus.
435     */
436    ActivityRecord mFocusedActivity = null;
437    /**
438     * List of intents that were used to start the most recent tasks.
439     */
440    final ArrayList<TaskRecord> mRecentTasks
441            = new ArrayList<TaskRecord>();
442
443    /**
444     * All of the applications we currently have running organized by name.
445     * The keys are strings of the application package name (as
446     * returned by the package manager), and the keys are ApplicationRecord
447     * objects.
448     */
449    final ProcessMap<ProcessRecord> mProcessNames
450            = new ProcessMap<ProcessRecord>();
451
452    /**
453     * The currently running heavy-weight process, if any.
454     */
455    ProcessRecord mHeavyWeightProcess = null;
456
457    /**
458     * The last time that various processes have crashed.
459     */
460    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
461
462    /**
463     * Set of applications that we consider to be bad, and will reject
464     * incoming broadcasts from (which the user has no control over).
465     * Processes are added to this set when they have crashed twice within
466     * a minimum amount of time; they are removed from it when they are
467     * later restarted (hopefully due to some user action).  The value is the
468     * time it was added to the list.
469     */
470    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
471
472    /**
473     * All of the processes we currently have running organized by pid.
474     * The keys are the pid running the application.
475     *
476     * <p>NOTE: This object is protected by its own lock, NOT the global
477     * activity manager lock!
478     */
479    final SparseArray<ProcessRecord> mPidsSelfLocked
480            = new SparseArray<ProcessRecord>();
481
482    /**
483     * All of the processes that have been forced to be foreground.  The key
484     * is the pid of the caller who requested it (we hold a death
485     * link on it).
486     */
487    abstract class ForegroundToken implements IBinder.DeathRecipient {
488        int pid;
489        IBinder token;
490    }
491    final SparseArray<ForegroundToken> mForegroundProcesses
492            = new SparseArray<ForegroundToken>();
493
494    /**
495     * List of records for processes that someone had tried to start before the
496     * system was ready.  We don't start them at that point, but ensure they
497     * are started by the time booting is complete.
498     */
499    final ArrayList<ProcessRecord> mProcessesOnHold
500            = new ArrayList<ProcessRecord>();
501
502    /**
503     * List of records for processes that we have started and are waiting
504     * for them to call back.  This is really only needed when running in
505     * single processes mode, in which case we do not have a unique pid for
506     * each process.
507     */
508    final ArrayList<ProcessRecord> mStartingProcesses
509            = new ArrayList<ProcessRecord>();
510
511    /**
512     * List of persistent applications that are in the process
513     * of being started.
514     */
515    final ArrayList<ProcessRecord> mPersistentStartingProcesses
516            = new ArrayList<ProcessRecord>();
517
518    /**
519     * Processes that are being forcibly torn down.
520     */
521    final ArrayList<ProcessRecord> mRemovedProcesses
522            = new ArrayList<ProcessRecord>();
523
524    /**
525     * List of running applications, sorted by recent usage.
526     * The first entry in the list is the least recently used.
527     * It contains ApplicationRecord objects.  This list does NOT include
528     * any persistent application records (since we never want to exit them).
529     */
530    final ArrayList<ProcessRecord> mLruProcesses
531            = new ArrayList<ProcessRecord>();
532
533    /**
534     * List of processes that should gc as soon as things are idle.
535     */
536    final ArrayList<ProcessRecord> mProcessesToGc
537            = new ArrayList<ProcessRecord>();
538
539    /**
540     * This is the process holding what we currently consider to be
541     * the "home" activity.
542     */
543    ProcessRecord mHomeProcess;
544
545    /**
546     * Set of PendingResultRecord objects that are currently active.
547     */
548    final HashSet mPendingResultRecords = new HashSet();
549
550    /**
551     * Set of IntentSenderRecord objects that are currently active.
552     */
553    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
554            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
555
556    /**
557     * Fingerprints (String.hashCode()) of stack traces that we've
558     * already logged DropBox entries for.  Guarded by itself.  If
559     * something (rogue user app) forces this over
560     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
561     */
562    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
563    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
564
565    /**
566     * Strict Mode background batched logging state.
567     *
568     * The string buffer is guarded by itself, and its lock is also
569     * used to determine if another batched write is already
570     * in-flight.
571     */
572    private final StringBuilder mStrictModeBuffer = new StringBuilder();
573
574    /**
575     * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
576     */
577    private boolean mPendingBroadcastTimeoutMessage;
578
579    /**
580     * Intent broadcast that we have tried to start, but are
581     * waiting for its application's process to be created.  We only
582     * need one (instead of a list) because we always process broadcasts
583     * one at a time, so no others can be started while waiting for this
584     * one.
585     */
586    BroadcastRecord mPendingBroadcast = null;
587
588    /**
589     * The receiver index that is pending, to restart the broadcast if needed.
590     */
591    int mPendingBroadcastRecvIndex;
592
593    /**
594     * Keeps track of all IIntentReceivers that have been registered for
595     * broadcasts.  Hash keys are the receiver IBinder, hash value is
596     * a ReceiverList.
597     */
598    final HashMap mRegisteredReceivers = new HashMap();
599
600    /**
601     * Resolver for broadcast intents to registered receivers.
602     * Holds BroadcastFilter (subclass of IntentFilter).
603     */
604    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
605            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
606        @Override
607        protected boolean allowFilterResult(
608                BroadcastFilter filter, List<BroadcastFilter> dest) {
609            IBinder target = filter.receiverList.receiver.asBinder();
610            for (int i=dest.size()-1; i>=0; i--) {
611                if (dest.get(i).receiverList.receiver.asBinder() == target) {
612                    return false;
613                }
614            }
615            return true;
616        }
617    };
618
619    /**
620     * State of all active sticky broadcasts.  Keys are the action of the
621     * sticky Intent, values are an ArrayList of all broadcasted intents with
622     * that action (which should usually be one).
623     */
624    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
625            new HashMap<String, ArrayList<Intent>>();
626
627    /**
628     * All currently running services.
629     */
630    final HashMap<ComponentName, ServiceRecord> mServices =
631        new HashMap<ComponentName, ServiceRecord>();
632
633    /**
634     * All currently running services indexed by the Intent used to start them.
635     */
636    final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
637        new HashMap<Intent.FilterComparison, ServiceRecord>();
638
639    /**
640     * All currently bound service connections.  Keys are the IBinder of
641     * the client's IServiceConnection.
642     */
643    final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
644            = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
645
646    /**
647     * List of services that we have been asked to start,
648     * but haven't yet been able to.  It is used to hold start requests
649     * while waiting for their corresponding application thread to get
650     * going.
651     */
652    final ArrayList<ServiceRecord> mPendingServices
653            = new ArrayList<ServiceRecord>();
654
655    /**
656     * List of services that are scheduled to restart following a crash.
657     */
658    final ArrayList<ServiceRecord> mRestartingServices
659            = new ArrayList<ServiceRecord>();
660
661    /**
662     * List of services that are in the process of being stopped.
663     */
664    final ArrayList<ServiceRecord> mStoppingServices
665            = new ArrayList<ServiceRecord>();
666
667    /**
668     * Backup/restore process management
669     */
670    String mBackupAppName = null;
671    BackupRecord mBackupTarget = null;
672
673    /**
674     * List of PendingThumbnailsRecord objects of clients who are still
675     * waiting to receive all of the thumbnails for a task.
676     */
677    final ArrayList mPendingThumbnails = new ArrayList();
678
679    /**
680     * List of HistoryRecord objects that have been finished and must
681     * still report back to a pending thumbnail receiver.
682     */
683    final ArrayList mCancelledThumbnails = new ArrayList();
684
685    /**
686     * All of the currently running global content providers.  Keys are a
687     * string containing the provider name and values are a
688     * ContentProviderRecord object containing the data about it.  Note
689     * that a single provider may be published under multiple names, so
690     * there may be multiple entries here for a single one in mProvidersByClass.
691     */
692    final HashMap<String, ContentProviderRecord> mProvidersByName
693            = new HashMap<String, ContentProviderRecord>();
694
695    /**
696     * All of the currently running global content providers.  Keys are a
697     * string containing the provider's implementation class and values are a
698     * ContentProviderRecord object containing the data about it.
699     */
700    final HashMap<String, ContentProviderRecord> mProvidersByClass
701            = new HashMap<String, ContentProviderRecord>();
702
703    /**
704     * List of content providers who have clients waiting for them.  The
705     * application is currently being launched and the provider will be
706     * removed from this list once it is published.
707     */
708    final ArrayList<ContentProviderRecord> mLaunchingProviders
709            = new ArrayList<ContentProviderRecord>();
710
711    /**
712     * Global set of specific Uri permissions that have been granted.
713     */
714    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
715            = new SparseArray<HashMap<Uri, UriPermission>>();
716
717    /**
718     * Thread-local storage used to carry caller permissions over through
719     * indirect content-provider access.
720     * @see #ActivityManagerService.openContentUri()
721     */
722    private class Identity {
723        public int pid;
724        public int uid;
725
726        Identity(int _pid, int _uid) {
727            pid = _pid;
728            uid = _uid;
729        }
730    }
731    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
732
733    /**
734     * All information we have collected about the runtime performance of
735     * any user id that can impact battery performance.
736     */
737    final BatteryStatsService mBatteryStatsService;
738
739    /**
740     * information about component usage
741     */
742    final UsageStatsService mUsageStatsService;
743
744    /**
745     * Current configuration information.  HistoryRecord objects are given
746     * a reference to this object to indicate which configuration they are
747     * currently running in, so this object must be kept immutable.
748     */
749    Configuration mConfiguration = new Configuration();
750
751    /**
752     * Current sequencing integer of the configuration, for skipping old
753     * configurations.
754     */
755    int mConfigurationSeq = 0;
756
757    /**
758     * Hardware-reported OpenGLES version.
759     */
760    final int GL_ES_VERSION;
761
762    /**
763     * List of initialization arguments to pass to all processes when binding applications to them.
764     * For example, references to the commonly used services.
765     */
766    HashMap<String, IBinder> mAppBindArgs;
767
768    /**
769     * Temporary to avoid allocations.  Protected by main lock.
770     */
771    final StringBuilder mStringBuilder = new StringBuilder(256);
772
773    /**
774     * Used to control how we initialize the service.
775     */
776    boolean mStartRunning = false;
777    ComponentName mTopComponent;
778    String mTopAction;
779    String mTopData;
780    boolean mProcessesReady = false;
781    boolean mSystemReady = false;
782    boolean mBooting = false;
783    boolean mWaitingUpdate = false;
784    boolean mDidUpdate = false;
785    boolean mOnBattery = false;
786    boolean mLaunchWarningShown = false;
787
788    Context mContext;
789
790    int mFactoryTest;
791
792    boolean mCheckedForSetup;
793
794    /**
795     * The time at which we will allow normal application switches again,
796     * after a call to {@link #stopAppSwitches()}.
797     */
798    long mAppSwitchesAllowedTime;
799
800    /**
801     * This is set to true after the first switch after mAppSwitchesAllowedTime
802     * is set; any switches after that will clear the time.
803     */
804    boolean mDidAppSwitch;
805
806    /**
807     * Last time (in realtime) at which we checked for power usage.
808     */
809    long mLastPowerCheckRealtime;
810
811    /**
812     * Last time (in uptime) at which we checked for power usage.
813     */
814    long mLastPowerCheckUptime;
815
816    /**
817     * Set while we are wanting to sleep, to prevent any
818     * activities from being started/resumed.
819     */
820    boolean mSleeping = false;
821
822    /**
823     * Set if we are shutting down the system, similar to sleeping.
824     */
825    boolean mShuttingDown = false;
826
827    /**
828     * Task identifier that activities are currently being started
829     * in.  Incremented each time a new task is created.
830     * todo: Replace this with a TokenSpace class that generates non-repeating
831     * integers that won't wrap.
832     */
833    int mCurTask = 1;
834
835    /**
836     * Current sequence id for oom_adj computation traversal.
837     */
838    int mAdjSeq = 0;
839
840    /**
841     * Current sequence id for process LRU updating.
842     */
843    int mLruSeq = 0;
844
845    /**
846     * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
847     * is set, indicating the user wants processes started in such a way
848     * that they can use ANDROID_PROCESS_WRAPPER and know what will be
849     * running in each process (thus no pre-initialized process, etc).
850     */
851    boolean mSimpleProcessManagement = false;
852
853    /**
854     * System monitoring: number of processes that died since the last
855     * N procs were started.
856     */
857    int[] mProcDeaths = new int[20];
858
859    /**
860     * This is set if we had to do a delayed dexopt of an app before launching
861     * it, to increasing the ANR timeouts in that case.
862     */
863    boolean mDidDexOpt;
864
865    String mDebugApp = null;
866    boolean mWaitForDebugger = false;
867    boolean mDebugTransient = false;
868    String mOrigDebugApp = null;
869    boolean mOrigWaitForDebugger = false;
870    boolean mAlwaysFinishActivities = false;
871    IActivityController mController = null;
872
873    final RemoteCallbackList<IActivityWatcher> mWatchers
874            = new RemoteCallbackList<IActivityWatcher>();
875
876    /**
877     * Callback of last caller to {@link #requestPss}.
878     */
879    Runnable mRequestPssCallback;
880
881    /**
882     * Remaining processes for which we are waiting results from the last
883     * call to {@link #requestPss}.
884     */
885    final ArrayList<ProcessRecord> mRequestPssList
886            = new ArrayList<ProcessRecord>();
887
888    /**
889     * Runtime statistics collection thread.  This object's lock is used to
890     * protect all related state.
891     */
892    final Thread mProcessStatsThread;
893
894    /**
895     * Used to collect process stats when showing not responding dialog.
896     * Protected by mProcessStatsThread.
897     */
898    final ProcessStats mProcessStats = new ProcessStats(
899            MONITOR_THREAD_CPU_USAGE);
900    final AtomicLong mLastCpuTime = new AtomicLong(0);
901    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
902
903    long mLastWriteTime = 0;
904
905    /**
906     * Set to true after the system has finished booting.
907     */
908    boolean mBooted = false;
909
910    int mProcessLimit = 0;
911
912    WindowManagerService mWindowManager;
913
914    static ActivityManagerService mSelf;
915    static ActivityThread mSystemThread;
916
917    private final class AppDeathRecipient implements IBinder.DeathRecipient {
918        final ProcessRecord mApp;
919        final int mPid;
920        final IApplicationThread mAppThread;
921
922        AppDeathRecipient(ProcessRecord app, int pid,
923                IApplicationThread thread) {
924            if (localLOGV) Slog.v(
925                TAG, "New death recipient " + this
926                + " for thread " + thread.asBinder());
927            mApp = app;
928            mPid = pid;
929            mAppThread = thread;
930        }
931
932        public void binderDied() {
933            if (localLOGV) Slog.v(
934                TAG, "Death received in " + this
935                + " for thread " + mAppThread.asBinder());
936            synchronized(ActivityManagerService.this) {
937                appDiedLocked(mApp, mPid, mAppThread);
938            }
939        }
940    }
941
942    static final int SHOW_ERROR_MSG = 1;
943    static final int SHOW_NOT_RESPONDING_MSG = 2;
944    static final int SHOW_FACTORY_ERROR_MSG = 3;
945    static final int UPDATE_CONFIGURATION_MSG = 4;
946    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
947    static final int WAIT_FOR_DEBUGGER_MSG = 6;
948    static final int BROADCAST_INTENT_MSG = 7;
949    static final int BROADCAST_TIMEOUT_MSG = 8;
950    static final int SERVICE_TIMEOUT_MSG = 12;
951    static final int UPDATE_TIME_ZONE = 13;
952    static final int SHOW_UID_ERROR_MSG = 14;
953    static final int IM_FEELING_LUCKY_MSG = 15;
954    static final int PROC_START_TIMEOUT_MSG = 20;
955    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
956    static final int KILL_APPLICATION_MSG = 22;
957    static final int FINALIZE_PENDING_INTENT_MSG = 23;
958    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
959    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
960    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
961    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
962
963    AlertDialog mUidAlert;
964
965    final Handler mHandler = new Handler() {
966        //public Handler() {
967        //    if (localLOGV) Slog.v(TAG, "Handler started!");
968        //}
969
970        public void handleMessage(Message msg) {
971            switch (msg.what) {
972            case SHOW_ERROR_MSG: {
973                HashMap data = (HashMap) msg.obj;
974                synchronized (ActivityManagerService.this) {
975                    ProcessRecord proc = (ProcessRecord)data.get("app");
976                    if (proc != null && proc.crashDialog != null) {
977                        Slog.e(TAG, "App already has crash dialog: " + proc);
978                        return;
979                    }
980                    AppErrorResult res = (AppErrorResult) data.get("result");
981                    if (!mSleeping && !mShuttingDown) {
982                        Dialog d = new AppErrorDialog(mContext, res, proc);
983                        d.show();
984                        proc.crashDialog = d;
985                    } else {
986                        // The device is asleep, so just pretend that the user
987                        // saw a crash dialog and hit "force quit".
988                        res.set(0);
989                    }
990                }
991
992                ensureBootCompleted();
993            } break;
994            case SHOW_NOT_RESPONDING_MSG: {
995                synchronized (ActivityManagerService.this) {
996                    HashMap data = (HashMap) msg.obj;
997                    ProcessRecord proc = (ProcessRecord)data.get("app");
998                    if (proc != null && proc.anrDialog != null) {
999                        Slog.e(TAG, "App already has anr dialog: " + proc);
1000                        return;
1001                    }
1002
1003                    Intent intent = new Intent("android.intent.action.ANR");
1004                    if (!mProcessesReady) {
1005                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1006                    }
1007                    broadcastIntentLocked(null, null, intent,
1008                            null, null, 0, null, null, null,
1009                            false, false, MY_PID, Process.SYSTEM_UID);
1010
1011                    Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1012                            mContext, proc, (ActivityRecord)data.get("activity"));
1013                    d.show();
1014                    proc.anrDialog = d;
1015                }
1016
1017                ensureBootCompleted();
1018            } break;
1019            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1020                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1021                synchronized (ActivityManagerService.this) {
1022                    ProcessRecord proc = (ProcessRecord) data.get("app");
1023                    if (proc == null) {
1024                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1025                        break;
1026                    }
1027                    if (proc.crashDialog != null) {
1028                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1029                        return;
1030                    }
1031                    AppErrorResult res = (AppErrorResult) data.get("result");
1032                    if (!mSleeping && !mShuttingDown) {
1033                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
1034                        d.show();
1035                        proc.crashDialog = d;
1036                    } else {
1037                        // The device is asleep, so just pretend that the user
1038                        // saw a crash dialog and hit "force quit".
1039                        res.set(0);
1040                    }
1041                }
1042                ensureBootCompleted();
1043            } break;
1044            case SHOW_FACTORY_ERROR_MSG: {
1045                Dialog d = new FactoryErrorDialog(
1046                    mContext, msg.getData().getCharSequence("msg"));
1047                d.show();
1048                ensureBootCompleted();
1049            } break;
1050            case UPDATE_CONFIGURATION_MSG: {
1051                final ContentResolver resolver = mContext.getContentResolver();
1052                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1053            } break;
1054            case GC_BACKGROUND_PROCESSES_MSG: {
1055                synchronized (ActivityManagerService.this) {
1056                    performAppGcsIfAppropriateLocked();
1057                }
1058            } break;
1059            case WAIT_FOR_DEBUGGER_MSG: {
1060                synchronized (ActivityManagerService.this) {
1061                    ProcessRecord app = (ProcessRecord)msg.obj;
1062                    if (msg.arg1 != 0) {
1063                        if (!app.waitedForDebugger) {
1064                            Dialog d = new AppWaitingForDebuggerDialog(
1065                                    ActivityManagerService.this,
1066                                    mContext, app);
1067                            app.waitDialog = d;
1068                            app.waitedForDebugger = true;
1069                            d.show();
1070                        }
1071                    } else {
1072                        if (app.waitDialog != null) {
1073                            app.waitDialog.dismiss();
1074                            app.waitDialog = null;
1075                        }
1076                    }
1077                }
1078            } break;
1079            case BROADCAST_INTENT_MSG: {
1080                if (DEBUG_BROADCAST) Slog.v(
1081                        TAG, "Received BROADCAST_INTENT_MSG");
1082                processNextBroadcast(true);
1083            } break;
1084            case BROADCAST_TIMEOUT_MSG: {
1085                synchronized (ActivityManagerService.this) {
1086                    broadcastTimeoutLocked(true);
1087                }
1088            } break;
1089            case SERVICE_TIMEOUT_MSG: {
1090                if (mDidDexOpt) {
1091                    mDidDexOpt = false;
1092                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1093                    nmsg.obj = msg.obj;
1094                    mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1095                    return;
1096                }
1097                serviceTimeout((ProcessRecord)msg.obj);
1098            } break;
1099            case UPDATE_TIME_ZONE: {
1100                synchronized (ActivityManagerService.this) {
1101                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1102                        ProcessRecord r = mLruProcesses.get(i);
1103                        if (r.thread != null) {
1104                            try {
1105                                r.thread.updateTimeZone();
1106                            } catch (RemoteException ex) {
1107                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1108                            }
1109                        }
1110                    }
1111                }
1112            } break;
1113            case SHOW_UID_ERROR_MSG: {
1114                // XXX This is a temporary dialog, no need to localize.
1115                AlertDialog d = new BaseErrorDialog(mContext);
1116                d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1117                d.setCancelable(false);
1118                d.setTitle("System UIDs Inconsistent");
1119                d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
1120                d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1121                        mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1122                mUidAlert = d;
1123                d.show();
1124            } break;
1125            case IM_FEELING_LUCKY_MSG: {
1126                if (mUidAlert != null) {
1127                    mUidAlert.dismiss();
1128                    mUidAlert = null;
1129                }
1130            } break;
1131            case PROC_START_TIMEOUT_MSG: {
1132                if (mDidDexOpt) {
1133                    mDidDexOpt = false;
1134                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1135                    nmsg.obj = msg.obj;
1136                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1137                    return;
1138                }
1139                ProcessRecord app = (ProcessRecord)msg.obj;
1140                synchronized (ActivityManagerService.this) {
1141                    processStartTimedOutLocked(app);
1142                }
1143            } break;
1144            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1145                synchronized (ActivityManagerService.this) {
1146                    doPendingActivityLaunchesLocked(true);
1147                }
1148            } break;
1149            case KILL_APPLICATION_MSG: {
1150                synchronized (ActivityManagerService.this) {
1151                    int uid = msg.arg1;
1152                    boolean restart = (msg.arg2 == 1);
1153                    String pkg = (String) msg.obj;
1154                    forceStopPackageLocked(pkg, uid, restart, false, true);
1155                }
1156            } break;
1157            case FINALIZE_PENDING_INTENT_MSG: {
1158                ((PendingIntentRecord)msg.obj).completeFinalize();
1159            } break;
1160            case POST_HEAVY_NOTIFICATION_MSG: {
1161                INotificationManager inm = NotificationManager.getService();
1162                if (inm == null) {
1163                    return;
1164                }
1165
1166                ActivityRecord root = (ActivityRecord)msg.obj;
1167                ProcessRecord process = root.app;
1168                if (process == null) {
1169                    return;
1170                }
1171
1172                try {
1173                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1174                    String text = mContext.getString(R.string.heavy_weight_notification,
1175                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1176                    Notification notification = new Notification();
1177                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1178                    notification.when = 0;
1179                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1180                    notification.tickerText = text;
1181                    notification.defaults = 0; // please be quiet
1182                    notification.sound = null;
1183                    notification.vibrate = null;
1184                    notification.setLatestEventInfo(context, text,
1185                            mContext.getText(R.string.heavy_weight_notification_detail),
1186                            PendingIntent.getActivity(mContext, 0, root.intent,
1187                                    PendingIntent.FLAG_CANCEL_CURRENT));
1188
1189                    try {
1190                        int[] outId = new int[1];
1191                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
1192                                notification, outId);
1193                    } catch (RuntimeException e) {
1194                        Slog.w(ActivityManagerService.TAG,
1195                                "Error showing notification for heavy-weight app", e);
1196                    } catch (RemoteException e) {
1197                    }
1198                } catch (NameNotFoundException e) {
1199                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1200                }
1201            } break;
1202            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1203                INotificationManager inm = NotificationManager.getService();
1204                if (inm == null) {
1205                    return;
1206                }
1207                try {
1208                    inm.cancelNotification("android",
1209                            R.string.heavy_weight_notification);
1210                } catch (RuntimeException e) {
1211                    Slog.w(ActivityManagerService.TAG,
1212                            "Error canceling notification for service", e);
1213                } catch (RemoteException e) {
1214                }
1215            } break;
1216            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1217                synchronized (ActivityManagerService.this) {
1218                    checkExcessivePowerUsageLocked(true);
1219                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1220                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1221                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1222                }
1223            } break;
1224            }
1225        }
1226    };
1227
1228    public static void setSystemProcess() {
1229        try {
1230            ActivityManagerService m = mSelf;
1231
1232            ServiceManager.addService("activity", m);
1233            ServiceManager.addService("meminfo", new MemBinder(m));
1234            if (MONITOR_CPU_USAGE) {
1235                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1236            }
1237            ServiceManager.addService("permission", new PermissionController(m));
1238
1239            ApplicationInfo info =
1240                mSelf.mContext.getPackageManager().getApplicationInfo(
1241                        "android", STOCK_PM_FLAGS);
1242            mSystemThread.installSystemApplicationInfo(info);
1243
1244            synchronized (mSelf) {
1245                ProcessRecord app = mSelf.newProcessRecordLocked(
1246                        mSystemThread.getApplicationThread(), info,
1247                        info.processName);
1248                app.persistent = true;
1249                app.pid = MY_PID;
1250                app.maxAdj = SYSTEM_ADJ;
1251                mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1252                synchronized (mSelf.mPidsSelfLocked) {
1253                    mSelf.mPidsSelfLocked.put(app.pid, app);
1254                }
1255                mSelf.updateLruProcessLocked(app, true, true);
1256            }
1257        } catch (PackageManager.NameNotFoundException e) {
1258            throw new RuntimeException(
1259                    "Unable to find android system package", e);
1260        }
1261    }
1262
1263    public void setWindowManager(WindowManagerService wm) {
1264        mWindowManager = wm;
1265    }
1266
1267    public static final Context main(int factoryTest) {
1268        AThread thr = new AThread();
1269        thr.start();
1270
1271        synchronized (thr) {
1272            while (thr.mService == null) {
1273                try {
1274                    thr.wait();
1275                } catch (InterruptedException e) {
1276                }
1277            }
1278        }
1279
1280        ActivityManagerService m = thr.mService;
1281        mSelf = m;
1282        ActivityThread at = ActivityThread.systemMain();
1283        mSystemThread = at;
1284        Context context = at.getSystemContext();
1285        m.mContext = context;
1286        m.mFactoryTest = factoryTest;
1287        m.mMainStack = new ActivityStack(m, context, true);
1288
1289        m.mBatteryStatsService.publish(context);
1290        m.mUsageStatsService.publish(context);
1291
1292        synchronized (thr) {
1293            thr.mReady = true;
1294            thr.notifyAll();
1295        }
1296
1297        m.startRunning(null, null, null, null);
1298
1299        return context;
1300    }
1301
1302    public static ActivityManagerService self() {
1303        return mSelf;
1304    }
1305
1306    static class AThread extends Thread {
1307        ActivityManagerService mService;
1308        boolean mReady = false;
1309
1310        public AThread() {
1311            super("ActivityManager");
1312        }
1313
1314        public void run() {
1315            Looper.prepare();
1316
1317            android.os.Process.setThreadPriority(
1318                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1319            android.os.Process.setCanSelfBackground(false);
1320
1321            ActivityManagerService m = new ActivityManagerService();
1322
1323            synchronized (this) {
1324                mService = m;
1325                notifyAll();
1326            }
1327
1328            synchronized (this) {
1329                while (!mReady) {
1330                    try {
1331                        wait();
1332                    } catch (InterruptedException e) {
1333                    }
1334                }
1335            }
1336
1337            Looper.loop();
1338        }
1339    }
1340
1341    static class MemBinder extends Binder {
1342        ActivityManagerService mActivityManagerService;
1343        MemBinder(ActivityManagerService activityManagerService) {
1344            mActivityManagerService = activityManagerService;
1345        }
1346
1347        @Override
1348        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1349            ActivityManagerService service = mActivityManagerService;
1350            ArrayList<ProcessRecord> procs;
1351            synchronized (mActivityManagerService) {
1352                if (args != null && args.length > 0
1353                        && args[0].charAt(0) != '-') {
1354                    procs = new ArrayList<ProcessRecord>();
1355                    int pid = -1;
1356                    try {
1357                        pid = Integer.parseInt(args[0]);
1358                    } catch (NumberFormatException e) {
1359
1360                    }
1361                    for (int i=service.mLruProcesses.size()-1; i>=0; i--) {
1362                        ProcessRecord proc = service.mLruProcesses.get(i);
1363                        if (proc.pid == pid) {
1364                            procs.add(proc);
1365                        } else if (proc.processName.equals(args[0])) {
1366                            procs.add(proc);
1367                        }
1368                    }
1369                    if (procs.size() <= 0) {
1370                        pw.println("No process found for: " + args[0]);
1371                        return;
1372                    }
1373                } else {
1374                    procs = new ArrayList<ProcessRecord>(service.mLruProcesses);
1375                }
1376            }
1377            dumpApplicationMemoryUsage(fd, pw, procs, "  ", args);
1378        }
1379    }
1380
1381    static class CpuBinder extends Binder {
1382        ActivityManagerService mActivityManagerService;
1383        CpuBinder(ActivityManagerService activityManagerService) {
1384            mActivityManagerService = activityManagerService;
1385        }
1386
1387        @Override
1388        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1389            synchronized (mActivityManagerService.mProcessStatsThread) {
1390                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1391                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1392                        SystemClock.uptimeMillis()));
1393            }
1394        }
1395    }
1396
1397    private ActivityManagerService() {
1398        String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
1399        if (v != null && Integer.getInteger(v) != 0) {
1400            mSimpleProcessManagement = true;
1401        }
1402        v = System.getenv("ANDROID_DEBUG_APP");
1403        if (v != null) {
1404            mSimpleProcessManagement = true;
1405        }
1406
1407        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1408
1409        File dataDir = Environment.getDataDirectory();
1410        File systemDir = new File(dataDir, "system");
1411        systemDir.mkdirs();
1412        mBatteryStatsService = new BatteryStatsService(new File(
1413                systemDir, "batterystats.bin").toString());
1414        mBatteryStatsService.getActiveStatistics().readLocked();
1415        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1416        mOnBattery = DEBUG_POWER ? true
1417                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1418        mBatteryStatsService.getActiveStatistics().setCallback(this);
1419
1420        mUsageStatsService = new UsageStatsService(new File(
1421                systemDir, "usagestats").toString());
1422
1423        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1424            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1425
1426        mConfiguration.setToDefaults();
1427        mConfiguration.locale = Locale.getDefault();
1428        mProcessStats.init();
1429
1430        // Add ourself to the Watchdog monitors.
1431        Watchdog.getInstance().addMonitor(this);
1432
1433        mProcessStatsThread = new Thread("ProcessStats") {
1434            public void run() {
1435                while (true) {
1436                    try {
1437                        try {
1438                            synchronized(this) {
1439                                final long now = SystemClock.uptimeMillis();
1440                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1441                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1442                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1443                                //        + ", write delay=" + nextWriteDelay);
1444                                if (nextWriteDelay < nextCpuDelay) {
1445                                    nextCpuDelay = nextWriteDelay;
1446                                }
1447                                if (nextCpuDelay > 0) {
1448                                    mProcessStatsMutexFree.set(true);
1449                                    this.wait(nextCpuDelay);
1450                                }
1451                            }
1452                        } catch (InterruptedException e) {
1453                        }
1454                        updateCpuStatsNow();
1455                    } catch (Exception e) {
1456                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1457                    }
1458                }
1459            }
1460        };
1461        mProcessStatsThread.start();
1462    }
1463
1464    @Override
1465    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1466            throws RemoteException {
1467        try {
1468            return super.onTransact(code, data, reply, flags);
1469        } catch (RuntimeException e) {
1470            // The activity manager only throws security exceptions, so let's
1471            // log all others.
1472            if (!(e instanceof SecurityException)) {
1473                Slog.e(TAG, "Activity Manager Crash", e);
1474            }
1475            throw e;
1476        }
1477    }
1478
1479    void updateCpuStats() {
1480        final long now = SystemClock.uptimeMillis();
1481        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1482            return;
1483        }
1484        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1485            synchronized (mProcessStatsThread) {
1486                mProcessStatsThread.notify();
1487            }
1488        }
1489    }
1490
1491    void updateCpuStatsNow() {
1492        synchronized (mProcessStatsThread) {
1493            mProcessStatsMutexFree.set(false);
1494            final long now = SystemClock.uptimeMillis();
1495            boolean haveNewCpuStats = false;
1496
1497            if (MONITOR_CPU_USAGE &&
1498                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1499                mLastCpuTime.set(now);
1500                haveNewCpuStats = true;
1501                mProcessStats.update();
1502                //Slog.i(TAG, mProcessStats.printCurrentState());
1503                //Slog.i(TAG, "Total CPU usage: "
1504                //        + mProcessStats.getTotalCpuPercent() + "%");
1505
1506                // Slog the cpu usage if the property is set.
1507                if ("true".equals(SystemProperties.get("events.cpu"))) {
1508                    int user = mProcessStats.getLastUserTime();
1509                    int system = mProcessStats.getLastSystemTime();
1510                    int iowait = mProcessStats.getLastIoWaitTime();
1511                    int irq = mProcessStats.getLastIrqTime();
1512                    int softIrq = mProcessStats.getLastSoftIrqTime();
1513                    int idle = mProcessStats.getLastIdleTime();
1514
1515                    int total = user + system + iowait + irq + softIrq + idle;
1516                    if (total == 0) total = 1;
1517
1518                    EventLog.writeEvent(EventLogTags.CPU,
1519                            ((user+system+iowait+irq+softIrq) * 100) / total,
1520                            (user * 100) / total,
1521                            (system * 100) / total,
1522                            (iowait * 100) / total,
1523                            (irq * 100) / total,
1524                            (softIrq * 100) / total);
1525                }
1526            }
1527
1528            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1529            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1530            synchronized(bstats) {
1531                synchronized(mPidsSelfLocked) {
1532                    if (haveNewCpuStats) {
1533                        if (mOnBattery) {
1534                            int perc = bstats.startAddingCpuLocked();
1535                            int totalUTime = 0;
1536                            int totalSTime = 0;
1537                            final int N = mProcessStats.countStats();
1538                            for (int i=0; i<N; i++) {
1539                                ProcessStats.Stats st = mProcessStats.getStats(i);
1540                                if (!st.working) {
1541                                    continue;
1542                                }
1543                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1544                                int otherUTime = (st.rel_utime*perc)/100;
1545                                int otherSTime = (st.rel_stime*perc)/100;
1546                                totalUTime += otherUTime;
1547                                totalSTime += otherSTime;
1548                                if (pr != null) {
1549                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1550                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1551                                            st.rel_stime-otherSTime);
1552                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1553                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1554                                } else {
1555                                    BatteryStatsImpl.Uid.Proc ps =
1556                                            bstats.getProcessStatsLocked(st.name, st.pid);
1557                                    if (ps != null) {
1558                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1559                                                st.rel_stime-otherSTime);
1560                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1561                                    }
1562                                }
1563                            }
1564                            bstats.finishAddingCpuLocked(perc, totalUTime,
1565                                    totalSTime, cpuSpeedTimes);
1566                        }
1567                    }
1568                }
1569
1570                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1571                    mLastWriteTime = now;
1572                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1573                }
1574            }
1575        }
1576    }
1577
1578    @Override
1579    public void batteryNeedsCpuUpdate() {
1580        updateCpuStatsNow();
1581    }
1582
1583    @Override
1584    public void batteryPowerChanged(boolean onBattery) {
1585        // When plugging in, update the CPU stats first before changing
1586        // the plug state.
1587        updateCpuStatsNow();
1588        synchronized (this) {
1589            synchronized(mPidsSelfLocked) {
1590                mOnBattery = DEBUG_POWER ? true : onBattery;
1591            }
1592        }
1593    }
1594
1595    /**
1596     * Initialize the application bind args. These are passed to each
1597     * process when the bindApplication() IPC is sent to the process. They're
1598     * lazily setup to make sure the services are running when they're asked for.
1599     */
1600    private HashMap<String, IBinder> getCommonServicesLocked() {
1601        if (mAppBindArgs == null) {
1602            mAppBindArgs = new HashMap<String, IBinder>();
1603
1604            // Setup the application init args
1605            mAppBindArgs.put("package", ServiceManager.getService("package"));
1606            mAppBindArgs.put("window", ServiceManager.getService("window"));
1607            mAppBindArgs.put(Context.ALARM_SERVICE,
1608                    ServiceManager.getService(Context.ALARM_SERVICE));
1609        }
1610        return mAppBindArgs;
1611    }
1612
1613    final void setFocusedActivityLocked(ActivityRecord r) {
1614        if (mFocusedActivity != r) {
1615            mFocusedActivity = r;
1616            mWindowManager.setFocusedApp(r, true);
1617        }
1618    }
1619
1620    private final void updateLruProcessInternalLocked(ProcessRecord app,
1621            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1622        // put it on the LRU to keep track of when it should be exited.
1623        int lrui = mLruProcesses.indexOf(app);
1624        if (lrui >= 0) mLruProcesses.remove(lrui);
1625
1626        int i = mLruProcesses.size()-1;
1627        int skipTop = 0;
1628
1629        app.lruSeq = mLruSeq;
1630
1631        // compute the new weight for this process.
1632        if (updateActivityTime) {
1633            app.lastActivityTime = SystemClock.uptimeMillis();
1634        }
1635        if (app.activities.size() > 0) {
1636            // If this process has activities, we more strongly want to keep
1637            // it around.
1638            app.lruWeight = app.lastActivityTime;
1639        } else if (app.pubProviders.size() > 0) {
1640            // If this process contains content providers, we want to keep
1641            // it a little more strongly.
1642            app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
1643            // Also don't let it kick out the first few "real" hidden processes.
1644            skipTop = MIN_HIDDEN_APPS;
1645        } else {
1646            // If this process doesn't have activities, we less strongly
1647            // want to keep it around, and generally want to avoid getting
1648            // in front of any very recently used activities.
1649            app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
1650            // Also don't let it kick out the first few "real" hidden processes.
1651            skipTop = MIN_HIDDEN_APPS;
1652        }
1653
1654        while (i >= 0) {
1655            ProcessRecord p = mLruProcesses.get(i);
1656            // If this app shouldn't be in front of the first N background
1657            // apps, then skip over that many that are currently hidden.
1658            if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
1659                skipTop--;
1660            }
1661            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1662                mLruProcesses.add(i+1, app);
1663                break;
1664            }
1665            i--;
1666        }
1667        if (i < 0) {
1668            mLruProcesses.add(0, app);
1669        }
1670
1671        // If the app is currently using a content provider or service,
1672        // bump those processes as well.
1673        if (app.connections.size() > 0) {
1674            for (ConnectionRecord cr : app.connections) {
1675                if (cr.binding != null && cr.binding.service != null
1676                        && cr.binding.service.app != null
1677                        && cr.binding.service.app.lruSeq != mLruSeq) {
1678                    updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1679                            updateActivityTime, i+1);
1680                }
1681            }
1682        }
1683        if (app.conProviders.size() > 0) {
1684            for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1685                if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1686                    updateLruProcessInternalLocked(cpr.app, oomAdj,
1687                            updateActivityTime, i+1);
1688                }
1689            }
1690        }
1691
1692        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1693        if (oomAdj) {
1694            updateOomAdjLocked();
1695        }
1696    }
1697
1698    final void updateLruProcessLocked(ProcessRecord app,
1699            boolean oomAdj, boolean updateActivityTime) {
1700        mLruSeq++;
1701        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1702    }
1703
1704    final ProcessRecord getProcessRecordLocked(
1705            String processName, int uid) {
1706        if (uid == Process.SYSTEM_UID) {
1707            // The system gets to run in any process.  If there are multiple
1708            // processes with the same uid, just pick the first (this
1709            // should never happen).
1710            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1711                    processName);
1712            return procs != null ? procs.valueAt(0) : null;
1713        }
1714        ProcessRecord proc = mProcessNames.get(processName, uid);
1715        return proc;
1716    }
1717
1718    void ensurePackageDexOpt(String packageName) {
1719        IPackageManager pm = AppGlobals.getPackageManager();
1720        try {
1721            if (pm.performDexOpt(packageName)) {
1722                mDidDexOpt = true;
1723            }
1724        } catch (RemoteException e) {
1725        }
1726    }
1727
1728    boolean isNextTransitionForward() {
1729        int transit = mWindowManager.getPendingAppTransition();
1730        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1731                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1732                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1733    }
1734
1735    final ProcessRecord startProcessLocked(String processName,
1736            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1737            String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
1738        ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1739        // We don't have to do anything more if:
1740        // (1) There is an existing application record; and
1741        // (2) The caller doesn't think it is dead, OR there is no thread
1742        //     object attached to it so we know it couldn't have crashed; and
1743        // (3) There is a pid assigned to it, so it is either starting or
1744        //     already running.
1745        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1746                + " app=" + app + " knownToBeDead=" + knownToBeDead
1747                + " thread=" + (app != null ? app.thread : null)
1748                + " pid=" + (app != null ? app.pid : -1));
1749        if (app != null && app.pid > 0) {
1750            if (!knownToBeDead || app.thread == null) {
1751                // We already have the app running, or are waiting for it to
1752                // come up (we have a pid but not yet its thread), so keep it.
1753                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1754                return app;
1755            } else {
1756                // An application record is attached to a previous process,
1757                // clean it up now.
1758                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1759                handleAppDiedLocked(app, true);
1760            }
1761        }
1762
1763        String hostingNameStr = hostingName != null
1764                ? hostingName.flattenToShortString() : null;
1765
1766        if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1767            // If we are in the background, then check to see if this process
1768            // is bad.  If so, we will just silently fail.
1769            if (mBadProcesses.get(info.processName, info.uid) != null) {
1770                if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1771                        + "/" + info.processName);
1772                return null;
1773            }
1774        } else {
1775            // When the user is explicitly starting a process, then clear its
1776            // crash count so that we won't make it bad until they see at
1777            // least one crash dialog again, and make the process good again
1778            // if it had been bad.
1779            if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1780                    + "/" + info.processName);
1781            mProcessCrashTimes.remove(info.processName, info.uid);
1782            if (mBadProcesses.get(info.processName, info.uid) != null) {
1783                EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1784                        info.processName);
1785                mBadProcesses.remove(info.processName, info.uid);
1786                if (app != null) {
1787                    app.bad = false;
1788                }
1789            }
1790        }
1791
1792        if (app == null) {
1793            app = newProcessRecordLocked(null, info, processName);
1794            mProcessNames.put(processName, info.uid, app);
1795        } else {
1796            // If this is a new package in the process, add the package to the list
1797            app.addPackage(info.packageName);
1798        }
1799
1800        // If the system is not ready yet, then hold off on starting this
1801        // process until it is.
1802        if (!mProcessesReady
1803                && !isAllowedWhileBooting(info)
1804                && !allowWhileBooting) {
1805            if (!mProcessesOnHold.contains(app)) {
1806                mProcessesOnHold.add(app);
1807            }
1808            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1809            return app;
1810        }
1811
1812        startProcessLocked(app, hostingType, hostingNameStr);
1813        return (app.pid != 0) ? app : null;
1814    }
1815
1816    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1817        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1818    }
1819
1820    private final void startProcessLocked(ProcessRecord app,
1821            String hostingType, String hostingNameStr) {
1822        if (app.pid > 0 && app.pid != MY_PID) {
1823            synchronized (mPidsSelfLocked) {
1824                mPidsSelfLocked.remove(app.pid);
1825                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1826            }
1827            app.pid = 0;
1828        }
1829
1830        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1831                "startProcessLocked removing on hold: " + app);
1832        mProcessesOnHold.remove(app);
1833
1834        updateCpuStats();
1835
1836        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1837        mProcDeaths[0] = 0;
1838
1839        try {
1840            int uid = app.info.uid;
1841            int[] gids = null;
1842            try {
1843                gids = mContext.getPackageManager().getPackageGids(
1844                        app.info.packageName);
1845            } catch (PackageManager.NameNotFoundException e) {
1846                Slog.w(TAG, "Unable to retrieve gids", e);
1847            }
1848            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1849                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1850                        && mTopComponent != null
1851                        && app.processName.equals(mTopComponent.getPackageName())) {
1852                    uid = 0;
1853                }
1854                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1855                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1856                    uid = 0;
1857                }
1858            }
1859            int debugFlags = 0;
1860            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1861                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1862            }
1863            // Run the app in safe mode if its manifest requests so or the
1864            // system is booted in safe mode.
1865            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1866                Zygote.systemInSafeMode == true) {
1867                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1868            }
1869            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1870                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1871            }
1872            if ("1".equals(SystemProperties.get("debug.assert"))) {
1873                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1874            }
1875            int pid = Process.start("android.app.ActivityThread",
1876                    mSimpleProcessManagement ? app.processName : null, uid, uid,
1877                    gids, debugFlags, null);
1878            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1879            synchronized (bs) {
1880                if (bs.isOnBattery()) {
1881                    app.batteryStats.incStartsLocked();
1882                }
1883            }
1884
1885            EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
1886                    app.processName, hostingType,
1887                    hostingNameStr != null ? hostingNameStr : "");
1888
1889            if (app.persistent) {
1890                Watchdog.getInstance().processStarted(app.processName, pid);
1891            }
1892
1893            StringBuilder buf = mStringBuilder;
1894            buf.setLength(0);
1895            buf.append("Start proc ");
1896            buf.append(app.processName);
1897            buf.append(" for ");
1898            buf.append(hostingType);
1899            if (hostingNameStr != null) {
1900                buf.append(" ");
1901                buf.append(hostingNameStr);
1902            }
1903            buf.append(": pid=");
1904            buf.append(pid);
1905            buf.append(" uid=");
1906            buf.append(uid);
1907            buf.append(" gids={");
1908            if (gids != null) {
1909                for (int gi=0; gi<gids.length; gi++) {
1910                    if (gi != 0) buf.append(", ");
1911                    buf.append(gids[gi]);
1912
1913                }
1914            }
1915            buf.append("}");
1916            Slog.i(TAG, buf.toString());
1917            if (pid == 0 || pid == MY_PID) {
1918                // Processes are being emulated with threads.
1919                app.pid = MY_PID;
1920                app.removed = false;
1921                mStartingProcesses.add(app);
1922            } else if (pid > 0) {
1923                app.pid = pid;
1924                app.removed = false;
1925                synchronized (mPidsSelfLocked) {
1926                    this.mPidsSelfLocked.put(pid, app);
1927                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1928                    msg.obj = app;
1929                    mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
1930                }
1931            } else {
1932                app.pid = 0;
1933                RuntimeException e = new RuntimeException(
1934                        "Failure starting process " + app.processName
1935                        + ": returned pid=" + pid);
1936                Slog.e(TAG, e.getMessage(), e);
1937            }
1938        } catch (RuntimeException e) {
1939            // XXX do better error recovery.
1940            app.pid = 0;
1941            Slog.e(TAG, "Failure starting process " + app.processName, e);
1942        }
1943    }
1944
1945    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
1946        if (resumed) {
1947            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
1948        } else {
1949            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
1950        }
1951    }
1952
1953    boolean startHomeActivityLocked() {
1954        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1955                && mTopAction == null) {
1956            // We are running in factory test mode, but unable to find
1957            // the factory test app, so just sit around displaying the
1958            // error message and don't try to start anything.
1959            return false;
1960        }
1961        Intent intent = new Intent(
1962            mTopAction,
1963            mTopData != null ? Uri.parse(mTopData) : null);
1964        intent.setComponent(mTopComponent);
1965        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
1966            intent.addCategory(Intent.CATEGORY_HOME);
1967        }
1968        ActivityInfo aInfo =
1969            intent.resolveActivityInfo(mContext.getPackageManager(),
1970                    STOCK_PM_FLAGS);
1971        if (aInfo != null) {
1972            intent.setComponent(new ComponentName(
1973                    aInfo.applicationInfo.packageName, aInfo.name));
1974            // Don't do this if the home app is currently being
1975            // instrumented.
1976            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
1977                    aInfo.applicationInfo.uid);
1978            if (app == null || app.instrumentationClass == null) {
1979                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
1980                mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
1981                        null, null, 0, 0, 0, false, false);
1982            }
1983        }
1984
1985
1986        return true;
1987    }
1988
1989    /**
1990     * Starts the "new version setup screen" if appropriate.
1991     */
1992    void startSetupActivityLocked() {
1993        // Only do this once per boot.
1994        if (mCheckedForSetup) {
1995            return;
1996        }
1997
1998        // We will show this screen if the current one is a different
1999        // version than the last one shown, and we are not running in
2000        // low-level factory test mode.
2001        final ContentResolver resolver = mContext.getContentResolver();
2002        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2003                Settings.Secure.getInt(resolver,
2004                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2005            mCheckedForSetup = true;
2006
2007            // See if we should be showing the platform update setup UI.
2008            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2009            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2010                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2011
2012            // We don't allow third party apps to replace this.
2013            ResolveInfo ri = null;
2014            for (int i=0; ris != null && i<ris.size(); i++) {
2015                if ((ris.get(i).activityInfo.applicationInfo.flags
2016                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2017                    ri = ris.get(i);
2018                    break;
2019                }
2020            }
2021
2022            if (ri != null) {
2023                String vers = ri.activityInfo.metaData != null
2024                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2025                        : null;
2026                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2027                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2028                            Intent.METADATA_SETUP_VERSION);
2029                }
2030                String lastVers = Settings.Secure.getString(
2031                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2032                if (vers != null && !vers.equals(lastVers)) {
2033                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2034                    intent.setComponent(new ComponentName(
2035                            ri.activityInfo.packageName, ri.activityInfo.name));
2036                    mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
2037                            null, null, 0, 0, 0, false, false);
2038                }
2039            }
2040        }
2041    }
2042
2043    void reportResumedActivityLocked(ActivityRecord r) {
2044        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2045
2046        final int identHash = System.identityHashCode(r);
2047        updateUsageStats(r, true);
2048
2049        int i = mWatchers.beginBroadcast();
2050        while (i > 0) {
2051            i--;
2052            IActivityWatcher w = mWatchers.getBroadcastItem(i);
2053            if (w != null) {
2054                try {
2055                    w.activityResuming(identHash);
2056                } catch (RemoteException e) {
2057                }
2058            }
2059        }
2060        mWatchers.finishBroadcast();
2061    }
2062
2063    final void doPendingActivityLaunchesLocked(boolean doResume) {
2064        final int N = mPendingActivityLaunches.size();
2065        if (N <= 0) {
2066            return;
2067        }
2068        for (int i=0; i<N; i++) {
2069            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2070            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2071                    pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2072                    doResume && i == (N-1));
2073        }
2074        mPendingActivityLaunches.clear();
2075    }
2076
2077    public final int startActivity(IApplicationThread caller,
2078            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2079            int grantedMode, IBinder resultTo,
2080            String resultWho, int requestCode, boolean onlyIfNeeded,
2081            boolean debug) {
2082        return mMainStack.startActivityMayWait(caller, intent, resolvedType,
2083                grantedUriPermissions, grantedMode, resultTo, resultWho,
2084                requestCode, onlyIfNeeded, debug, null, null);
2085    }
2086
2087    public final WaitResult startActivityAndWait(IApplicationThread caller,
2088            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2089            int grantedMode, IBinder resultTo,
2090            String resultWho, int requestCode, boolean onlyIfNeeded,
2091            boolean debug) {
2092        WaitResult res = new WaitResult();
2093        mMainStack.startActivityMayWait(caller, intent, resolvedType,
2094                grantedUriPermissions, grantedMode, resultTo, resultWho,
2095                requestCode, onlyIfNeeded, debug, res, null);
2096        return res;
2097    }
2098
2099    public final int startActivityWithConfig(IApplicationThread caller,
2100            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2101            int grantedMode, IBinder resultTo,
2102            String resultWho, int requestCode, boolean onlyIfNeeded,
2103            boolean debug, Configuration config) {
2104        return mMainStack.startActivityMayWait(caller, intent, resolvedType,
2105                grantedUriPermissions, grantedMode, resultTo, resultWho,
2106                requestCode, onlyIfNeeded, debug, null, config);
2107    }
2108
2109     public int startActivityIntentSender(IApplicationThread caller,
2110            IntentSender intent, Intent fillInIntent, String resolvedType,
2111            IBinder resultTo, String resultWho, int requestCode,
2112            int flagsMask, int flagsValues) {
2113        // Refuse possible leaked file descriptors
2114        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2115            throw new IllegalArgumentException("File descriptors passed in Intent");
2116        }
2117
2118        IIntentSender sender = intent.getTarget();
2119        if (!(sender instanceof PendingIntentRecord)) {
2120            throw new IllegalArgumentException("Bad PendingIntent object");
2121        }
2122
2123        PendingIntentRecord pir = (PendingIntentRecord)sender;
2124
2125        synchronized (this) {
2126            // If this is coming from the currently resumed activity, it is
2127            // effectively saying that app switches are allowed at this point.
2128            if (mMainStack.mResumedActivity != null
2129                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2130                            Binder.getCallingUid()) {
2131                mAppSwitchesAllowedTime = 0;
2132            }
2133        }
2134
2135        return pir.sendInner(0, fillInIntent, resolvedType,
2136                null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2137    }
2138
2139    public boolean startNextMatchingActivity(IBinder callingActivity,
2140            Intent intent) {
2141        // Refuse possible leaked file descriptors
2142        if (intent != null && intent.hasFileDescriptors() == true) {
2143            throw new IllegalArgumentException("File descriptors passed in Intent");
2144        }
2145
2146        synchronized (this) {
2147            int index = mMainStack.indexOfTokenLocked(callingActivity);
2148            if (index < 0) {
2149                return false;
2150            }
2151            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
2152            if (r.app == null || r.app.thread == null) {
2153                // The caller is not running...  d'oh!
2154                return false;
2155            }
2156            intent = new Intent(intent);
2157            // The caller is not allowed to change the data.
2158            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2159            // And we are resetting to find the next component...
2160            intent.setComponent(null);
2161
2162            ActivityInfo aInfo = null;
2163            try {
2164                List<ResolveInfo> resolves =
2165                    AppGlobals.getPackageManager().queryIntentActivities(
2166                            intent, r.resolvedType,
2167                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
2168
2169                // Look for the original activity in the list...
2170                final int N = resolves != null ? resolves.size() : 0;
2171                for (int i=0; i<N; i++) {
2172                    ResolveInfo rInfo = resolves.get(i);
2173                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2174                            && rInfo.activityInfo.name.equals(r.info.name)) {
2175                        // We found the current one...  the next matching is
2176                        // after it.
2177                        i++;
2178                        if (i<N) {
2179                            aInfo = resolves.get(i).activityInfo;
2180                        }
2181                        break;
2182                    }
2183                }
2184            } catch (RemoteException e) {
2185            }
2186
2187            if (aInfo == null) {
2188                // Nobody who is next!
2189                return false;
2190            }
2191
2192            intent.setComponent(new ComponentName(
2193                    aInfo.applicationInfo.packageName, aInfo.name));
2194            intent.setFlags(intent.getFlags()&~(
2195                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2196                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2197                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2198                    Intent.FLAG_ACTIVITY_NEW_TASK));
2199
2200            // Okay now we need to start the new activity, replacing the
2201            // currently running activity.  This is a little tricky because
2202            // we want to start the new one as if the current one is finished,
2203            // but not finish the current one first so that there is no flicker.
2204            // And thus...
2205            final boolean wasFinishing = r.finishing;
2206            r.finishing = true;
2207
2208            // Propagate reply information over to the new activity.
2209            final ActivityRecord resultTo = r.resultTo;
2210            final String resultWho = r.resultWho;
2211            final int requestCode = r.requestCode;
2212            r.resultTo = null;
2213            if (resultTo != null) {
2214                resultTo.removeResultsLocked(r, resultWho, requestCode);
2215            }
2216
2217            final long origId = Binder.clearCallingIdentity();
2218            // XXX we are not dealing with propagating grantedUriPermissions...
2219            // those are not yet exposed to user code, so there is no need.
2220            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2221                    r.resolvedType, null, 0, aInfo, resultTo, resultWho,
2222                    requestCode, -1, r.launchedFromUid, false, false);
2223            Binder.restoreCallingIdentity(origId);
2224
2225            r.finishing = wasFinishing;
2226            if (res != START_SUCCESS) {
2227                return false;
2228            }
2229            return true;
2230        }
2231    }
2232
2233    public final int startActivityInPackage(int uid,
2234            Intent intent, String resolvedType, IBinder resultTo,
2235            String resultWho, int requestCode, boolean onlyIfNeeded) {
2236
2237        // This is so super not safe, that only the system (or okay root)
2238        // can do it.
2239        final int callingUid = Binder.getCallingUid();
2240        if (callingUid != 0 && callingUid != Process.myUid()) {
2241            throw new SecurityException(
2242                    "startActivityInPackage only available to the system");
2243        }
2244
2245        final boolean componentSpecified = intent.getComponent() != null;
2246
2247        // Don't modify the client's object!
2248        intent = new Intent(intent);
2249
2250        // Collect information about the target of the Intent.
2251        ActivityInfo aInfo;
2252        try {
2253            ResolveInfo rInfo =
2254                AppGlobals.getPackageManager().resolveIntent(
2255                        intent, resolvedType,
2256                        PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
2257            aInfo = rInfo != null ? rInfo.activityInfo : null;
2258        } catch (RemoteException e) {
2259            aInfo = null;
2260        }
2261
2262        if (aInfo != null) {
2263            // Store the found target back into the intent, because now that
2264            // we have it we never want to do this again.  For example, if the
2265            // user navigates back to this point in the history, we should
2266            // always restart the exact same activity.
2267            intent.setComponent(new ComponentName(
2268                    aInfo.applicationInfo.packageName, aInfo.name));
2269        }
2270
2271        synchronized(this) {
2272            return mMainStack.startActivityLocked(null, intent, resolvedType,
2273                    null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid,
2274                    onlyIfNeeded, componentSpecified);
2275        }
2276    }
2277
2278    final void addRecentTaskLocked(TaskRecord task) {
2279        // Remove any existing entries that are the same kind of task.
2280        int N = mRecentTasks.size();
2281        for (int i=0; i<N; i++) {
2282            TaskRecord tr = mRecentTasks.get(i);
2283            if ((task.affinity != null && task.affinity.equals(tr.affinity))
2284                    || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2285                mRecentTasks.remove(i);
2286                i--;
2287                N--;
2288                if (task.intent == null) {
2289                    // If the new recent task we are adding is not fully
2290                    // specified, then replace it with the existing recent task.
2291                    task = tr;
2292                }
2293            }
2294        }
2295        if (N >= MAX_RECENT_TASKS) {
2296            mRecentTasks.remove(N-1);
2297        }
2298        mRecentTasks.add(0, task);
2299    }
2300
2301    public void setRequestedOrientation(IBinder token,
2302            int requestedOrientation) {
2303        synchronized (this) {
2304            int index = mMainStack.indexOfTokenLocked(token);
2305            if (index < 0) {
2306                return;
2307            }
2308            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
2309            final long origId = Binder.clearCallingIdentity();
2310            mWindowManager.setAppOrientation(r, requestedOrientation);
2311            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2312                    mConfiguration,
2313                    r.mayFreezeScreenLocked(r.app) ? r : null);
2314            if (config != null) {
2315                r.frozenBeforeDestroy = true;
2316                if (!updateConfigurationLocked(config, r)) {
2317                    mMainStack.resumeTopActivityLocked(null);
2318                }
2319            }
2320            Binder.restoreCallingIdentity(origId);
2321        }
2322    }
2323
2324    public int getRequestedOrientation(IBinder token) {
2325        synchronized (this) {
2326            int index = mMainStack.indexOfTokenLocked(token);
2327            if (index < 0) {
2328                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2329            }
2330            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
2331            return mWindowManager.getAppOrientation(r);
2332        }
2333    }
2334
2335    /**
2336     * This is the internal entry point for handling Activity.finish().
2337     *
2338     * @param token The Binder token referencing the Activity we want to finish.
2339     * @param resultCode Result code, if any, from this Activity.
2340     * @param resultData Result data (Intent), if any, from this Activity.
2341     *
2342     * @return Returns true if the activity successfully finished, or false if it is still running.
2343     */
2344    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2345        // Refuse possible leaked file descriptors
2346        if (resultData != null && resultData.hasFileDescriptors() == true) {
2347            throw new IllegalArgumentException("File descriptors passed in Intent");
2348        }
2349
2350        synchronized(this) {
2351            if (mController != null) {
2352                // Find the first activity that is not finishing.
2353                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2354                if (next != null) {
2355                    // ask watcher if this is allowed
2356                    boolean resumeOK = true;
2357                    try {
2358                        resumeOK = mController.activityResuming(next.packageName);
2359                    } catch (RemoteException e) {
2360                        mController = null;
2361                    }
2362
2363                    if (!resumeOK) {
2364                        return false;
2365                    }
2366                }
2367            }
2368            final long origId = Binder.clearCallingIdentity();
2369            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2370                    resultData, "app-request");
2371            Binder.restoreCallingIdentity(origId);
2372            return res;
2373        }
2374    }
2375
2376    public final void finishHeavyWeightApp() {
2377        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2378                != PackageManager.PERMISSION_GRANTED) {
2379            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2380                    + Binder.getCallingPid()
2381                    + ", uid=" + Binder.getCallingUid()
2382                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2383            Slog.w(TAG, msg);
2384            throw new SecurityException(msg);
2385        }
2386
2387        synchronized(this) {
2388            if (mHeavyWeightProcess == null) {
2389                return;
2390            }
2391
2392            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2393                    mHeavyWeightProcess.activities);
2394            for (int i=0; i<activities.size(); i++) {
2395                ActivityRecord r = activities.get(i);
2396                if (!r.finishing) {
2397                    int index = mMainStack.indexOfTokenLocked(r);
2398                    if (index >= 0) {
2399                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2400                                null, "finish-heavy");
2401                    }
2402                }
2403            }
2404
2405            mHeavyWeightProcess = null;
2406            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2407        }
2408    }
2409
2410    public void crashApplication(int uid, int initialPid, String packageName,
2411            String message) {
2412        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2413                != PackageManager.PERMISSION_GRANTED) {
2414            String msg = "Permission Denial: crashApplication() from pid="
2415                    + Binder.getCallingPid()
2416                    + ", uid=" + Binder.getCallingUid()
2417                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2418            Slog.w(TAG, msg);
2419            throw new SecurityException(msg);
2420        }
2421
2422        synchronized(this) {
2423            ProcessRecord proc = null;
2424
2425            // Figure out which process to kill.  We don't trust that initialPid
2426            // still has any relation to current pids, so must scan through the
2427            // list.
2428            synchronized (mPidsSelfLocked) {
2429                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2430                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2431                    if (p.info.uid != uid) {
2432                        continue;
2433                    }
2434                    if (p.pid == initialPid) {
2435                        proc = p;
2436                        break;
2437                    }
2438                    for (String str : p.pkgList) {
2439                        if (str.equals(packageName)) {
2440                            proc = p;
2441                        }
2442                    }
2443                }
2444            }
2445
2446            if (proc == null) {
2447                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2448                        + " initialPid=" + initialPid
2449                        + " packageName=" + packageName);
2450                return;
2451            }
2452
2453            if (proc.thread != null) {
2454                if (proc.pid == Process.myPid()) {
2455                    Log.w(TAG, "crashApplication: trying to crash self!");
2456                    return;
2457                }
2458                long ident = Binder.clearCallingIdentity();
2459                try {
2460                    proc.thread.scheduleCrash(message);
2461                } catch (RemoteException e) {
2462                }
2463                Binder.restoreCallingIdentity(ident);
2464            }
2465        }
2466    }
2467
2468    public final void finishSubActivity(IBinder token, String resultWho,
2469            int requestCode) {
2470        synchronized(this) {
2471            int index = mMainStack.indexOfTokenLocked(token);
2472            if (index < 0) {
2473                return;
2474            }
2475            ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
2476
2477            final long origId = Binder.clearCallingIdentity();
2478
2479            int i;
2480            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2481                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2482                if (r.resultTo == self && r.requestCode == requestCode) {
2483                    if ((r.resultWho == null && resultWho == null) ||
2484                        (r.resultWho != null && r.resultWho.equals(resultWho))) {
2485                        mMainStack.finishActivityLocked(r, i,
2486                                Activity.RESULT_CANCELED, null, "request-sub");
2487                    }
2488                }
2489            }
2490
2491            Binder.restoreCallingIdentity(origId);
2492        }
2493    }
2494
2495    public boolean willActivityBeVisible(IBinder token) {
2496        synchronized(this) {
2497            int i;
2498            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2499                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2500                if (r == token) {
2501                    return true;
2502                }
2503                if (r.fullscreen && !r.finishing) {
2504                    return false;
2505                }
2506            }
2507            return true;
2508        }
2509    }
2510
2511    public void overridePendingTransition(IBinder token, String packageName,
2512            int enterAnim, int exitAnim) {
2513        synchronized(this) {
2514            int index = mMainStack.indexOfTokenLocked(token);
2515            if (index < 0) {
2516                return;
2517            }
2518            ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
2519
2520            final long origId = Binder.clearCallingIdentity();
2521
2522            if (self.state == ActivityState.RESUMED
2523                    || self.state == ActivityState.PAUSING) {
2524                mWindowManager.overridePendingAppTransition(packageName,
2525                        enterAnim, exitAnim);
2526            }
2527
2528            Binder.restoreCallingIdentity(origId);
2529        }
2530    }
2531
2532    /**
2533     * Main function for removing an existing process from the activity manager
2534     * as a result of that process going away.  Clears out all connections
2535     * to the process.
2536     */
2537    private final void handleAppDiedLocked(ProcessRecord app,
2538            boolean restarting) {
2539        cleanUpApplicationRecordLocked(app, restarting, -1);
2540        if (!restarting) {
2541            mLruProcesses.remove(app);
2542        }
2543
2544        // Just in case...
2545        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2546            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2547            mMainStack.mPausingActivity = null;
2548        }
2549        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2550            mMainStack.mLastPausedActivity = null;
2551        }
2552
2553        // Remove this application's activities from active lists.
2554        mMainStack.removeHistoryRecordsForAppLocked(app);
2555
2556        boolean atTop = true;
2557        boolean hasVisibleActivities = false;
2558
2559        // Clean out the history list.
2560        int i = mMainStack.mHistory.size();
2561        if (localLOGV) Slog.v(
2562            TAG, "Removing app " + app + " from history with " + i + " entries");
2563        while (i > 0) {
2564            i--;
2565            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2566            if (localLOGV) Slog.v(
2567                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2568            if (r.app == app) {
2569                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2570                    if (localLOGV) Slog.v(
2571                        TAG, "Removing this entry!  frozen=" + r.haveState
2572                        + " finishing=" + r.finishing);
2573                    mMainStack.mHistory.remove(i);
2574
2575                    r.inHistory = false;
2576                    mWindowManager.removeAppToken(r);
2577                    if (VALIDATE_TOKENS) {
2578                        mWindowManager.validateAppTokens(mMainStack.mHistory);
2579                    }
2580                    r.removeUriPermissionsLocked();
2581
2582                } else {
2583                    // We have the current state for this activity, so
2584                    // it can be restarted later when needed.
2585                    if (localLOGV) Slog.v(
2586                        TAG, "Keeping entry, setting app to null");
2587                    if (r.visible) {
2588                        hasVisibleActivities = true;
2589                    }
2590                    r.app = null;
2591                    r.nowVisible = false;
2592                    if (!r.haveState) {
2593                        r.icicle = null;
2594                    }
2595                }
2596
2597                r.stack.cleanUpActivityLocked(r, true);
2598                r.state = ActivityState.STOPPED;
2599            }
2600            atTop = false;
2601        }
2602
2603        app.activities.clear();
2604
2605        if (app.instrumentationClass != null) {
2606            Slog.w(TAG, "Crash of app " + app.processName
2607                  + " running instrumentation " + app.instrumentationClass);
2608            Bundle info = new Bundle();
2609            info.putString("shortMsg", "Process crashed.");
2610            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2611        }
2612
2613        if (!restarting) {
2614            if (!mMainStack.resumeTopActivityLocked(null)) {
2615                // If there was nothing to resume, and we are not already
2616                // restarting this process, but there is a visible activity that
2617                // is hosted by the process...  then make sure all visible
2618                // activities are running, taking care of restarting this
2619                // process.
2620                if (hasVisibleActivities) {
2621                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2622                }
2623            }
2624        }
2625    }
2626
2627    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2628        IBinder threadBinder = thread.asBinder();
2629
2630        // Find the application record.
2631        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2632            ProcessRecord rec = mLruProcesses.get(i);
2633            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2634                return i;
2635            }
2636        }
2637        return -1;
2638    }
2639
2640    final ProcessRecord getRecordForAppLocked(
2641            IApplicationThread thread) {
2642        if (thread == null) {
2643            return null;
2644        }
2645
2646        int appIndex = getLRURecordIndexForAppLocked(thread);
2647        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2648    }
2649
2650    final void appDiedLocked(ProcessRecord app, int pid,
2651            IApplicationThread thread) {
2652
2653        mProcDeaths[0]++;
2654
2655        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2656        synchronized (stats) {
2657            stats.noteProcessDiedLocked(app.info.uid, pid);
2658        }
2659
2660        // Clean up already done if the process has been re-started.
2661        if (app.pid == pid && app.thread != null &&
2662                app.thread.asBinder() == thread.asBinder()) {
2663            if (!app.killedBackground) {
2664                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2665                        + ") has died.");
2666            }
2667            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2668            if (localLOGV) Slog.v(
2669                TAG, "Dying app: " + app + ", pid: " + pid
2670                + ", thread: " + thread.asBinder());
2671            boolean doLowMem = app.instrumentationClass == null;
2672            handleAppDiedLocked(app, false);
2673
2674            if (doLowMem) {
2675                // If there are no longer any background processes running,
2676                // and the app that died was not running instrumentation,
2677                // then tell everyone we are now low on memory.
2678                boolean haveBg = false;
2679                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2680                    ProcessRecord rec = mLruProcesses.get(i);
2681                    if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
2682                        haveBg = true;
2683                        break;
2684                    }
2685                }
2686
2687                if (!haveBg) {
2688                    Slog.i(TAG, "Low Memory: No more background processes.");
2689                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2690                    long now = SystemClock.uptimeMillis();
2691                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2692                        ProcessRecord rec = mLruProcesses.get(i);
2693                        if (rec != app && rec.thread != null &&
2694                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2695                            // The low memory report is overriding any current
2696                            // state for a GC request.  Make sure to do
2697                            // heavy/important/visible/foreground processes first.
2698                            if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) {
2699                                rec.lastRequestedGc = 0;
2700                            } else {
2701                                rec.lastRequestedGc = rec.lastLowMemory;
2702                            }
2703                            rec.reportLowMemory = true;
2704                            rec.lastLowMemory = now;
2705                            mProcessesToGc.remove(rec);
2706                            addProcessToGcListLocked(rec);
2707                        }
2708                    }
2709                    scheduleAppGcsLocked();
2710                }
2711            }
2712        } else if (app.pid != pid) {
2713            // A new process has already been started.
2714            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2715                    + ") has died and restarted (pid " + app.pid + ").");
2716            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2717        } else if (DEBUG_PROCESSES) {
2718            Slog.d(TAG, "Received spurious death notification for thread "
2719                    + thread.asBinder());
2720        }
2721    }
2722
2723    /**
2724     * If a stack trace dump file is configured, dump process stack traces.
2725     * @param clearTraces causes the dump file to be erased prior to the new
2726     *    traces being written, if true; when false, the new traces will be
2727     *    appended to any existing file content.
2728     * @param firstPids of dalvik VM processes to dump stack traces for first
2729     * @param lastPids of dalvik VM processes to dump stack traces for last
2730     * @return file containing stack traces, or null if no dump file is configured
2731     */
2732    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2733            ProcessStats processStats, SparseArray<Boolean> lastPids) {
2734        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2735        if (tracesPath == null || tracesPath.length() == 0) {
2736            return null;
2737        }
2738
2739        File tracesFile = new File(tracesPath);
2740        try {
2741            File tracesDir = tracesFile.getParentFile();
2742            if (!tracesDir.exists()) tracesFile.mkdirs();
2743            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
2744
2745            if (clearTraces && tracesFile.exists()) tracesFile.delete();
2746            tracesFile.createNewFile();
2747            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2748        } catch (IOException e) {
2749            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
2750            return null;
2751        }
2752
2753        // Use a FileObserver to detect when traces finish writing.
2754        // The order of traces is considered important to maintain for legibility.
2755        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2756            public synchronized void onEvent(int event, String path) { notify(); }
2757        };
2758
2759        try {
2760            observer.startWatching();
2761
2762            // First collect all of the stacks of the most important pids.
2763            try {
2764                int num = firstPids.size();
2765                for (int i = 0; i < num; i++) {
2766                    synchronized (observer) {
2767                        Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2768                        observer.wait(200);  // Wait for write-close, give up after 200msec
2769                    }
2770                }
2771            } catch (InterruptedException e) {
2772                Log.wtf(TAG, e);
2773            }
2774
2775            // Next measure CPU usage.
2776            if (processStats != null) {
2777                processStats.init();
2778                System.gc();
2779                processStats.update();
2780                try {
2781                    synchronized (processStats) {
2782                        processStats.wait(500); // measure over 1/2 second.
2783                    }
2784                } catch (InterruptedException e) {
2785                }
2786                processStats.update();
2787
2788                // We'll take the stack crawls of just the top apps using CPU.
2789                final int N = processStats.countWorkingStats();
2790                int numProcs = 0;
2791                for (int i=0; i<N && numProcs<5; i++) {
2792                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
2793                    if (lastPids.indexOfKey(stats.pid) >= 0) {
2794                        numProcs++;
2795                        try {
2796                            synchronized (observer) {
2797                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2798                                observer.wait(200);  // Wait for write-close, give up after 200msec
2799                            }
2800                        } catch (InterruptedException e) {
2801                            Log.wtf(TAG, e);
2802                        }
2803
2804                    }
2805                }
2806            }
2807
2808            return tracesFile;
2809
2810        } finally {
2811            observer.stopWatching();
2812        }
2813    }
2814
2815    private final class AppNotResponding implements Runnable {
2816        private final ProcessRecord mApp;
2817        private final String mAnnotation;
2818
2819        public AppNotResponding(ProcessRecord app, String annotation) {
2820            mApp = app;
2821            mAnnotation = annotation;
2822        }
2823
2824        @Override
2825        public void run() {
2826            appNotResponding(mApp, null, null, mAnnotation);
2827        }
2828    }
2829
2830    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2831            ActivityRecord parent, final String annotation) {
2832        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2833        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2834
2835        if (mController != null) {
2836            try {
2837                // 0 == continue, -1 = kill process immediately
2838                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2839                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2840            } catch (RemoteException e) {
2841                mController = null;
2842            }
2843        }
2844
2845        long anrTime = SystemClock.uptimeMillis();
2846        if (MONITOR_CPU_USAGE) {
2847            updateCpuStatsNow();
2848        }
2849
2850        synchronized (this) {
2851            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2852            if (mShuttingDown) {
2853                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2854                return;
2855            } else if (app.notResponding) {
2856                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2857                return;
2858            } else if (app.crashing) {
2859                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2860                return;
2861            }
2862
2863            // In case we come through here for the same app before completing
2864            // this one, mark as anring now so we will bail out.
2865            app.notResponding = true;
2866
2867            // Log the ANR to the event log.
2868            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2869                    annotation);
2870
2871            // Dump thread traces as quickly as we can, starting with "interesting" processes.
2872            firstPids.add(app.pid);
2873
2874            int parentPid = app.pid;
2875            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
2876            if (parentPid != app.pid) firstPids.add(parentPid);
2877
2878            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
2879
2880            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2881                ProcessRecord r = mLruProcesses.get(i);
2882                if (r != null && r.thread != null) {
2883                    int pid = r.pid;
2884                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2885                        if (r.persistent) {
2886                            firstPids.add(pid);
2887                        } else {
2888                            lastPids.put(pid, Boolean.TRUE);
2889                        }
2890                    }
2891                }
2892            }
2893        }
2894
2895        // Log the ANR to the main log.
2896        StringBuilder info = mStringBuilder;
2897        info.setLength(0);
2898        info.append("ANR in ").append(app.processName);
2899        if (activity != null && activity.shortComponentName != null) {
2900            info.append(" (").append(activity.shortComponentName).append(")");
2901        }
2902        info.append("\n");
2903        if (annotation != null) {
2904            info.append("Reason: ").append(annotation).append("\n");
2905        }
2906        if (parent != null && parent != activity) {
2907            info.append("Parent: ").append(parent.shortComponentName).append("\n");
2908        }
2909
2910        final ProcessStats processStats = new ProcessStats(true);
2911
2912        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
2913
2914        String cpuInfo = null;
2915        if (MONITOR_CPU_USAGE) {
2916            updateCpuStatsNow();
2917            synchronized (mProcessStatsThread) {
2918                cpuInfo = mProcessStats.printCurrentState(anrTime);
2919            }
2920            info.append(processStats.printCurrentLoad());
2921            info.append(cpuInfo);
2922        }
2923
2924        info.append(processStats.printCurrentState(anrTime));
2925
2926        Slog.e(TAG, info.toString());
2927        if (tracesFile == null) {
2928            // There is no trace file, so dump (only) the alleged culprit's threads to the log
2929            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
2930        }
2931
2932        addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
2933
2934        if (mController != null) {
2935            try {
2936                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
2937                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
2938                if (res != 0) {
2939                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2940                    return;
2941                }
2942            } catch (RemoteException e) {
2943                mController = null;
2944            }
2945        }
2946
2947        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
2948        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
2949                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
2950
2951        synchronized (this) {
2952            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
2953                Process.killProcess(app.pid);
2954                return;
2955            }
2956
2957            // Set the app's notResponding state, and look up the errorReportReceiver
2958            makeAppNotRespondingLocked(app,
2959                    activity != null ? activity.shortComponentName : null,
2960                    annotation != null ? "ANR " + annotation : "ANR",
2961                    info.toString());
2962
2963            // Bring up the infamous App Not Responding dialog
2964            Message msg = Message.obtain();
2965            HashMap map = new HashMap();
2966            msg.what = SHOW_NOT_RESPONDING_MSG;
2967            msg.obj = map;
2968            map.put("app", app);
2969            if (activity != null) {
2970                map.put("activity", activity);
2971            }
2972
2973            mHandler.sendMessage(msg);
2974        }
2975    }
2976
2977    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
2978        if (!mLaunchWarningShown) {
2979            mLaunchWarningShown = true;
2980            mHandler.post(new Runnable() {
2981                @Override
2982                public void run() {
2983                    synchronized (ActivityManagerService.this) {
2984                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
2985                        d.show();
2986                        mHandler.postDelayed(new Runnable() {
2987                            @Override
2988                            public void run() {
2989                                synchronized (ActivityManagerService.this) {
2990                                    d.dismiss();
2991                                    mLaunchWarningShown = false;
2992                                }
2993                            }
2994                        }, 4000);
2995                    }
2996                }
2997            });
2998        }
2999    }
3000
3001    public boolean clearApplicationUserData(final String packageName,
3002            final IPackageDataObserver observer) {
3003        int uid = Binder.getCallingUid();
3004        int pid = Binder.getCallingPid();
3005        long callingId = Binder.clearCallingIdentity();
3006        try {
3007            IPackageManager pm = AppGlobals.getPackageManager();
3008            int pkgUid = -1;
3009            synchronized(this) {
3010                try {
3011                    pkgUid = pm.getPackageUid(packageName);
3012                } catch (RemoteException e) {
3013                }
3014                if (pkgUid == -1) {
3015                    Slog.w(TAG, "Invalid packageName:" + packageName);
3016                    return false;
3017                }
3018                if (uid == pkgUid || checkComponentPermission(
3019                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3020                        pid, uid, -1)
3021                        == PackageManager.PERMISSION_GRANTED) {
3022                    forceStopPackageLocked(packageName, pkgUid);
3023                } else {
3024                    throw new SecurityException(pid+" does not have permission:"+
3025                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3026                                    "for process:"+packageName);
3027                }
3028            }
3029
3030            try {
3031                //clear application user data
3032                pm.clearApplicationUserData(packageName, observer);
3033                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3034                        Uri.fromParts("package", packageName, null));
3035                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3036                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3037                        null, null, 0, null, null, null, false, false);
3038            } catch (RemoteException e) {
3039            }
3040        } finally {
3041            Binder.restoreCallingIdentity(callingId);
3042        }
3043        return true;
3044    }
3045
3046    public void killBackgroundProcesses(final String packageName) {
3047        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3048                != PackageManager.PERMISSION_GRANTED &&
3049                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3050                        != PackageManager.PERMISSION_GRANTED) {
3051            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3052                    + Binder.getCallingPid()
3053                    + ", uid=" + Binder.getCallingUid()
3054                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3055            Slog.w(TAG, msg);
3056            throw new SecurityException(msg);
3057        }
3058
3059        long callingId = Binder.clearCallingIdentity();
3060        try {
3061            IPackageManager pm = AppGlobals.getPackageManager();
3062            int pkgUid = -1;
3063            synchronized(this) {
3064                try {
3065                    pkgUid = pm.getPackageUid(packageName);
3066                } catch (RemoteException e) {
3067                }
3068                if (pkgUid == -1) {
3069                    Slog.w(TAG, "Invalid packageName: " + packageName);
3070                    return;
3071                }
3072                killPackageProcessesLocked(packageName, pkgUid,
3073                        SECONDARY_SERVER_ADJ, false, true);
3074            }
3075        } finally {
3076            Binder.restoreCallingIdentity(callingId);
3077        }
3078    }
3079
3080    public void forceStopPackage(final String packageName) {
3081        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3082                != PackageManager.PERMISSION_GRANTED) {
3083            String msg = "Permission Denial: forceStopPackage() from pid="
3084                    + Binder.getCallingPid()
3085                    + ", uid=" + Binder.getCallingUid()
3086                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3087            Slog.w(TAG, msg);
3088            throw new SecurityException(msg);
3089        }
3090
3091        long callingId = Binder.clearCallingIdentity();
3092        try {
3093            IPackageManager pm = AppGlobals.getPackageManager();
3094            int pkgUid = -1;
3095            synchronized(this) {
3096                try {
3097                    pkgUid = pm.getPackageUid(packageName);
3098                } catch (RemoteException e) {
3099                }
3100                if (pkgUid == -1) {
3101                    Slog.w(TAG, "Invalid packageName: " + packageName);
3102                    return;
3103                }
3104                forceStopPackageLocked(packageName, pkgUid);
3105            }
3106        } finally {
3107            Binder.restoreCallingIdentity(callingId);
3108        }
3109    }
3110
3111    /*
3112     * The pkg name and uid have to be specified.
3113     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3114     */
3115    public void killApplicationWithUid(String pkg, int uid) {
3116        if (pkg == null) {
3117            return;
3118        }
3119        // Make sure the uid is valid.
3120        if (uid < 0) {
3121            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3122            return;
3123        }
3124        int callerUid = Binder.getCallingUid();
3125        // Only the system server can kill an application
3126        if (callerUid == Process.SYSTEM_UID) {
3127            // Post an aysnc message to kill the application
3128            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3129            msg.arg1 = uid;
3130            msg.arg2 = 0;
3131            msg.obj = pkg;
3132            mHandler.sendMessage(msg);
3133        } else {
3134            throw new SecurityException(callerUid + " cannot kill pkg: " +
3135                    pkg);
3136        }
3137    }
3138
3139    public void closeSystemDialogs(String reason) {
3140        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3141        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3142        if (reason != null) {
3143            intent.putExtra("reason", reason);
3144        }
3145
3146        final int uid = Binder.getCallingUid();
3147        final long origId = Binder.clearCallingIdentity();
3148        synchronized (this) {
3149            int i = mWatchers.beginBroadcast();
3150            while (i > 0) {
3151                i--;
3152                IActivityWatcher w = mWatchers.getBroadcastItem(i);
3153                if (w != null) {
3154                    try {
3155                        w.closingSystemDialogs(reason);
3156                    } catch (RemoteException e) {
3157                    }
3158                }
3159            }
3160            mWatchers.finishBroadcast();
3161
3162            mWindowManager.closeSystemDialogs(reason);
3163
3164            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3165                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3166                if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3167                    r.stack.finishActivityLocked(r, i,
3168                            Activity.RESULT_CANCELED, null, "close-sys");
3169                }
3170            }
3171
3172            broadcastIntentLocked(null, null, intent, null,
3173                    null, 0, null, null, null, false, false, -1, uid);
3174        }
3175        Binder.restoreCallingIdentity(origId);
3176    }
3177
3178    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3179            throws RemoteException {
3180        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3181        for (int i=pids.length-1; i>=0; i--) {
3182            infos[i] = new Debug.MemoryInfo();
3183            Debug.getMemoryInfo(pids[i], infos[i]);
3184        }
3185        return infos;
3186    }
3187
3188    public void killApplicationProcess(String processName, int uid) {
3189        if (processName == null) {
3190            return;
3191        }
3192
3193        int callerUid = Binder.getCallingUid();
3194        // Only the system server can kill an application
3195        if (callerUid == Process.SYSTEM_UID) {
3196            synchronized (this) {
3197                ProcessRecord app = getProcessRecordLocked(processName, uid);
3198                if (app != null) {
3199                    try {
3200                        app.thread.scheduleSuicide();
3201                    } catch (RemoteException e) {
3202                        // If the other end already died, then our work here is done.
3203                    }
3204                } else {
3205                    Slog.w(TAG, "Process/uid not found attempting kill of "
3206                            + processName + " / " + uid);
3207                }
3208            }
3209        } else {
3210            throw new SecurityException(callerUid + " cannot kill app process: " +
3211                    processName);
3212        }
3213    }
3214
3215    private void forceStopPackageLocked(final String packageName, int uid) {
3216        forceStopPackageLocked(packageName, uid, false, false, true);
3217        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3218                Uri.fromParts("package", packageName, null));
3219        if (!mProcessesReady) {
3220            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3221        }
3222        intent.putExtra(Intent.EXTRA_UID, uid);
3223        broadcastIntentLocked(null, null, intent,
3224                null, null, 0, null, null, null,
3225                false, false, MY_PID, Process.SYSTEM_UID);
3226    }
3227
3228    private final boolean killPackageProcessesLocked(String packageName, int uid,
3229            int minOomAdj, boolean callerWillRestart, boolean doit) {
3230        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3231
3232        // Remove all processes this package may have touched: all with the
3233        // same UID (except for the system or root user), and all whose name
3234        // matches the package name.
3235        final String procNamePrefix = packageName + ":";
3236        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3237            final int NA = apps.size();
3238            for (int ia=0; ia<NA; ia++) {
3239                ProcessRecord app = apps.valueAt(ia);
3240                if (app.removed) {
3241                    if (doit) {
3242                        procs.add(app);
3243                    }
3244                } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3245                        || app.processName.equals(packageName)
3246                        || app.processName.startsWith(procNamePrefix)) {
3247                    if (app.setAdj >= minOomAdj) {
3248                        if (!doit) {
3249                            return true;
3250                        }
3251                        app.removed = true;
3252                        procs.add(app);
3253                    }
3254                }
3255            }
3256        }
3257
3258        int N = procs.size();
3259        for (int i=0; i<N; i++) {
3260            removeProcessLocked(procs.get(i), callerWillRestart);
3261        }
3262        return N > 0;
3263    }
3264
3265    private final boolean forceStopPackageLocked(String name, int uid,
3266            boolean callerWillRestart, boolean purgeCache, boolean doit) {
3267        int i, N;
3268
3269        if (uid < 0) {
3270            try {
3271                uid = AppGlobals.getPackageManager().getPackageUid(name);
3272            } catch (RemoteException e) {
3273            }
3274        }
3275
3276        if (doit) {
3277            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3278
3279            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3280            while (badApps.hasNext()) {
3281                SparseArray<Long> ba = badApps.next();
3282                if (ba.get(uid) != null) {
3283                    badApps.remove();
3284                }
3285            }
3286        }
3287
3288        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3289                callerWillRestart, doit);
3290
3291        for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3292            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3293            if (r.packageName.equals(name)) {
3294                if (!doit) {
3295                    return true;
3296                }
3297                didSomething = true;
3298                Slog.i(TAG, "  Force finishing activity " + r);
3299                if (r.app != null) {
3300                    r.app.removed = true;
3301                }
3302                r.app = null;
3303                r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
3304            }
3305        }
3306
3307        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3308        for (ServiceRecord service : mServices.values()) {
3309            if (service.packageName.equals(name)) {
3310                if (!doit) {
3311                    return true;
3312                }
3313                didSomething = true;
3314                Slog.i(TAG, "  Force stopping service " + service);
3315                if (service.app != null) {
3316                    service.app.removed = true;
3317                }
3318                service.app = null;
3319                services.add(service);
3320            }
3321        }
3322
3323        N = services.size();
3324        for (i=0; i<N; i++) {
3325            bringDownServiceLocked(services.get(i), true);
3326        }
3327
3328        if (doit) {
3329            if (purgeCache) {
3330                AttributeCache ac = AttributeCache.instance();
3331                if (ac != null) {
3332                    ac.removePackage(name);
3333                }
3334            }
3335            mMainStack.resumeTopActivityLocked(null);
3336        }
3337
3338        return didSomething;
3339    }
3340
3341    private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
3342        final String name = app.processName;
3343        final int uid = app.info.uid;
3344        if (DEBUG_PROCESSES) Slog.d(
3345            TAG, "Force removing process " + app + " (" + name
3346            + "/" + uid + ")");
3347
3348        mProcessNames.remove(name, uid);
3349        if (mHeavyWeightProcess == app) {
3350            mHeavyWeightProcess = null;
3351            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3352        }
3353        boolean needRestart = false;
3354        if (app.pid > 0 && app.pid != MY_PID) {
3355            int pid = app.pid;
3356            synchronized (mPidsSelfLocked) {
3357                mPidsSelfLocked.remove(pid);
3358                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3359            }
3360            handleAppDiedLocked(app, true);
3361            mLruProcesses.remove(app);
3362            Process.killProcess(pid);
3363
3364            if (app.persistent) {
3365                if (!callerWillRestart) {
3366                    addAppLocked(app.info);
3367                } else {
3368                    needRestart = true;
3369                }
3370            }
3371        } else {
3372            mRemovedProcesses.add(app);
3373        }
3374
3375        return needRestart;
3376    }
3377
3378    private final void processStartTimedOutLocked(ProcessRecord app) {
3379        final int pid = app.pid;
3380        boolean gone = false;
3381        synchronized (mPidsSelfLocked) {
3382            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3383            if (knownApp != null && knownApp.thread == null) {
3384                mPidsSelfLocked.remove(pid);
3385                gone = true;
3386            }
3387        }
3388
3389        if (gone) {
3390            Slog.w(TAG, "Process " + app + " failed to attach");
3391            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
3392                    app.processName);
3393            mProcessNames.remove(app.processName, app.info.uid);
3394            if (mHeavyWeightProcess == app) {
3395                mHeavyWeightProcess = null;
3396                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3397            }
3398            // Take care of any launching providers waiting for this process.
3399            checkAppInLaunchingProvidersLocked(app, true);
3400            // Take care of any services that are waiting for the process.
3401            for (int i=0; i<mPendingServices.size(); i++) {
3402                ServiceRecord sr = mPendingServices.get(i);
3403                if (app.info.uid == sr.appInfo.uid
3404                        && app.processName.equals(sr.processName)) {
3405                    Slog.w(TAG, "Forcing bringing down service: " + sr);
3406                    mPendingServices.remove(i);
3407                    i--;
3408                    bringDownServiceLocked(sr, true);
3409                }
3410            }
3411            Process.killProcess(pid);
3412            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3413                Slog.w(TAG, "Unattached app died before backup, skipping");
3414                try {
3415                    IBackupManager bm = IBackupManager.Stub.asInterface(
3416                            ServiceManager.getService(Context.BACKUP_SERVICE));
3417                    bm.agentDisconnected(app.info.packageName);
3418                } catch (RemoteException e) {
3419                    // Can't happen; the backup manager is local
3420                }
3421            }
3422            if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
3423                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3424                mPendingBroadcast.state = BroadcastRecord.IDLE;
3425                mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
3426                mPendingBroadcast = null;
3427                scheduleBroadcastsLocked();
3428            }
3429        } else {
3430            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3431        }
3432    }
3433
3434    private final boolean attachApplicationLocked(IApplicationThread thread,
3435            int pid) {
3436
3437        // Find the application record that is being attached...  either via
3438        // the pid if we are running in multiple processes, or just pull the
3439        // next app record if we are emulating process with anonymous threads.
3440        ProcessRecord app;
3441        if (pid != MY_PID && pid >= 0) {
3442            synchronized (mPidsSelfLocked) {
3443                app = mPidsSelfLocked.get(pid);
3444            }
3445        } else if (mStartingProcesses.size() > 0) {
3446            app = mStartingProcesses.remove(0);
3447            app.setPid(pid);
3448        } else {
3449            app = null;
3450        }
3451
3452        if (app == null) {
3453            Slog.w(TAG, "No pending application record for pid " + pid
3454                    + " (IApplicationThread " + thread + "); dropping process");
3455            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3456            if (pid > 0 && pid != MY_PID) {
3457                Process.killProcess(pid);
3458            } else {
3459                try {
3460                    thread.scheduleExit();
3461                } catch (Exception e) {
3462                    // Ignore exceptions.
3463                }
3464            }
3465            return false;
3466        }
3467
3468        // If this application record is still attached to a previous
3469        // process, clean it up now.
3470        if (app.thread != null) {
3471            handleAppDiedLocked(app, true);
3472        }
3473
3474        // Tell the process all about itself.
3475
3476        if (localLOGV) Slog.v(
3477                TAG, "Binding process pid " + pid + " to record " + app);
3478
3479        String processName = app.processName;
3480        try {
3481            thread.asBinder().linkToDeath(new AppDeathRecipient(
3482                    app, pid, thread), 0);
3483        } catch (RemoteException e) {
3484            app.resetPackageList();
3485            startProcessLocked(app, "link fail", processName);
3486            return false;
3487        }
3488
3489        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3490
3491        app.thread = thread;
3492        app.curAdj = app.setAdj = -100;
3493        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3494        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3495        app.forcingToForeground = null;
3496        app.foregroundServices = false;
3497        app.debugging = false;
3498
3499        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3500
3501        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3502        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3503
3504        if (!normalMode) {
3505            Slog.i(TAG, "Launching preboot mode app: " + app);
3506        }
3507
3508        if (localLOGV) Slog.v(
3509            TAG, "New app record " + app
3510            + " thread=" + thread.asBinder() + " pid=" + pid);
3511        try {
3512            int testMode = IApplicationThread.DEBUG_OFF;
3513            if (mDebugApp != null && mDebugApp.equals(processName)) {
3514                testMode = mWaitForDebugger
3515                    ? IApplicationThread.DEBUG_WAIT
3516                    : IApplicationThread.DEBUG_ON;
3517                app.debugging = true;
3518                if (mDebugTransient) {
3519                    mDebugApp = mOrigDebugApp;
3520                    mWaitForDebugger = mOrigWaitForDebugger;
3521                }
3522            }
3523
3524            // If the app is being launched for restore or full backup, set it up specially
3525            boolean isRestrictedBackupMode = false;
3526            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3527                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3528                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3529            }
3530
3531            ensurePackageDexOpt(app.instrumentationInfo != null
3532                    ? app.instrumentationInfo.packageName
3533                    : app.info.packageName);
3534            if (app.instrumentationClass != null) {
3535                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
3536            }
3537            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
3538                    + processName + " with config " + mConfiguration);
3539            thread.bindApplication(processName, app.instrumentationInfo != null
3540                    ? app.instrumentationInfo : app.info, providers,
3541                    app.instrumentationClass, app.instrumentationProfileFile,
3542                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
3543                    isRestrictedBackupMode || !normalMode,
3544                    mConfiguration, getCommonServicesLocked());
3545            updateLruProcessLocked(app, false, true);
3546            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
3547        } catch (Exception e) {
3548            // todo: Yikes!  What should we do?  For now we will try to
3549            // start another process, but that could easily get us in
3550            // an infinite loop of restarting processes...
3551            Slog.w(TAG, "Exception thrown during bind!", e);
3552
3553            app.resetPackageList();
3554            startProcessLocked(app, "bind fail", processName);
3555            return false;
3556        }
3557
3558        // Remove this record from the list of starting applications.
3559        mPersistentStartingProcesses.remove(app);
3560        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3561                "Attach application locked removing on hold: " + app);
3562        mProcessesOnHold.remove(app);
3563
3564        boolean badApp = false;
3565        boolean didSomething = false;
3566
3567        // See if the top visible activity is waiting to run in this process...
3568        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
3569        if (hr != null && normalMode) {
3570            if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3571                    && processName.equals(hr.processName)) {
3572                try {
3573                    if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
3574                        didSomething = true;
3575                    }
3576                } catch (Exception e) {
3577                    Slog.w(TAG, "Exception in new application when starting activity "
3578                          + hr.intent.getComponent().flattenToShortString(), e);
3579                    badApp = true;
3580                }
3581            } else {
3582                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
3583            }
3584        }
3585
3586        // Find any services that should be running in this process...
3587        if (!badApp && mPendingServices.size() > 0) {
3588            ServiceRecord sr = null;
3589            try {
3590                for (int i=0; i<mPendingServices.size(); i++) {
3591                    sr = mPendingServices.get(i);
3592                    if (app.info.uid != sr.appInfo.uid
3593                            || !processName.equals(sr.processName)) {
3594                        continue;
3595                    }
3596
3597                    mPendingServices.remove(i);
3598                    i--;
3599                    realStartServiceLocked(sr, app);
3600                    didSomething = true;
3601                }
3602            } catch (Exception e) {
3603                Slog.w(TAG, "Exception in new application when starting service "
3604                      + sr.shortName, e);
3605                badApp = true;
3606            }
3607        }
3608
3609        // Check if the next broadcast receiver is in this process...
3610        BroadcastRecord br = mPendingBroadcast;
3611        if (!badApp && br != null && br.curApp == app) {
3612            try {
3613                mPendingBroadcast = null;
3614                processCurBroadcastLocked(br, app);
3615                didSomething = true;
3616            } catch (Exception e) {
3617                Slog.w(TAG, "Exception in new application when starting receiver "
3618                      + br.curComponent.flattenToShortString(), e);
3619                badApp = true;
3620                logBroadcastReceiverDiscardLocked(br);
3621                finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3622                        br.resultExtras, br.resultAbort, true);
3623                scheduleBroadcastsLocked();
3624                // We need to reset the state if we fails to start the receiver.
3625                br.state = BroadcastRecord.IDLE;
3626            }
3627        }
3628
3629        // Check whether the next backup agent is in this process...
3630        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
3631            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
3632            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
3633            try {
3634                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode);
3635            } catch (Exception e) {
3636                Slog.w(TAG, "Exception scheduling backup agent creation: ");
3637                e.printStackTrace();
3638            }
3639        }
3640
3641        if (badApp) {
3642            // todo: Also need to kill application to deal with all
3643            // kinds of exceptions.
3644            handleAppDiedLocked(app, false);
3645            return false;
3646        }
3647
3648        if (!didSomething) {
3649            updateOomAdjLocked();
3650        }
3651
3652        return true;
3653    }
3654
3655    public final void attachApplication(IApplicationThread thread) {
3656        synchronized (this) {
3657            int callingPid = Binder.getCallingPid();
3658            final long origId = Binder.clearCallingIdentity();
3659            attachApplicationLocked(thread, callingPid);
3660            Binder.restoreCallingIdentity(origId);
3661        }
3662    }
3663
3664    public final void activityIdle(IBinder token, Configuration config) {
3665        final long origId = Binder.clearCallingIdentity();
3666        mMainStack.activityIdleInternal(token, false, config);
3667        Binder.restoreCallingIdentity(origId);
3668    }
3669
3670    void enableScreenAfterBoot() {
3671        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
3672                SystemClock.uptimeMillis());
3673        mWindowManager.enableScreenAfterBoot();
3674    }
3675
3676    final void finishBooting() {
3677        IntentFilter pkgFilter = new IntentFilter();
3678        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3679        pkgFilter.addDataScheme("package");
3680        mContext.registerReceiver(new BroadcastReceiver() {
3681            @Override
3682            public void onReceive(Context context, Intent intent) {
3683                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3684                if (pkgs != null) {
3685                    for (String pkg : pkgs) {
3686                        synchronized (ActivityManagerService.this) {
3687                          if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3688                              setResultCode(Activity.RESULT_OK);
3689                              return;
3690                          }
3691                       }
3692                    }
3693                }
3694            }
3695        }, pkgFilter);
3696
3697        synchronized (this) {
3698            // Ensure that any processes we had put on hold are now started
3699            // up.
3700            final int NP = mProcessesOnHold.size();
3701            if (NP > 0) {
3702                ArrayList<ProcessRecord> procs =
3703                    new ArrayList<ProcessRecord>(mProcessesOnHold);
3704                for (int ip=0; ip<NP; ip++) {
3705                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3706                            + procs.get(ip));
3707                    startProcessLocked(procs.get(ip), "on-hold", null);
3708                }
3709            }
3710
3711            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
3712                // Start looking for apps that are abusing wake locks.
3713                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
3714                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
3715                // Tell anyone interested that we are done booting!
3716                SystemProperties.set("sys.boot_completed", "1");
3717                broadcastIntentLocked(null, null,
3718                        new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3719                        null, null, 0, null, null,
3720                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3721                        false, false, MY_PID, Process.SYSTEM_UID);
3722            }
3723        }
3724    }
3725
3726    final void ensureBootCompleted() {
3727        boolean booting;
3728        boolean enableScreen;
3729        synchronized (this) {
3730            booting = mBooting;
3731            mBooting = false;
3732            enableScreen = !mBooted;
3733            mBooted = true;
3734        }
3735
3736        if (booting) {
3737            finishBooting();
3738        }
3739
3740        if (enableScreen) {
3741            enableScreenAfterBoot();
3742        }
3743    }
3744
3745    public final void activityPaused(IBinder token, Bundle icicle) {
3746        // Refuse possible leaked file descriptors
3747        if (icicle != null && icicle.hasFileDescriptors()) {
3748            throw new IllegalArgumentException("File descriptors passed in Bundle");
3749        }
3750
3751        final long origId = Binder.clearCallingIdentity();
3752        mMainStack.activityPaused(token, icicle, false);
3753        Binder.restoreCallingIdentity(origId);
3754    }
3755
3756    public final void activityStopped(IBinder token, Bitmap thumbnail,
3757            CharSequence description) {
3758        if (localLOGV) Slog.v(
3759            TAG, "Activity stopped: token=" + token);
3760
3761        ActivityRecord r = null;
3762
3763        final long origId = Binder.clearCallingIdentity();
3764
3765        synchronized (this) {
3766            int index = mMainStack.indexOfTokenLocked(token);
3767            if (index >= 0) {
3768                r = (ActivityRecord)mMainStack.mHistory.get(index);
3769                r.thumbnail = thumbnail;
3770                r.description = description;
3771                r.stopped = true;
3772                r.state = ActivityState.STOPPED;
3773                if (!r.finishing) {
3774                    if (r.configDestroy) {
3775                        r.stack.destroyActivityLocked(r, true);
3776                        r.stack.resumeTopActivityLocked(null);
3777                    }
3778                }
3779            }
3780        }
3781
3782        if (r != null) {
3783            sendPendingThumbnail(r, null, null, null, false);
3784        }
3785
3786        trimApplications();
3787
3788        Binder.restoreCallingIdentity(origId);
3789    }
3790
3791    public final void activityDestroyed(IBinder token) {
3792        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
3793        mMainStack.activityDestroyed(token);
3794    }
3795
3796    public String getCallingPackage(IBinder token) {
3797        synchronized (this) {
3798            ActivityRecord r = getCallingRecordLocked(token);
3799            return r != null && r.app != null ? r.info.packageName : null;
3800        }
3801    }
3802
3803    public ComponentName getCallingActivity(IBinder token) {
3804        synchronized (this) {
3805            ActivityRecord r = getCallingRecordLocked(token);
3806            return r != null ? r.intent.getComponent() : null;
3807        }
3808    }
3809
3810    private ActivityRecord getCallingRecordLocked(IBinder token) {
3811        int index = mMainStack.indexOfTokenLocked(token);
3812        if (index >= 0) {
3813            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
3814            if (r != null) {
3815                return r.resultTo;
3816            }
3817        }
3818        return null;
3819    }
3820
3821    public ComponentName getActivityClassForToken(IBinder token) {
3822        synchronized(this) {
3823            int index = mMainStack.indexOfTokenLocked(token);
3824            if (index >= 0) {
3825                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
3826                return r.intent.getComponent();
3827            }
3828            return null;
3829        }
3830    }
3831
3832    public String getPackageForToken(IBinder token) {
3833        synchronized(this) {
3834            int index = mMainStack.indexOfTokenLocked(token);
3835            if (index >= 0) {
3836                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
3837                return r.packageName;
3838            }
3839            return null;
3840        }
3841    }
3842
3843    public IIntentSender getIntentSender(int type,
3844            String packageName, IBinder token, String resultWho,
3845            int requestCode, Intent intent, String resolvedType, int flags) {
3846        // Refuse possible leaked file descriptors
3847        if (intent != null && intent.hasFileDescriptors() == true) {
3848            throw new IllegalArgumentException("File descriptors passed in Intent");
3849        }
3850
3851        if (type == INTENT_SENDER_BROADCAST) {
3852            if ((intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3853                throw new IllegalArgumentException(
3854                        "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3855            }
3856        }
3857
3858        synchronized(this) {
3859            int callingUid = Binder.getCallingUid();
3860            try {
3861                if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
3862                        Process.supportsProcesses()) {
3863                    int uid = AppGlobals.getPackageManager()
3864                            .getPackageUid(packageName);
3865                    if (uid != Binder.getCallingUid()) {
3866                        String msg = "Permission Denial: getIntentSender() from pid="
3867                            + Binder.getCallingPid()
3868                            + ", uid=" + Binder.getCallingUid()
3869                            + ", (need uid=" + uid + ")"
3870                            + " is not allowed to send as package " + packageName;
3871                        Slog.w(TAG, msg);
3872                        throw new SecurityException(msg);
3873                    }
3874                }
3875
3876                return getIntentSenderLocked(type, packageName, callingUid,
3877                        token, resultWho, requestCode, intent, resolvedType, flags);
3878
3879            } catch (RemoteException e) {
3880                throw new SecurityException(e);
3881            }
3882        }
3883    }
3884
3885    IIntentSender getIntentSenderLocked(int type,
3886            String packageName, int callingUid, IBinder token, String resultWho,
3887            int requestCode, Intent intent, String resolvedType, int flags) {
3888        ActivityRecord activity = null;
3889        if (type == INTENT_SENDER_ACTIVITY_RESULT) {
3890            int index = mMainStack.indexOfTokenLocked(token);
3891            if (index < 0) {
3892                return null;
3893            }
3894            activity = (ActivityRecord)mMainStack.mHistory.get(index);
3895            if (activity.finishing) {
3896                return null;
3897            }
3898        }
3899
3900        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
3901        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
3902        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
3903        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
3904                |PendingIntent.FLAG_UPDATE_CURRENT);
3905
3906        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
3907                type, packageName, activity, resultWho,
3908                requestCode, intent, resolvedType, flags);
3909        WeakReference<PendingIntentRecord> ref;
3910        ref = mIntentSenderRecords.get(key);
3911        PendingIntentRecord rec = ref != null ? ref.get() : null;
3912        if (rec != null) {
3913            if (!cancelCurrent) {
3914                if (updateCurrent) {
3915                    rec.key.requestIntent.replaceExtras(intent);
3916                }
3917                return rec;
3918            }
3919            rec.canceled = true;
3920            mIntentSenderRecords.remove(key);
3921        }
3922        if (noCreate) {
3923            return rec;
3924        }
3925        rec = new PendingIntentRecord(this, key, callingUid);
3926        mIntentSenderRecords.put(key, rec.ref);
3927        if (type == INTENT_SENDER_ACTIVITY_RESULT) {
3928            if (activity.pendingResults == null) {
3929                activity.pendingResults
3930                        = new HashSet<WeakReference<PendingIntentRecord>>();
3931            }
3932            activity.pendingResults.add(rec.ref);
3933        }
3934        return rec;
3935    }
3936
3937    public void cancelIntentSender(IIntentSender sender) {
3938        if (!(sender instanceof PendingIntentRecord)) {
3939            return;
3940        }
3941        synchronized(this) {
3942            PendingIntentRecord rec = (PendingIntentRecord)sender;
3943            try {
3944                int uid = AppGlobals.getPackageManager()
3945                        .getPackageUid(rec.key.packageName);
3946                if (uid != Binder.getCallingUid()) {
3947                    String msg = "Permission Denial: cancelIntentSender() from pid="
3948                        + Binder.getCallingPid()
3949                        + ", uid=" + Binder.getCallingUid()
3950                        + " is not allowed to cancel packges "
3951                        + rec.key.packageName;
3952                    Slog.w(TAG, msg);
3953                    throw new SecurityException(msg);
3954                }
3955            } catch (RemoteException e) {
3956                throw new SecurityException(e);
3957            }
3958            cancelIntentSenderLocked(rec, true);
3959        }
3960    }
3961
3962    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
3963        rec.canceled = true;
3964        mIntentSenderRecords.remove(rec.key);
3965        if (cleanActivity && rec.key.activity != null) {
3966            rec.key.activity.pendingResults.remove(rec.ref);
3967        }
3968    }
3969
3970    public String getPackageForIntentSender(IIntentSender pendingResult) {
3971        if (!(pendingResult instanceof PendingIntentRecord)) {
3972            return null;
3973        }
3974        try {
3975            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
3976            return res.key.packageName;
3977        } catch (ClassCastException e) {
3978        }
3979        return null;
3980    }
3981
3982    public void setProcessLimit(int max) {
3983        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
3984                "setProcessLimit()");
3985        mProcessLimit = max;
3986    }
3987
3988    public int getProcessLimit() {
3989        return mProcessLimit;
3990    }
3991
3992    void foregroundTokenDied(ForegroundToken token) {
3993        synchronized (ActivityManagerService.this) {
3994            synchronized (mPidsSelfLocked) {
3995                ForegroundToken cur
3996                    = mForegroundProcesses.get(token.pid);
3997                if (cur != token) {
3998                    return;
3999                }
4000                mForegroundProcesses.remove(token.pid);
4001                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4002                if (pr == null) {
4003                    return;
4004                }
4005                pr.forcingToForeground = null;
4006                pr.foregroundServices = false;
4007            }
4008            updateOomAdjLocked();
4009        }
4010    }
4011
4012    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4013        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4014                "setProcessForeground()");
4015        synchronized(this) {
4016            boolean changed = false;
4017
4018            synchronized (mPidsSelfLocked) {
4019                ProcessRecord pr = mPidsSelfLocked.get(pid);
4020                if (pr == null) {
4021                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4022                    return;
4023                }
4024                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4025                if (oldToken != null) {
4026                    oldToken.token.unlinkToDeath(oldToken, 0);
4027                    mForegroundProcesses.remove(pid);
4028                    pr.forcingToForeground = null;
4029                    changed = true;
4030                }
4031                if (isForeground && token != null) {
4032                    ForegroundToken newToken = new ForegroundToken() {
4033                        public void binderDied() {
4034                            foregroundTokenDied(this);
4035                        }
4036                    };
4037                    newToken.pid = pid;
4038                    newToken.token = token;
4039                    try {
4040                        token.linkToDeath(newToken, 0);
4041                        mForegroundProcesses.put(pid, newToken);
4042                        pr.forcingToForeground = token;
4043                        changed = true;
4044                    } catch (RemoteException e) {
4045                        // If the process died while doing this, we will later
4046                        // do the cleanup with the process death link.
4047                    }
4048                }
4049            }
4050
4051            if (changed) {
4052                updateOomAdjLocked();
4053            }
4054        }
4055    }
4056
4057    // =========================================================
4058    // PERMISSIONS
4059    // =========================================================
4060
4061    static class PermissionController extends IPermissionController.Stub {
4062        ActivityManagerService mActivityManagerService;
4063        PermissionController(ActivityManagerService activityManagerService) {
4064            mActivityManagerService = activityManagerService;
4065        }
4066
4067        public boolean checkPermission(String permission, int pid, int uid) {
4068            return mActivityManagerService.checkPermission(permission, pid,
4069                    uid) == PackageManager.PERMISSION_GRANTED;
4070        }
4071    }
4072
4073    /**
4074     * This can be called with or without the global lock held.
4075     */
4076    int checkComponentPermission(String permission, int pid, int uid,
4077            int reqUid) {
4078        // We might be performing an operation on behalf of an indirect binder
4079        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4080        // client identity accordingly before proceeding.
4081        Identity tlsIdentity = sCallerIdentity.get();
4082        if (tlsIdentity != null) {
4083            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4084                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4085            uid = tlsIdentity.uid;
4086            pid = tlsIdentity.pid;
4087        }
4088
4089        // Root, system server and our own process get to do everything.
4090        if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
4091            !Process.supportsProcesses()) {
4092            return PackageManager.PERMISSION_GRANTED;
4093        }
4094        // If the target requires a specific UID, always fail for others.
4095        if (reqUid >= 0 && uid != reqUid) {
4096            Slog.w(TAG, "Permission denied: checkComponentPermission() reqUid=" + reqUid);
4097            return PackageManager.PERMISSION_DENIED;
4098        }
4099        if (permission == null) {
4100            return PackageManager.PERMISSION_GRANTED;
4101        }
4102        try {
4103            return AppGlobals.getPackageManager()
4104                    .checkUidPermission(permission, uid);
4105        } catch (RemoteException e) {
4106            // Should never happen, but if it does... deny!
4107            Slog.e(TAG, "PackageManager is dead?!?", e);
4108        }
4109        return PackageManager.PERMISSION_DENIED;
4110    }
4111
4112    /**
4113     * As the only public entry point for permissions checking, this method
4114     * can enforce the semantic that requesting a check on a null global
4115     * permission is automatically denied.  (Internally a null permission
4116     * string is used when calling {@link #checkComponentPermission} in cases
4117     * when only uid-based security is needed.)
4118     *
4119     * This can be called with or without the global lock held.
4120     */
4121    public int checkPermission(String permission, int pid, int uid) {
4122        if (permission == null) {
4123            return PackageManager.PERMISSION_DENIED;
4124        }
4125        return checkComponentPermission(permission, pid, uid, -1);
4126    }
4127
4128    /**
4129     * Binder IPC calls go through the public entry point.
4130     * This can be called with or without the global lock held.
4131     */
4132    int checkCallingPermission(String permission) {
4133        return checkPermission(permission,
4134                Binder.getCallingPid(),
4135                Binder.getCallingUid());
4136    }
4137
4138    /**
4139     * This can be called with or without the global lock held.
4140     */
4141    void enforceCallingPermission(String permission, String func) {
4142        if (checkCallingPermission(permission)
4143                == PackageManager.PERMISSION_GRANTED) {
4144            return;
4145        }
4146
4147        String msg = "Permission Denial: " + func + " from pid="
4148                + Binder.getCallingPid()
4149                + ", uid=" + Binder.getCallingUid()
4150                + " requires " + permission;
4151        Slog.w(TAG, msg);
4152        throw new SecurityException(msg);
4153    }
4154
4155    private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
4156            ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4157        boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4158        boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4159        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4160                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4161        try {
4162            // Is the component private from the target uid?
4163            final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4164
4165            // Acceptable if the there is no read permission needed from the
4166            // target or the target is holding the read permission.
4167            if (!readPerm) {
4168                if ((!prv && pi.readPermission == null) ||
4169                        (pm.checkUidPermission(pi.readPermission, uid)
4170                                == PackageManager.PERMISSION_GRANTED)) {
4171                    readPerm = true;
4172                }
4173            }
4174
4175            // Acceptable if the there is no write permission needed from the
4176            // target or the target is holding the read permission.
4177            if (!writePerm) {
4178                if (!prv && (pi.writePermission == null) ||
4179                        (pm.checkUidPermission(pi.writePermission, uid)
4180                                == PackageManager.PERMISSION_GRANTED)) {
4181                    writePerm = true;
4182                }
4183            }
4184
4185            // Acceptable if there is a path permission matching the URI that
4186            // the target holds the permission on.
4187            PathPermission[] pps = pi.pathPermissions;
4188            if (pps != null && (!readPerm || !writePerm)) {
4189                final String path = uri.getPath();
4190                int i = pps.length;
4191                while (i > 0 && (!readPerm || !writePerm)) {
4192                    i--;
4193                    PathPermission pp = pps[i];
4194                    if (!readPerm) {
4195                        final String pprperm = pp.getReadPermission();
4196                        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4197                                + pprperm + " for " + pp.getPath()
4198                                + ": match=" + pp.match(path)
4199                                + " check=" + pm.checkUidPermission(pprperm, uid));
4200                        if (pprperm != null && pp.match(path) &&
4201                                (pm.checkUidPermission(pprperm, uid)
4202                                        == PackageManager.PERMISSION_GRANTED)) {
4203                            readPerm = true;
4204                        }
4205                    }
4206                    if (!writePerm) {
4207                        final String ppwperm = pp.getWritePermission();
4208                        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4209                                + ppwperm + " for " + pp.getPath()
4210                                + ": match=" + pp.match(path)
4211                                + " check=" + pm.checkUidPermission(ppwperm, uid));
4212                        if (ppwperm != null && pp.match(path) &&
4213                                (pm.checkUidPermission(ppwperm, uid)
4214                                        == PackageManager.PERMISSION_GRANTED)) {
4215                            writePerm = true;
4216                        }
4217                    }
4218                }
4219            }
4220        } catch (RemoteException e) {
4221            return false;
4222        }
4223
4224        return readPerm && writePerm;
4225    }
4226
4227    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4228            int modeFlags) {
4229        // Root gets to do everything.
4230        if (uid == 0 || !Process.supportsProcesses()) {
4231            return true;
4232        }
4233        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4234        if (perms == null) return false;
4235        UriPermission perm = perms.get(uri);
4236        if (perm == null) return false;
4237        return (modeFlags&perm.modeFlags) == modeFlags;
4238    }
4239
4240    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4241        // Another redirected-binder-call permissions check as in
4242        // {@link checkComponentPermission}.
4243        Identity tlsIdentity = sCallerIdentity.get();
4244        if (tlsIdentity != null) {
4245            uid = tlsIdentity.uid;
4246            pid = tlsIdentity.pid;
4247        }
4248
4249        // Our own process gets to do everything.
4250        if (pid == MY_PID) {
4251            return PackageManager.PERMISSION_GRANTED;
4252        }
4253        synchronized(this) {
4254            return checkUriPermissionLocked(uri, uid, modeFlags)
4255                    ? PackageManager.PERMISSION_GRANTED
4256                    : PackageManager.PERMISSION_DENIED;
4257        }
4258    }
4259
4260    /**
4261     * Check if the targetPkg can be granted permission to access uri by
4262     * the callingUid using the given modeFlags.  Throws a security exception
4263     * if callingUid is not allowed to do this.  Returns the uid of the target
4264     * if the URI permission grant should be performed; returns -1 if it is not
4265     * needed (for example targetPkg already has permission to access the URI).
4266     */
4267    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4268            Uri uri, int modeFlags) {
4269        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4270                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4271        if (modeFlags == 0) {
4272            return -1;
4273        }
4274
4275        if (targetPkg != null) {
4276            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4277                    "Checking grant " + targetPkg + " permission to " + uri);
4278        }
4279
4280        final IPackageManager pm = AppGlobals.getPackageManager();
4281
4282        // If this is not a content: uri, we can't do anything with it.
4283        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4284            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4285                    "Can't grant URI permission for non-content URI: " + uri);
4286            return -1;
4287        }
4288
4289        String name = uri.getAuthority();
4290        ProviderInfo pi = null;
4291        ContentProviderRecord cpr = mProvidersByName.get(name);
4292        if (cpr != null) {
4293            pi = cpr.info;
4294        } else {
4295            try {
4296                pi = pm.resolveContentProvider(name,
4297                        PackageManager.GET_URI_PERMISSION_PATTERNS);
4298            } catch (RemoteException ex) {
4299            }
4300        }
4301        if (pi == null) {
4302            Slog.w(TAG, "No content provider found for: " + name);
4303            return -1;
4304        }
4305
4306        int targetUid;
4307        if (targetPkg != null) {
4308            try {
4309                targetUid = pm.getPackageUid(targetPkg);
4310                if (targetUid < 0) {
4311                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4312                            "Can't grant URI permission no uid for: " + targetPkg);
4313                    return -1;
4314                }
4315            } catch (RemoteException ex) {
4316                return -1;
4317            }
4318        } else {
4319            targetUid = -1;
4320        }
4321
4322        if (targetUid >= 0) {
4323            // First...  does the target actually need this permission?
4324            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4325                // No need to grant the target this permission.
4326                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4327                        "Target " + targetPkg + " already has full permission to " + uri);
4328                return -1;
4329            }
4330        } else {
4331            // First...  there is no target package, so can anyone access it?
4332            boolean allowed = pi.exported;
4333            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4334                if (pi.readPermission != null) {
4335                    allowed = false;
4336                }
4337            }
4338            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4339                if (pi.writePermission != null) {
4340                    allowed = false;
4341                }
4342            }
4343            if (allowed) {
4344                return -1;
4345            }
4346        }
4347
4348        // Second...  is the provider allowing granting of URI permissions?
4349        if (!pi.grantUriPermissions) {
4350            throw new SecurityException("Provider " + pi.packageName
4351                    + "/" + pi.name
4352                    + " does not allow granting of Uri permissions (uri "
4353                    + uri + ")");
4354        }
4355        if (pi.uriPermissionPatterns != null) {
4356            final int N = pi.uriPermissionPatterns.length;
4357            boolean allowed = false;
4358            for (int i=0; i<N; i++) {
4359                if (pi.uriPermissionPatterns[i] != null
4360                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4361                    allowed = true;
4362                    break;
4363                }
4364            }
4365            if (!allowed) {
4366                throw new SecurityException("Provider " + pi.packageName
4367                        + "/" + pi.name
4368                        + " does not allow granting of permission to path of Uri "
4369                        + uri);
4370            }
4371        }
4372
4373        // Third...  does the caller itself have permission to access
4374        // this uri?
4375        if (callingUid != Process.myUid()) {
4376            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4377                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4378                    throw new SecurityException("Uid " + callingUid
4379                            + " does not have permission to uri " + uri);
4380                }
4381            }
4382        }
4383
4384        return targetUid;
4385    }
4386
4387    public int checkGrantUriPermission(int callingUid, String targetPkg,
4388            Uri uri, int modeFlags) {
4389        synchronized(this) {
4390            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4391        }
4392    }
4393
4394    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4395            Uri uri, int modeFlags, UriPermissionOwner owner) {
4396        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4397                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4398        if (modeFlags == 0) {
4399            return;
4400        }
4401
4402        // So here we are: the caller has the assumed permission
4403        // to the uri, and the target doesn't.  Let's now give this to
4404        // the target.
4405
4406        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4407                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
4408
4409        HashMap<Uri, UriPermission> targetUris
4410                = mGrantedUriPermissions.get(targetUid);
4411        if (targetUris == null) {
4412            targetUris = new HashMap<Uri, UriPermission>();
4413            mGrantedUriPermissions.put(targetUid, targetUris);
4414        }
4415
4416        UriPermission perm = targetUris.get(uri);
4417        if (perm == null) {
4418            perm = new UriPermission(targetUid, uri);
4419            targetUris.put(uri, perm);
4420        }
4421
4422        perm.modeFlags |= modeFlags;
4423        if (owner == null) {
4424            perm.globalModeFlags |= modeFlags;
4425        } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4426            perm.readOwners.add(owner);
4427            owner.addReadPermission(perm);
4428        } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4429            perm.writeOwners.add(owner);
4430            owner.addWritePermission(perm);
4431        }
4432    }
4433
4434    void grantUriPermissionLocked(int callingUid,
4435            String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
4436        if (targetPkg == null) {
4437            throw new NullPointerException("targetPkg");
4438        }
4439
4440        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4441        if (targetUid < 0) {
4442            return;
4443        }
4444
4445        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4446    }
4447
4448    /**
4449     * Like checkGrantUriPermissionLocked, but takes an Intent.
4450     */
4451    int checkGrantUriPermissionFromIntentLocked(int callingUid,
4452            String targetPkg, Intent intent) {
4453        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4454                "Checking URI perm to " + (intent != null ? intent.getData() : null)
4455                + " from " + intent + "; flags=0x"
4456                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4457
4458        if (targetPkg == null) {
4459            throw new NullPointerException("targetPkg");
4460        }
4461
4462        if (intent == null) {
4463            return -1;
4464        }
4465        Uri data = intent.getData();
4466        if (data == null) {
4467            return -1;
4468        }
4469        return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4470                intent.getFlags());
4471    }
4472
4473    /**
4474     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4475     */
4476    void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4477            String targetPkg, Intent intent, UriPermissionOwner owner) {
4478        grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4479                intent.getFlags(), owner);
4480    }
4481
4482    void grantUriPermissionFromIntentLocked(int callingUid,
4483            String targetPkg, Intent intent, UriPermissionOwner owner) {
4484        int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4485        if (targetUid < 0) {
4486            return;
4487        }
4488
4489        grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
4490    }
4491
4492    public void grantUriPermission(IApplicationThread caller, String targetPkg,
4493            Uri uri, int modeFlags) {
4494        synchronized(this) {
4495            final ProcessRecord r = getRecordForAppLocked(caller);
4496            if (r == null) {
4497                throw new SecurityException("Unable to find app for caller "
4498                        + caller
4499                        + " when granting permission to uri " + uri);
4500            }
4501            if (targetPkg == null) {
4502                throw new IllegalArgumentException("null target");
4503            }
4504            if (uri == null) {
4505                throw new IllegalArgumentException("null uri");
4506            }
4507
4508            grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4509                    null);
4510        }
4511    }
4512
4513    void removeUriPermissionIfNeededLocked(UriPermission perm) {
4514        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4515                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4516            HashMap<Uri, UriPermission> perms
4517                    = mGrantedUriPermissions.get(perm.uid);
4518            if (perms != null) {
4519                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4520                        "Removing " + perm.uid + " permission to " + perm.uri);
4521                perms.remove(perm.uri);
4522                if (perms.size() == 0) {
4523                    mGrantedUriPermissions.remove(perm.uid);
4524                }
4525            }
4526        }
4527    }
4528
4529    private void revokeUriPermissionLocked(int callingUid, Uri uri,
4530            int modeFlags) {
4531        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4532                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4533        if (modeFlags == 0) {
4534            return;
4535        }
4536
4537        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4538                "Revoking all granted permissions to " + uri);
4539
4540        final IPackageManager pm = AppGlobals.getPackageManager();
4541
4542        final String authority = uri.getAuthority();
4543        ProviderInfo pi = null;
4544        ContentProviderRecord cpr = mProvidersByName.get(authority);
4545        if (cpr != null) {
4546            pi = cpr.info;
4547        } else {
4548            try {
4549                pi = pm.resolveContentProvider(authority,
4550                        PackageManager.GET_URI_PERMISSION_PATTERNS);
4551            } catch (RemoteException ex) {
4552            }
4553        }
4554        if (pi == null) {
4555            Slog.w(TAG, "No content provider found for: " + authority);
4556            return;
4557        }
4558
4559        // Does the caller have this permission on the URI?
4560        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4561            // Right now, if you are not the original owner of the permission,
4562            // you are not allowed to revoke it.
4563            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4564                throw new SecurityException("Uid " + callingUid
4565                        + " does not have permission to uri " + uri);
4566            //}
4567        }
4568
4569        // Go through all of the permissions and remove any that match.
4570        final List<String> SEGMENTS = uri.getPathSegments();
4571        if (SEGMENTS != null) {
4572            final int NS = SEGMENTS.size();
4573            int N = mGrantedUriPermissions.size();
4574            for (int i=0; i<N; i++) {
4575                HashMap<Uri, UriPermission> perms
4576                        = mGrantedUriPermissions.valueAt(i);
4577                Iterator<UriPermission> it = perms.values().iterator();
4578            toploop:
4579                while (it.hasNext()) {
4580                    UriPermission perm = it.next();
4581                    Uri targetUri = perm.uri;
4582                    if (!authority.equals(targetUri.getAuthority())) {
4583                        continue;
4584                    }
4585                    List<String> targetSegments = targetUri.getPathSegments();
4586                    if (targetSegments == null) {
4587                        continue;
4588                    }
4589                    if (targetSegments.size() < NS) {
4590                        continue;
4591                    }
4592                    for (int j=0; j<NS; j++) {
4593                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4594                            continue toploop;
4595                        }
4596                    }
4597                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4598                            "Revoking " + perm.uid + " permission to " + perm.uri);
4599                    perm.clearModes(modeFlags);
4600                    if (perm.modeFlags == 0) {
4601                        it.remove();
4602                    }
4603                }
4604                if (perms.size() == 0) {
4605                    mGrantedUriPermissions.remove(
4606                            mGrantedUriPermissions.keyAt(i));
4607                    N--;
4608                    i--;
4609                }
4610            }
4611        }
4612    }
4613
4614    public void revokeUriPermission(IApplicationThread caller, Uri uri,
4615            int modeFlags) {
4616        synchronized(this) {
4617            final ProcessRecord r = getRecordForAppLocked(caller);
4618            if (r == null) {
4619                throw new SecurityException("Unable to find app for caller "
4620                        + caller
4621                        + " when revoking permission to uri " + uri);
4622            }
4623            if (uri == null) {
4624                Slog.w(TAG, "revokeUriPermission: null uri");
4625                return;
4626            }
4627
4628            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4629                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4630            if (modeFlags == 0) {
4631                return;
4632            }
4633
4634            final IPackageManager pm = AppGlobals.getPackageManager();
4635
4636            final String authority = uri.getAuthority();
4637            ProviderInfo pi = null;
4638            ContentProviderRecord cpr = mProvidersByName.get(authority);
4639            if (cpr != null) {
4640                pi = cpr.info;
4641            } else {
4642                try {
4643                    pi = pm.resolveContentProvider(authority,
4644                            PackageManager.GET_URI_PERMISSION_PATTERNS);
4645                } catch (RemoteException ex) {
4646                }
4647            }
4648            if (pi == null) {
4649                Slog.w(TAG, "No content provider found for: " + authority);
4650                return;
4651            }
4652
4653            revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4654        }
4655    }
4656
4657    @Override
4658    public IBinder newUriPermissionOwner(String name) {
4659        synchronized(this) {
4660            UriPermissionOwner owner = new UriPermissionOwner(this, name);
4661            return owner.getExternalTokenLocked();
4662        }
4663    }
4664
4665    @Override
4666    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4667            Uri uri, int modeFlags) {
4668        synchronized(this) {
4669            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4670            if (owner == null) {
4671                throw new IllegalArgumentException("Unknown owner: " + token);
4672            }
4673            if (fromUid != Binder.getCallingUid()) {
4674                if (Binder.getCallingUid() != Process.myUid()) {
4675                    // Only system code can grant URI permissions on behalf
4676                    // of other users.
4677                    throw new SecurityException("nice try");
4678                }
4679            }
4680            if (targetPkg == null) {
4681                throw new IllegalArgumentException("null target");
4682            }
4683            if (uri == null) {
4684                throw new IllegalArgumentException("null uri");
4685            }
4686
4687            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4688        }
4689    }
4690
4691    @Override
4692    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4693        synchronized(this) {
4694            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4695            if (owner == null) {
4696                throw new IllegalArgumentException("Unknown owner: " + token);
4697            }
4698
4699            if (uri == null) {
4700                owner.removeUriPermissionsLocked(mode);
4701            } else {
4702                owner.removeUriPermissionLocked(uri, mode);
4703            }
4704        }
4705    }
4706
4707    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4708        synchronized (this) {
4709            ProcessRecord app =
4710                who != null ? getRecordForAppLocked(who) : null;
4711            if (app == null) return;
4712
4713            Message msg = Message.obtain();
4714            msg.what = WAIT_FOR_DEBUGGER_MSG;
4715            msg.obj = app;
4716            msg.arg1 = waiting ? 1 : 0;
4717            mHandler.sendMessage(msg);
4718        }
4719    }
4720
4721    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
4722        outInfo.availMem = Process.getFreeMemory();
4723        outInfo.threshold = HOME_APP_MEM;
4724        outInfo.lowMemory = outInfo.availMem <
4725                (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
4726    }
4727
4728    // =========================================================
4729    // TASK MANAGEMENT
4730    // =========================================================
4731
4732    public List getTasks(int maxNum, int flags,
4733                         IThumbnailReceiver receiver) {
4734        ArrayList list = new ArrayList();
4735
4736        PendingThumbnailsRecord pending = null;
4737        IApplicationThread topThumbnail = null;
4738        ActivityRecord topRecord = null;
4739
4740        synchronized(this) {
4741            if (localLOGV) Slog.v(
4742                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4743                + ", receiver=" + receiver);
4744
4745            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4746                    != PackageManager.PERMISSION_GRANTED) {
4747                if (receiver != null) {
4748                    // If the caller wants to wait for pending thumbnails,
4749                    // it ain't gonna get them.
4750                    try {
4751                        receiver.finished();
4752                    } catch (RemoteException ex) {
4753                    }
4754                }
4755                String msg = "Permission Denial: getTasks() from pid="
4756                        + Binder.getCallingPid()
4757                        + ", uid=" + Binder.getCallingUid()
4758                        + " requires " + android.Manifest.permission.GET_TASKS;
4759                Slog.w(TAG, msg);
4760                throw new SecurityException(msg);
4761            }
4762
4763            int pos = mMainStack.mHistory.size()-1;
4764            ActivityRecord next =
4765                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
4766            ActivityRecord top = null;
4767            CharSequence topDescription = null;
4768            TaskRecord curTask = null;
4769            int numActivities = 0;
4770            int numRunning = 0;
4771            while (pos >= 0 && maxNum > 0) {
4772                final ActivityRecord r = next;
4773                pos--;
4774                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
4775
4776                // Initialize state for next task if needed.
4777                if (top == null ||
4778                        (top.state == ActivityState.INITIALIZING
4779                            && top.task == r.task)) {
4780                    top = r;
4781                    topDescription = r.description;
4782                    curTask = r.task;
4783                    numActivities = numRunning = 0;
4784                }
4785
4786                // Add 'r' into the current task.
4787                numActivities++;
4788                if (r.app != null && r.app.thread != null) {
4789                    numRunning++;
4790                }
4791                if (topDescription == null) {
4792                    topDescription = r.description;
4793                }
4794
4795                if (localLOGV) Slog.v(
4796                    TAG, r.intent.getComponent().flattenToShortString()
4797                    + ": task=" + r.task);
4798
4799                // If the next one is a different task, generate a new
4800                // TaskInfo entry for what we have.
4801                if (next == null || next.task != curTask) {
4802                    ActivityManager.RunningTaskInfo ci
4803                            = new ActivityManager.RunningTaskInfo();
4804                    ci.id = curTask.taskId;
4805                    ci.baseActivity = r.intent.getComponent();
4806                    ci.topActivity = top.intent.getComponent();
4807                    ci.thumbnail = top.thumbnail;
4808                    ci.description = topDescription;
4809                    ci.numActivities = numActivities;
4810                    ci.numRunning = numRunning;
4811                    //System.out.println(
4812                    //    "#" + maxNum + ": " + " descr=" + ci.description);
4813                    if (ci.thumbnail == null && receiver != null) {
4814                        if (localLOGV) Slog.v(
4815                            TAG, "State=" + top.state + "Idle=" + top.idle
4816                            + " app=" + top.app
4817                            + " thr=" + (top.app != null ? top.app.thread : null));
4818                        if (top.state == ActivityState.RESUMED
4819                                || top.state == ActivityState.PAUSING) {
4820                            if (top.idle && top.app != null
4821                                && top.app.thread != null) {
4822                                topRecord = top;
4823                                topThumbnail = top.app.thread;
4824                            } else {
4825                                top.thumbnailNeeded = true;
4826                            }
4827                        }
4828                        if (pending == null) {
4829                            pending = new PendingThumbnailsRecord(receiver);
4830                        }
4831                        pending.pendingRecords.add(top);
4832                    }
4833                    list.add(ci);
4834                    maxNum--;
4835                    top = null;
4836                }
4837            }
4838
4839            if (pending != null) {
4840                mPendingThumbnails.add(pending);
4841            }
4842        }
4843
4844        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
4845
4846        if (topThumbnail != null) {
4847            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
4848            try {
4849                topThumbnail.requestThumbnail(topRecord);
4850            } catch (Exception e) {
4851                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
4852                sendPendingThumbnail(null, topRecord, null, null, true);
4853            }
4854        }
4855
4856        if (pending == null && receiver != null) {
4857            // In this case all thumbnails were available and the client
4858            // is being asked to be told when the remaining ones come in...
4859            // which is unusually, since the top-most currently running
4860            // activity should never have a canned thumbnail!  Oh well.
4861            try {
4862                receiver.finished();
4863            } catch (RemoteException ex) {
4864            }
4865        }
4866
4867        return list;
4868    }
4869
4870    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
4871            int flags) {
4872        synchronized (this) {
4873            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
4874                    "getRecentTasks()");
4875
4876            IPackageManager pm = AppGlobals.getPackageManager();
4877
4878            final int N = mRecentTasks.size();
4879            ArrayList<ActivityManager.RecentTaskInfo> res
4880                    = new ArrayList<ActivityManager.RecentTaskInfo>(
4881                            maxNum < N ? maxNum : N);
4882            for (int i=0; i<N && maxNum > 0; i++) {
4883                TaskRecord tr = mRecentTasks.get(i);
4884                if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
4885                        || (tr.intent == null)
4886                        || ((tr.intent.getFlags()
4887                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
4888                    ActivityManager.RecentTaskInfo rti
4889                            = new ActivityManager.RecentTaskInfo();
4890                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
4891                    rti.baseIntent = new Intent(
4892                            tr.intent != null ? tr.intent : tr.affinityIntent);
4893                    rti.origActivity = tr.origActivity;
4894
4895                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
4896                        // Check whether this activity is currently available.
4897                        try {
4898                            if (rti.origActivity != null) {
4899                                if (pm.getActivityInfo(rti.origActivity, 0) == null) {
4900                                    continue;
4901                                }
4902                            } else if (rti.baseIntent != null) {
4903                                if (pm.queryIntentActivities(rti.baseIntent,
4904                                        null, 0) == null) {
4905                                    continue;
4906                                }
4907                            }
4908                        } catch (RemoteException e) {
4909                            // Will never happen.
4910                        }
4911                    }
4912
4913                    res.add(rti);
4914                    maxNum--;
4915                }
4916            }
4917            return res;
4918        }
4919    }
4920
4921    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
4922        int j;
4923        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
4924        TaskRecord jt = startTask;
4925
4926        // First look backwards
4927        for (j=startIndex-1; j>=0; j--) {
4928            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
4929            if (r.task != jt) {
4930                jt = r.task;
4931                if (affinity.equals(jt.affinity)) {
4932                    return j;
4933                }
4934            }
4935        }
4936
4937        // Now look forwards
4938        final int N = mMainStack.mHistory.size();
4939        jt = startTask;
4940        for (j=startIndex+1; j<N; j++) {
4941            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
4942            if (r.task != jt) {
4943                if (affinity.equals(jt.affinity)) {
4944                    return j;
4945                }
4946                jt = r.task;
4947            }
4948        }
4949
4950        // Might it be at the top?
4951        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
4952            return N-1;
4953        }
4954
4955        return -1;
4956    }
4957
4958    /**
4959     * TODO: Add mController hook
4960     */
4961    public void moveTaskToFront(int task) {
4962        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
4963                "moveTaskToFront()");
4964
4965        synchronized(this) {
4966            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
4967                    Binder.getCallingUid(), "Task to front")) {
4968                return;
4969            }
4970            final long origId = Binder.clearCallingIdentity();
4971            try {
4972                int N = mRecentTasks.size();
4973                for (int i=0; i<N; i++) {
4974                    TaskRecord tr = mRecentTasks.get(i);
4975                    if (tr.taskId == task) {
4976                        mMainStack.moveTaskToFrontLocked(tr, null);
4977                        return;
4978                    }
4979                }
4980                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
4981                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
4982                    if (hr.task.taskId == task) {
4983                        mMainStack.moveTaskToFrontLocked(hr.task, null);
4984                        return;
4985                    }
4986                }
4987            } finally {
4988                Binder.restoreCallingIdentity(origId);
4989            }
4990        }
4991    }
4992
4993    public void moveTaskToBack(int task) {
4994        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
4995                "moveTaskToBack()");
4996
4997        synchronized(this) {
4998            if (mMainStack.mResumedActivity != null
4999                    && mMainStack.mResumedActivity.task.taskId == task) {
5000                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5001                        Binder.getCallingUid(), "Task to back")) {
5002                    return;
5003                }
5004            }
5005            final long origId = Binder.clearCallingIdentity();
5006            mMainStack.moveTaskToBackLocked(task, null);
5007            Binder.restoreCallingIdentity(origId);
5008        }
5009    }
5010
5011    /**
5012     * Moves an activity, and all of the other activities within the same task, to the bottom
5013     * of the history stack.  The activity's order within the task is unchanged.
5014     *
5015     * @param token A reference to the activity we wish to move
5016     * @param nonRoot If false then this only works if the activity is the root
5017     *                of a task; if true it will work for any activity in a task.
5018     * @return Returns true if the move completed, false if not.
5019     */
5020    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5021        synchronized(this) {
5022            final long origId = Binder.clearCallingIdentity();
5023            int taskId = getTaskForActivityLocked(token, !nonRoot);
5024            if (taskId >= 0) {
5025                return mMainStack.moveTaskToBackLocked(taskId, null);
5026            }
5027            Binder.restoreCallingIdentity(origId);
5028        }
5029        return false;
5030    }
5031
5032    public void moveTaskBackwards(int task) {
5033        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5034                "moveTaskBackwards()");
5035
5036        synchronized(this) {
5037            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5038                    Binder.getCallingUid(), "Task backwards")) {
5039                return;
5040            }
5041            final long origId = Binder.clearCallingIdentity();
5042            moveTaskBackwardsLocked(task);
5043            Binder.restoreCallingIdentity(origId);
5044        }
5045    }
5046
5047    private final void moveTaskBackwardsLocked(int task) {
5048        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5049    }
5050
5051    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5052        synchronized(this) {
5053            return getTaskForActivityLocked(token, onlyRoot);
5054        }
5055    }
5056
5057    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5058        final int N = mMainStack.mHistory.size();
5059        TaskRecord lastTask = null;
5060        for (int i=0; i<N; i++) {
5061            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5062            if (r == token) {
5063                if (!onlyRoot || lastTask != r.task) {
5064                    return r.task.taskId;
5065                }
5066                return -1;
5067            }
5068            lastTask = r.task;
5069        }
5070
5071        return -1;
5072    }
5073
5074    public void finishOtherInstances(IBinder token, ComponentName className) {
5075        synchronized(this) {
5076            final long origId = Binder.clearCallingIdentity();
5077
5078            int N = mMainStack.mHistory.size();
5079            TaskRecord lastTask = null;
5080            for (int i=0; i<N; i++) {
5081                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5082                if (r.realActivity.equals(className)
5083                        && r != token && lastTask != r.task) {
5084                    if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
5085                            null, "others")) {
5086                        i--;
5087                        N--;
5088                    }
5089                }
5090                lastTask = r.task;
5091            }
5092
5093            Binder.restoreCallingIdentity(origId);
5094        }
5095    }
5096
5097    // =========================================================
5098    // THUMBNAILS
5099    // =========================================================
5100
5101    public void reportThumbnail(IBinder token,
5102            Bitmap thumbnail, CharSequence description) {
5103        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5104        final long origId = Binder.clearCallingIdentity();
5105        sendPendingThumbnail(null, token, thumbnail, description, true);
5106        Binder.restoreCallingIdentity(origId);
5107    }
5108
5109    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5110            Bitmap thumbnail, CharSequence description, boolean always) {
5111        TaskRecord task = null;
5112        ArrayList receivers = null;
5113
5114        //System.out.println("Send pending thumbnail: " + r);
5115
5116        synchronized(this) {
5117            if (r == null) {
5118                int index = mMainStack.indexOfTokenLocked(token);
5119                if (index < 0) {
5120                    return;
5121                }
5122                r = (ActivityRecord)mMainStack.mHistory.get(index);
5123            }
5124            if (thumbnail == null) {
5125                thumbnail = r.thumbnail;
5126                description = r.description;
5127            }
5128            if (thumbnail == null && !always) {
5129                // If there is no thumbnail, and this entry is not actually
5130                // going away, then abort for now and pick up the next
5131                // thumbnail we get.
5132                return;
5133            }
5134            task = r.task;
5135
5136            int N = mPendingThumbnails.size();
5137            int i=0;
5138            while (i<N) {
5139                PendingThumbnailsRecord pr =
5140                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5141                //System.out.println("Looking in " + pr.pendingRecords);
5142                if (pr.pendingRecords.remove(r)) {
5143                    if (receivers == null) {
5144                        receivers = new ArrayList();
5145                    }
5146                    receivers.add(pr);
5147                    if (pr.pendingRecords.size() == 0) {
5148                        pr.finished = true;
5149                        mPendingThumbnails.remove(i);
5150                        N--;
5151                        continue;
5152                    }
5153                }
5154                i++;
5155            }
5156        }
5157
5158        if (receivers != null) {
5159            final int N = receivers.size();
5160            for (int i=0; i<N; i++) {
5161                try {
5162                    PendingThumbnailsRecord pr =
5163                        (PendingThumbnailsRecord)receivers.get(i);
5164                    pr.receiver.newThumbnail(
5165                        task != null ? task.taskId : -1, thumbnail, description);
5166                    if (pr.finished) {
5167                        pr.receiver.finished();
5168                    }
5169                } catch (Exception e) {
5170                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
5171                }
5172            }
5173        }
5174    }
5175
5176    // =========================================================
5177    // CONTENT PROVIDERS
5178    // =========================================================
5179
5180    private final List generateApplicationProvidersLocked(ProcessRecord app) {
5181        List providers = null;
5182        try {
5183            providers = AppGlobals.getPackageManager().
5184                queryContentProviders(app.processName, app.info.uid,
5185                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
5186        } catch (RemoteException ex) {
5187        }
5188        if (providers != null) {
5189            final int N = providers.size();
5190            for (int i=0; i<N; i++) {
5191                ProviderInfo cpi =
5192                    (ProviderInfo)providers.get(i);
5193                ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
5194                if (cpr == null) {
5195                    cpr = new ContentProviderRecord(cpi, app.info);
5196                    mProvidersByClass.put(cpi.name, cpr);
5197                }
5198                app.pubProviders.put(cpi.name, cpr);
5199                app.addPackage(cpi.applicationInfo.packageName);
5200                ensurePackageDexOpt(cpi.applicationInfo.packageName);
5201            }
5202        }
5203        return providers;
5204    }
5205
5206    private final String checkContentProviderPermissionLocked(
5207            ProviderInfo cpi, ProcessRecord r) {
5208        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5209        final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5210        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
5211                cpi.exported ? -1 : cpi.applicationInfo.uid)
5212                == PackageManager.PERMISSION_GRANTED) {
5213            return null;
5214        }
5215        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
5216                cpi.exported ? -1 : cpi.applicationInfo.uid)
5217                == PackageManager.PERMISSION_GRANTED) {
5218            return null;
5219        }
5220
5221        PathPermission[] pps = cpi.pathPermissions;
5222        if (pps != null) {
5223            int i = pps.length;
5224            while (i > 0) {
5225                i--;
5226                PathPermission pp = pps[i];
5227                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
5228                        cpi.exported ? -1 : cpi.applicationInfo.uid)
5229                        == PackageManager.PERMISSION_GRANTED) {
5230                    return null;
5231                }
5232                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
5233                        cpi.exported ? -1 : cpi.applicationInfo.uid)
5234                        == PackageManager.PERMISSION_GRANTED) {
5235                    return null;
5236                }
5237            }
5238        }
5239
5240        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5241        if (perms != null) {
5242            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5243                if (uri.getKey().getAuthority().equals(cpi.authority)) {
5244                    return null;
5245                }
5246            }
5247        }
5248
5249        String msg = "Permission Denial: opening provider " + cpi.name
5250                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5251                + ", uid=" + callingUid + ") requires "
5252                + cpi.readPermission + " or " + cpi.writePermission;
5253        Slog.w(TAG, msg);
5254        return msg;
5255    }
5256
5257    private final ContentProviderHolder getContentProviderImpl(
5258        IApplicationThread caller, String name) {
5259        ContentProviderRecord cpr;
5260        ProviderInfo cpi = null;
5261
5262        synchronized(this) {
5263            ProcessRecord r = null;
5264            if (caller != null) {
5265                r = getRecordForAppLocked(caller);
5266                if (r == null) {
5267                    throw new SecurityException(
5268                            "Unable to find app for caller " + caller
5269                          + " (pid=" + Binder.getCallingPid()
5270                          + ") when getting content provider " + name);
5271                }
5272            }
5273
5274            // First check if this content provider has been published...
5275            cpr = mProvidersByName.get(name);
5276            if (cpr != null) {
5277                cpi = cpr.info;
5278                String msg;
5279                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5280                    throw new SecurityException(msg);
5281                }
5282
5283                if (r != null && cpr.canRunHere(r)) {
5284                    // This provider has been published or is in the process
5285                    // of being published...  but it is also allowed to run
5286                    // in the caller's process, so don't make a connection
5287                    // and just let the caller instantiate its own instance.
5288                    if (cpr.provider != null) {
5289                        // don't give caller the provider object, it needs
5290                        // to make its own.
5291                        cpr = new ContentProviderRecord(cpr);
5292                    }
5293                    return cpr;
5294                }
5295
5296                final long origId = Binder.clearCallingIdentity();
5297
5298                // In this case the provider instance already exists, so we can
5299                // return it right away.
5300                if (r != null) {
5301                    if (DEBUG_PROVIDER) Slog.v(TAG,
5302                            "Adding provider requested by "
5303                            + r.processName + " from process "
5304                            + cpr.info.processName);
5305                    Integer cnt = r.conProviders.get(cpr);
5306                    if (cnt == null) {
5307                        r.conProviders.put(cpr, new Integer(1));
5308                    } else {
5309                        r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5310                    }
5311                    cpr.clients.add(r);
5312                    if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) {
5313                        // If this is a perceptible app accessing the provider,
5314                        // make sure to count it as being accessed and thus
5315                        // back up on the LRU list.  This is good because
5316                        // content providers are often expensive to start.
5317                        updateLruProcessLocked(cpr.app, false, true);
5318                    }
5319                } else {
5320                    cpr.externals++;
5321                }
5322
5323                if (cpr.app != null) {
5324                    updateOomAdjLocked(cpr.app);
5325                }
5326
5327                Binder.restoreCallingIdentity(origId);
5328
5329            } else {
5330                try {
5331                    cpi = AppGlobals.getPackageManager().
5332                        resolveContentProvider(name,
5333                                STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
5334                } catch (RemoteException ex) {
5335                }
5336                if (cpi == null) {
5337                    return null;
5338                }
5339
5340                String msg;
5341                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5342                    throw new SecurityException(msg);
5343                }
5344
5345                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
5346                        && !cpi.processName.equals("system")) {
5347                    // If this content provider does not run in the system
5348                    // process, and the system is not yet ready to run other
5349                    // processes, then fail fast instead of hanging.
5350                    throw new IllegalArgumentException(
5351                            "Attempt to launch content provider before system ready");
5352                }
5353
5354                cpr = mProvidersByClass.get(cpi.name);
5355                final boolean firstClass = cpr == null;
5356                if (firstClass) {
5357                    try {
5358                        ApplicationInfo ai =
5359                            AppGlobals.getPackageManager().
5360                                getApplicationInfo(
5361                                        cpi.applicationInfo.packageName,
5362                                        STOCK_PM_FLAGS);
5363                        if (ai == null) {
5364                            Slog.w(TAG, "No package info for content provider "
5365                                    + cpi.name);
5366                            return null;
5367                        }
5368                        cpr = new ContentProviderRecord(cpi, ai);
5369                    } catch (RemoteException ex) {
5370                        // pm is in same process, this will never happen.
5371                    }
5372                }
5373
5374                if (r != null && cpr.canRunHere(r)) {
5375                    // If this is a multiprocess provider, then just return its
5376                    // info and allow the caller to instantiate it.  Only do
5377                    // this if the provider is the same user as the caller's
5378                    // process, or can run as root (so can be in any process).
5379                    return cpr;
5380                }
5381
5382                if (DEBUG_PROVIDER) {
5383                    RuntimeException e = new RuntimeException("here");
5384                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
5385                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
5386                }
5387
5388                // This is single process, and our app is now connecting to it.
5389                // See if we are already in the process of launching this
5390                // provider.
5391                final int N = mLaunchingProviders.size();
5392                int i;
5393                for (i=0; i<N; i++) {
5394                    if (mLaunchingProviders.get(i) == cpr) {
5395                        break;
5396                    }
5397                }
5398
5399                // If the provider is not already being launched, then get it
5400                // started.
5401                if (i >= N) {
5402                    final long origId = Binder.clearCallingIdentity();
5403                    ProcessRecord proc = startProcessLocked(cpi.processName,
5404                            cpr.appInfo, false, 0, "content provider",
5405                            new ComponentName(cpi.applicationInfo.packageName,
5406                                    cpi.name), false);
5407                    if (proc == null) {
5408                        Slog.w(TAG, "Unable to launch app "
5409                                + cpi.applicationInfo.packageName + "/"
5410                                + cpi.applicationInfo.uid + " for provider "
5411                                + name + ": process is bad");
5412                        return null;
5413                    }
5414                    cpr.launchingApp = proc;
5415                    mLaunchingProviders.add(cpr);
5416                    Binder.restoreCallingIdentity(origId);
5417                }
5418
5419                // Make sure the provider is published (the same provider class
5420                // may be published under multiple names).
5421                if (firstClass) {
5422                    mProvidersByClass.put(cpi.name, cpr);
5423                }
5424                mProvidersByName.put(name, cpr);
5425
5426                if (r != null) {
5427                    if (DEBUG_PROVIDER) Slog.v(TAG,
5428                            "Adding provider requested by "
5429                            + r.processName + " from process "
5430                            + cpr.info.processName);
5431                    Integer cnt = r.conProviders.get(cpr);
5432                    if (cnt == null) {
5433                        r.conProviders.put(cpr, new Integer(1));
5434                    } else {
5435                        r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5436                    }
5437                    cpr.clients.add(r);
5438                } else {
5439                    cpr.externals++;
5440                }
5441            }
5442        }
5443
5444        // Wait for the provider to be published...
5445        synchronized (cpr) {
5446            while (cpr.provider == null) {
5447                if (cpr.launchingApp == null) {
5448                    Slog.w(TAG, "Unable to launch app "
5449                            + cpi.applicationInfo.packageName + "/"
5450                            + cpi.applicationInfo.uid + " for provider "
5451                            + name + ": launching app became null");
5452                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
5453                            cpi.applicationInfo.packageName,
5454                            cpi.applicationInfo.uid, name);
5455                    return null;
5456                }
5457                try {
5458                    cpr.wait();
5459                } catch (InterruptedException ex) {
5460                }
5461            }
5462        }
5463        return cpr;
5464    }
5465
5466    public final ContentProviderHolder getContentProvider(
5467            IApplicationThread caller, String name) {
5468        if (caller == null) {
5469            String msg = "null IApplicationThread when getting content provider "
5470                    + name;
5471            Slog.w(TAG, msg);
5472            throw new SecurityException(msg);
5473        }
5474
5475        return getContentProviderImpl(caller, name);
5476    }
5477
5478    private ContentProviderHolder getContentProviderExternal(String name) {
5479        return getContentProviderImpl(null, name);
5480    }
5481
5482    /**
5483     * Drop a content provider from a ProcessRecord's bookkeeping
5484     * @param cpr
5485     */
5486    public void removeContentProvider(IApplicationThread caller, String name) {
5487        synchronized (this) {
5488            ContentProviderRecord cpr = mProvidersByName.get(name);
5489            if(cpr == null) {
5490                // remove from mProvidersByClass
5491                if (DEBUG_PROVIDER) Slog.v(TAG, name +
5492                        " provider not found in providers list");
5493                return;
5494            }
5495            final ProcessRecord r = getRecordForAppLocked(caller);
5496            if (r == null) {
5497                throw new SecurityException(
5498                        "Unable to find app for caller " + caller +
5499                        " when removing content provider " + name);
5500            }
5501            //update content provider record entry info
5502            ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
5503            if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
5504                    + r.info.processName + " from process "
5505                    + localCpr.appInfo.processName);
5506            if (localCpr.app == r) {
5507                //should not happen. taken care of as a local provider
5508                Slog.w(TAG, "removeContentProvider called on local provider: "
5509                        + cpr.info.name + " in process " + r.processName);
5510                return;
5511            } else {
5512                Integer cnt = r.conProviders.get(localCpr);
5513                if (cnt == null || cnt.intValue() <= 1) {
5514                    localCpr.clients.remove(r);
5515                    r.conProviders.remove(localCpr);
5516                } else {
5517                    r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5518                }
5519            }
5520            updateOomAdjLocked();
5521        }
5522    }
5523
5524    private void removeContentProviderExternal(String name) {
5525        synchronized (this) {
5526            ContentProviderRecord cpr = mProvidersByName.get(name);
5527            if(cpr == null) {
5528                //remove from mProvidersByClass
5529                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
5530                return;
5531            }
5532
5533            //update content provider record entry info
5534            ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
5535            localCpr.externals--;
5536            if (localCpr.externals < 0) {
5537                Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
5538            }
5539            updateOomAdjLocked();
5540        }
5541    }
5542
5543    public final void publishContentProviders(IApplicationThread caller,
5544            List<ContentProviderHolder> providers) {
5545        if (providers == null) {
5546            return;
5547        }
5548
5549        synchronized(this) {
5550            final ProcessRecord r = getRecordForAppLocked(caller);
5551            if (r == null) {
5552                throw new SecurityException(
5553                        "Unable to find app for caller " + caller
5554                      + " (pid=" + Binder.getCallingPid()
5555                      + ") when publishing content providers");
5556            }
5557
5558            final long origId = Binder.clearCallingIdentity();
5559
5560            final int N = providers.size();
5561            for (int i=0; i<N; i++) {
5562                ContentProviderHolder src = providers.get(i);
5563                if (src == null || src.info == null || src.provider == null) {
5564                    continue;
5565                }
5566                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
5567                if (dst != null) {
5568                    mProvidersByClass.put(dst.info.name, dst);
5569                    String names[] = dst.info.authority.split(";");
5570                    for (int j = 0; j < names.length; j++) {
5571                        mProvidersByName.put(names[j], dst);
5572                    }
5573
5574                    int NL = mLaunchingProviders.size();
5575                    int j;
5576                    for (j=0; j<NL; j++) {
5577                        if (mLaunchingProviders.get(j) == dst) {
5578                            mLaunchingProviders.remove(j);
5579                            j--;
5580                            NL--;
5581                        }
5582                    }
5583                    synchronized (dst) {
5584                        dst.provider = src.provider;
5585                        dst.app = r;
5586                        dst.notifyAll();
5587                    }
5588                    updateOomAdjLocked(r);
5589                }
5590            }
5591
5592            Binder.restoreCallingIdentity(origId);
5593        }
5594    }
5595
5596    public static final void installSystemProviders() {
5597        List providers;
5598        synchronized (mSelf) {
5599            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5600            providers = mSelf.generateApplicationProvidersLocked(app);
5601            if (providers != null) {
5602                for (int i=providers.size()-1; i>=0; i--) {
5603                    ProviderInfo pi = (ProviderInfo)providers.get(i);
5604                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5605                        Slog.w(TAG, "Not installing system proc provider " + pi.name
5606                                + ": not system .apk");
5607                        providers.remove(i);
5608                    }
5609                }
5610            }
5611        }
5612        if (providers != null) {
5613            mSystemThread.installSystemProviders(providers);
5614        }
5615    }
5616
5617    /**
5618     * Allows app to retrieve the MIME type of a URI without having permission
5619     * to access its content provider.
5620     *
5621     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5622     *
5623     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5624     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5625     */
5626    public String getProviderMimeType(Uri uri) {
5627        final String name = uri.getAuthority();
5628        final long ident = Binder.clearCallingIdentity();
5629        ContentProviderHolder holder = null;
5630
5631        try {
5632            holder = getContentProviderExternal(name);
5633            if (holder != null) {
5634                return holder.provider.getType(uri);
5635            }
5636        } catch (RemoteException e) {
5637            Log.w(TAG, "Content provider dead retrieving " + uri, e);
5638            return null;
5639        } finally {
5640            if (holder != null) {
5641                removeContentProviderExternal(name);
5642            }
5643            Binder.restoreCallingIdentity(ident);
5644        }
5645
5646        return null;
5647    }
5648
5649    // =========================================================
5650    // GLOBAL MANAGEMENT
5651    // =========================================================
5652
5653    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5654            ApplicationInfo info, String customProcess) {
5655        String proc = customProcess != null ? customProcess : info.processName;
5656        BatteryStatsImpl.Uid.Proc ps = null;
5657        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5658        synchronized (stats) {
5659            ps = stats.getProcessStatsLocked(info.uid, proc);
5660        }
5661        return new ProcessRecord(ps, thread, info, proc);
5662    }
5663
5664    final ProcessRecord addAppLocked(ApplicationInfo info) {
5665        ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
5666
5667        if (app == null) {
5668            app = newProcessRecordLocked(null, info, null);
5669            mProcessNames.put(info.processName, info.uid, app);
5670            updateLruProcessLocked(app, true, true);
5671        }
5672
5673        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
5674                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
5675            app.persistent = true;
5676            app.maxAdj = CORE_SERVER_ADJ;
5677        }
5678        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
5679            mPersistentStartingProcesses.add(app);
5680            startProcessLocked(app, "added application", app.processName);
5681        }
5682
5683        return app;
5684    }
5685
5686    public void unhandledBack() {
5687        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
5688                "unhandledBack()");
5689
5690        synchronized(this) {
5691            int count = mMainStack.mHistory.size();
5692            if (DEBUG_SWITCH) Slog.d(
5693                TAG, "Performing unhandledBack(): stack size = " + count);
5694            if (count > 1) {
5695                final long origId = Binder.clearCallingIdentity();
5696                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
5697                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
5698                Binder.restoreCallingIdentity(origId);
5699            }
5700        }
5701    }
5702
5703    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
5704        String name = uri.getAuthority();
5705        ContentProviderHolder cph = getContentProviderExternal(name);
5706        ParcelFileDescriptor pfd = null;
5707        if (cph != null) {
5708            // We record the binder invoker's uid in thread-local storage before
5709            // going to the content provider to open the file.  Later, in the code
5710            // that handles all permissions checks, we look for this uid and use
5711            // that rather than the Activity Manager's own uid.  The effect is that
5712            // we do the check against the caller's permissions even though it looks
5713            // to the content provider like the Activity Manager itself is making
5714            // the request.
5715            sCallerIdentity.set(new Identity(
5716                    Binder.getCallingPid(), Binder.getCallingUid()));
5717            try {
5718                pfd = cph.provider.openFile(uri, "r");
5719            } catch (FileNotFoundException e) {
5720                // do nothing; pfd will be returned null
5721            } finally {
5722                // Ensure that whatever happens, we clean up the identity state
5723                sCallerIdentity.remove();
5724            }
5725
5726            // We've got the fd now, so we're done with the provider.
5727            removeContentProviderExternal(name);
5728        } else {
5729            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
5730        }
5731        return pfd;
5732    }
5733
5734    public void goingToSleep() {
5735        synchronized(this) {
5736            mSleeping = true;
5737            mWindowManager.setEventDispatching(false);
5738
5739            if (mMainStack.mResumedActivity != null) {
5740                mMainStack.pauseIfSleepingLocked();
5741            } else {
5742                Slog.w(TAG, "goingToSleep with no resumed activity!");
5743            }
5744
5745            // Initialize the wake times of all processes.
5746            checkExcessivePowerUsageLocked(false);
5747            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5748            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5749            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5750        }
5751    }
5752
5753    public boolean shutdown(int timeout) {
5754        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
5755                != PackageManager.PERMISSION_GRANTED) {
5756            throw new SecurityException("Requires permission "
5757                    + android.Manifest.permission.SHUTDOWN);
5758        }
5759
5760        boolean timedout = false;
5761
5762        synchronized(this) {
5763            mShuttingDown = true;
5764            mWindowManager.setEventDispatching(false);
5765
5766            if (mMainStack.mResumedActivity != null) {
5767                mMainStack.pauseIfSleepingLocked();
5768                final long endTime = System.currentTimeMillis() + timeout;
5769                while (mMainStack.mResumedActivity != null
5770                        || mMainStack.mPausingActivity != null) {
5771                    long delay = endTime - System.currentTimeMillis();
5772                    if (delay <= 0) {
5773                        Slog.w(TAG, "Activity manager shutdown timed out");
5774                        timedout = true;
5775                        break;
5776                    }
5777                    try {
5778                        this.wait();
5779                    } catch (InterruptedException e) {
5780                    }
5781                }
5782            }
5783        }
5784
5785        mUsageStatsService.shutdown();
5786        mBatteryStatsService.shutdown();
5787
5788        return timedout;
5789    }
5790
5791    public void wakingUp() {
5792        synchronized(this) {
5793            if (mMainStack.mGoingToSleep.isHeld()) {
5794                mMainStack.mGoingToSleep.release();
5795            }
5796            mWindowManager.setEventDispatching(true);
5797            mSleeping = false;
5798            mMainStack.resumeTopActivityLocked(null);
5799        }
5800    }
5801
5802    public void stopAppSwitches() {
5803        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
5804                != PackageManager.PERMISSION_GRANTED) {
5805            throw new SecurityException("Requires permission "
5806                    + android.Manifest.permission.STOP_APP_SWITCHES);
5807        }
5808
5809        synchronized(this) {
5810            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
5811                    + APP_SWITCH_DELAY_TIME;
5812            mDidAppSwitch = false;
5813            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
5814            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
5815            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
5816        }
5817    }
5818
5819    public void resumeAppSwitches() {
5820        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
5821                != PackageManager.PERMISSION_GRANTED) {
5822            throw new SecurityException("Requires permission "
5823                    + android.Manifest.permission.STOP_APP_SWITCHES);
5824        }
5825
5826        synchronized(this) {
5827            // Note that we don't execute any pending app switches... we will
5828            // let those wait until either the timeout, or the next start
5829            // activity request.
5830            mAppSwitchesAllowedTime = 0;
5831        }
5832    }
5833
5834    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
5835            String name) {
5836        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
5837            return true;
5838        }
5839
5840        final int perm = checkComponentPermission(
5841                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
5842                callingUid, -1);
5843        if (perm == PackageManager.PERMISSION_GRANTED) {
5844            return true;
5845        }
5846
5847        Slog.w(TAG, name + " request from " + callingUid + " stopped");
5848        return false;
5849    }
5850
5851    public void setDebugApp(String packageName, boolean waitForDebugger,
5852            boolean persistent) {
5853        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
5854                "setDebugApp()");
5855
5856        // Note that this is not really thread safe if there are multiple
5857        // callers into it at the same time, but that's not a situation we
5858        // care about.
5859        if (persistent) {
5860            final ContentResolver resolver = mContext.getContentResolver();
5861            Settings.System.putString(
5862                resolver, Settings.System.DEBUG_APP,
5863                packageName);
5864            Settings.System.putInt(
5865                resolver, Settings.System.WAIT_FOR_DEBUGGER,
5866                waitForDebugger ? 1 : 0);
5867        }
5868
5869        synchronized (this) {
5870            if (!persistent) {
5871                mOrigDebugApp = mDebugApp;
5872                mOrigWaitForDebugger = mWaitForDebugger;
5873            }
5874            mDebugApp = packageName;
5875            mWaitForDebugger = waitForDebugger;
5876            mDebugTransient = !persistent;
5877            if (packageName != null) {
5878                final long origId = Binder.clearCallingIdentity();
5879                forceStopPackageLocked(packageName, -1, false, false, true);
5880                Binder.restoreCallingIdentity(origId);
5881            }
5882        }
5883    }
5884
5885    public void setAlwaysFinish(boolean enabled) {
5886        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
5887                "setAlwaysFinish()");
5888
5889        Settings.System.putInt(
5890                mContext.getContentResolver(),
5891                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
5892
5893        synchronized (this) {
5894            mAlwaysFinishActivities = enabled;
5895        }
5896    }
5897
5898    public void setActivityController(IActivityController controller) {
5899        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
5900                "setActivityController()");
5901        synchronized (this) {
5902            mController = controller;
5903        }
5904    }
5905
5906    public boolean isUserAMonkey() {
5907        // For now the fact that there is a controller implies
5908        // we have a monkey.
5909        synchronized (this) {
5910            return mController != null;
5911        }
5912    }
5913
5914    public void registerActivityWatcher(IActivityWatcher watcher) {
5915        synchronized (this) {
5916            mWatchers.register(watcher);
5917        }
5918    }
5919
5920    public void unregisterActivityWatcher(IActivityWatcher watcher) {
5921        synchronized (this) {
5922            mWatchers.unregister(watcher);
5923        }
5924    }
5925
5926    public void setImmersive(IBinder token, boolean immersive) {
5927        synchronized(this) {
5928            int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
5929            if (index < 0) {
5930                throw new IllegalArgumentException();
5931            }
5932            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
5933            r.immersive = immersive;
5934        }
5935    }
5936
5937    public boolean isImmersive(IBinder token) {
5938        synchronized (this) {
5939            int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
5940            if (index < 0) {
5941                throw new IllegalArgumentException();
5942            }
5943            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
5944            return r.immersive;
5945        }
5946    }
5947
5948    public boolean isTopActivityImmersive() {
5949        synchronized (this) {
5950            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
5951            return (r != null) ? r.immersive : false;
5952        }
5953    }
5954
5955    public final void enterSafeMode() {
5956        synchronized(this) {
5957            // It only makes sense to do this before the system is ready
5958            // and started launching other packages.
5959            if (!mSystemReady) {
5960                try {
5961                    AppGlobals.getPackageManager().enterSafeMode();
5962                } catch (RemoteException e) {
5963                }
5964
5965                View v = LayoutInflater.from(mContext).inflate(
5966                        com.android.internal.R.layout.safe_mode, null);
5967                WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
5968                lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
5969                lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
5970                lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
5971                lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
5972                lp.format = v.getBackground().getOpacity();
5973                lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
5974                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
5975                ((WindowManager)mContext.getSystemService(
5976                        Context.WINDOW_SERVICE)).addView(v, lp);
5977            }
5978        }
5979    }
5980
5981    public void noteWakeupAlarm(IIntentSender sender) {
5982        if (!(sender instanceof PendingIntentRecord)) {
5983            return;
5984        }
5985        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5986        synchronized (stats) {
5987            if (mBatteryStatsService.isOnBattery()) {
5988                mBatteryStatsService.enforceCallingPermission();
5989                PendingIntentRecord rec = (PendingIntentRecord)sender;
5990                int MY_UID = Binder.getCallingUid();
5991                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
5992                BatteryStatsImpl.Uid.Pkg pkg =
5993                    stats.getPackageStatsLocked(uid, rec.key.packageName);
5994                pkg.incWakeupsLocked();
5995            }
5996        }
5997    }
5998
5999    public boolean killPids(int[] pids, String pReason) {
6000        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
6001            throw new SecurityException("killPids only available to the system");
6002        }
6003        String reason = (pReason == null) ? "Unknown" : pReason;
6004        // XXX Note: don't acquire main activity lock here, because the window
6005        // manager calls in with its locks held.
6006
6007        boolean killed = false;
6008        synchronized (mPidsSelfLocked) {
6009            int[] types = new int[pids.length];
6010            int worstType = 0;
6011            for (int i=0; i<pids.length; i++) {
6012                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6013                if (proc != null) {
6014                    int type = proc.setAdj;
6015                    types[i] = type;
6016                    if (type > worstType) {
6017                        worstType = type;
6018                    }
6019                }
6020            }
6021
6022            // If the worse oom_adj is somewhere in the hidden proc LRU range,
6023            // then constrain it so we will kill all hidden procs.
6024            if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
6025                worstType = HIDDEN_APP_MIN_ADJ;
6026            }
6027            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
6028            for (int i=0; i<pids.length; i++) {
6029                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6030                if (proc == null) {
6031                    continue;
6032                }
6033                int adj = proc.setAdj;
6034                if (adj >= worstType && !proc.killedBackground) {
6035                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
6036                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6037                            proc.processName, adj, reason);
6038                    killed = true;
6039                    proc.killedBackground = true;
6040                    Process.killProcessQuiet(pids[i]);
6041                }
6042            }
6043        }
6044        return killed;
6045    }
6046
6047    public final void startRunning(String pkg, String cls, String action,
6048            String data) {
6049        synchronized(this) {
6050            if (mStartRunning) {
6051                return;
6052            }
6053            mStartRunning = true;
6054            mTopComponent = pkg != null && cls != null
6055                    ? new ComponentName(pkg, cls) : null;
6056            mTopAction = action != null ? action : Intent.ACTION_MAIN;
6057            mTopData = data;
6058            if (!mSystemReady) {
6059                return;
6060            }
6061        }
6062
6063        systemReady(null);
6064    }
6065
6066    private void retrieveSettings() {
6067        final ContentResolver resolver = mContext.getContentResolver();
6068        String debugApp = Settings.System.getString(
6069            resolver, Settings.System.DEBUG_APP);
6070        boolean waitForDebugger = Settings.System.getInt(
6071            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6072        boolean alwaysFinishActivities = Settings.System.getInt(
6073            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6074
6075        Configuration configuration = new Configuration();
6076        Settings.System.getConfiguration(resolver, configuration);
6077
6078        synchronized (this) {
6079            mDebugApp = mOrigDebugApp = debugApp;
6080            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6081            mAlwaysFinishActivities = alwaysFinishActivities;
6082            // This happens before any activities are started, so we can
6083            // change mConfiguration in-place.
6084            mConfiguration.updateFrom(configuration);
6085            mConfigurationSeq = mConfiguration.seq = 1;
6086            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
6087        }
6088    }
6089
6090    public boolean testIsSystemReady() {
6091        // no need to synchronize(this) just to read & return the value
6092        return mSystemReady;
6093    }
6094
6095    private static File getCalledPreBootReceiversFile() {
6096        File dataDir = Environment.getDataDirectory();
6097        File systemDir = new File(dataDir, "system");
6098        File fname = new File(systemDir, "called_pre_boots.dat");
6099        return fname;
6100    }
6101
6102    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6103        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6104        File file = getCalledPreBootReceiversFile();
6105        FileInputStream fis = null;
6106        try {
6107            fis = new FileInputStream(file);
6108            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6109            int vers = dis.readInt();
6110            String codename = dis.readUTF();
6111            if (vers == android.os.Build.VERSION.SDK_INT
6112                    && codename.equals(android.os.Build.VERSION.CODENAME)) {
6113                int num = dis.readInt();
6114                while (num > 0) {
6115                    num--;
6116                    String pkg = dis.readUTF();
6117                    String cls = dis.readUTF();
6118                    lastDoneReceivers.add(new ComponentName(pkg, cls));
6119                }
6120            }
6121        } catch (FileNotFoundException e) {
6122        } catch (IOException e) {
6123            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6124        } finally {
6125            if (fis != null) {
6126                try {
6127                    fis.close();
6128                } catch (IOException e) {
6129                }
6130            }
6131        }
6132        return lastDoneReceivers;
6133    }
6134
6135    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6136        File file = getCalledPreBootReceiversFile();
6137        FileOutputStream fos = null;
6138        DataOutputStream dos = null;
6139        try {
6140            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6141            fos = new FileOutputStream(file);
6142            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6143            dos.writeInt(android.os.Build.VERSION.SDK_INT);
6144            dos.writeUTF(android.os.Build.VERSION.CODENAME);
6145            dos.writeInt(list.size());
6146            for (int i=0; i<list.size(); i++) {
6147                dos.writeUTF(list.get(i).getPackageName());
6148                dos.writeUTF(list.get(i).getClassName());
6149            }
6150        } catch (IOException e) {
6151            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6152            file.delete();
6153        } finally {
6154            FileUtils.sync(fos);
6155            if (dos != null) {
6156                try {
6157                    dos.close();
6158                } catch (IOException e) {
6159                    // TODO Auto-generated catch block
6160                    e.printStackTrace();
6161                }
6162            }
6163        }
6164    }
6165
6166    public void systemReady(final Runnable goingCallback) {
6167        // In the simulator, startRunning will never have been called, which
6168        // normally sets a few crucial variables. Do it here instead.
6169        if (!Process.supportsProcesses()) {
6170            mStartRunning = true;
6171            mTopAction = Intent.ACTION_MAIN;
6172        }
6173
6174        synchronized(this) {
6175            if (mSystemReady) {
6176                if (goingCallback != null) goingCallback.run();
6177                return;
6178            }
6179
6180            // Check to see if there are any update receivers to run.
6181            if (!mDidUpdate) {
6182                if (mWaitingUpdate) {
6183                    return;
6184                }
6185                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6186                List<ResolveInfo> ris = null;
6187                try {
6188                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
6189                                intent, null, 0);
6190                } catch (RemoteException e) {
6191                }
6192                if (ris != null) {
6193                    for (int i=ris.size()-1; i>=0; i--) {
6194                        if ((ris.get(i).activityInfo.applicationInfo.flags
6195                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
6196                            ris.remove(i);
6197                        }
6198                    }
6199                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
6200
6201                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6202
6203                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
6204                    for (int i=0; i<ris.size(); i++) {
6205                        ActivityInfo ai = ris.get(i).activityInfo;
6206                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
6207                        if (lastDoneReceivers.contains(comp)) {
6208                            ris.remove(i);
6209                            i--;
6210                        }
6211                    }
6212
6213                    for (int i=0; i<ris.size(); i++) {
6214                        ActivityInfo ai = ris.get(i).activityInfo;
6215                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
6216                        doneReceivers.add(comp);
6217                        intent.setComponent(comp);
6218                        IIntentReceiver finisher = null;
6219                        if (i == ris.size()-1) {
6220                            finisher = new IIntentReceiver.Stub() {
6221                                public void performReceive(Intent intent, int resultCode,
6222                                        String data, Bundle extras, boolean ordered,
6223                                        boolean sticky) {
6224                                    // The raw IIntentReceiver interface is called
6225                                    // with the AM lock held, so redispatch to
6226                                    // execute our code without the lock.
6227                                    mHandler.post(new Runnable() {
6228                                        public void run() {
6229                                            synchronized (ActivityManagerService.this) {
6230                                                mDidUpdate = true;
6231                                            }
6232                                            writeLastDonePreBootReceivers(doneReceivers);
6233                                            systemReady(goingCallback);
6234                                        }
6235                                    });
6236                                }
6237                            };
6238                        }
6239                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
6240                        broadcastIntentLocked(null, null, intent, null, finisher,
6241                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
6242                        if (finisher != null) {
6243                            mWaitingUpdate = true;
6244                        }
6245                    }
6246                }
6247                if (mWaitingUpdate) {
6248                    return;
6249                }
6250                mDidUpdate = true;
6251            }
6252
6253            mSystemReady = true;
6254            if (!mStartRunning) {
6255                return;
6256            }
6257        }
6258
6259        ArrayList<ProcessRecord> procsToKill = null;
6260        synchronized(mPidsSelfLocked) {
6261            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6262                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6263                if (!isAllowedWhileBooting(proc.info)){
6264                    if (procsToKill == null) {
6265                        procsToKill = new ArrayList<ProcessRecord>();
6266                    }
6267                    procsToKill.add(proc);
6268                }
6269            }
6270        }
6271
6272        synchronized(this) {
6273            if (procsToKill != null) {
6274                for (int i=procsToKill.size()-1; i>=0; i--) {
6275                    ProcessRecord proc = procsToKill.get(i);
6276                    Slog.i(TAG, "Removing system update proc: " + proc);
6277                    removeProcessLocked(proc, true);
6278                }
6279            }
6280
6281            // Now that we have cleaned up any update processes, we
6282            // are ready to start launching real processes and know that
6283            // we won't trample on them any more.
6284            mProcessesReady = true;
6285        }
6286
6287        Slog.i(TAG, "System now ready");
6288        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
6289            SystemClock.uptimeMillis());
6290
6291        synchronized(this) {
6292            // Make sure we have no pre-ready processes sitting around.
6293
6294            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6295                ResolveInfo ri = mContext.getPackageManager()
6296                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
6297                                STOCK_PM_FLAGS);
6298                CharSequence errorMsg = null;
6299                if (ri != null) {
6300                    ActivityInfo ai = ri.activityInfo;
6301                    ApplicationInfo app = ai.applicationInfo;
6302                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6303                        mTopAction = Intent.ACTION_FACTORY_TEST;
6304                        mTopData = null;
6305                        mTopComponent = new ComponentName(app.packageName,
6306                                ai.name);
6307                    } else {
6308                        errorMsg = mContext.getResources().getText(
6309                                com.android.internal.R.string.factorytest_not_system);
6310                    }
6311                } else {
6312                    errorMsg = mContext.getResources().getText(
6313                            com.android.internal.R.string.factorytest_no_action);
6314                }
6315                if (errorMsg != null) {
6316                    mTopAction = null;
6317                    mTopData = null;
6318                    mTopComponent = null;
6319                    Message msg = Message.obtain();
6320                    msg.what = SHOW_FACTORY_ERROR_MSG;
6321                    msg.getData().putCharSequence("msg", errorMsg);
6322                    mHandler.sendMessage(msg);
6323                }
6324            }
6325        }
6326
6327        retrieveSettings();
6328
6329        if (goingCallback != null) goingCallback.run();
6330
6331        synchronized (this) {
6332            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6333                try {
6334                    List apps = AppGlobals.getPackageManager().
6335                        getPersistentApplications(STOCK_PM_FLAGS);
6336                    if (apps != null) {
6337                        int N = apps.size();
6338                        int i;
6339                        for (i=0; i<N; i++) {
6340                            ApplicationInfo info
6341                                = (ApplicationInfo)apps.get(i);
6342                            if (info != null &&
6343                                    !info.packageName.equals("android")) {
6344                                addAppLocked(info);
6345                            }
6346                        }
6347                    }
6348                } catch (RemoteException ex) {
6349                    // pm is in same process, this will never happen.
6350                }
6351            }
6352
6353            // Start up initial activity.
6354            mBooting = true;
6355
6356            try {
6357                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
6358                    Message msg = Message.obtain();
6359                    msg.what = SHOW_UID_ERROR_MSG;
6360                    mHandler.sendMessage(msg);
6361                }
6362            } catch (RemoteException e) {
6363            }
6364
6365            mMainStack.resumeTopActivityLocked(null);
6366        }
6367    }
6368
6369    private boolean makeAppCrashingLocked(ProcessRecord app,
6370            String shortMsg, String longMsg, String stackTrace) {
6371        app.crashing = true;
6372        app.crashingReport = generateProcessError(app,
6373                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
6374        startAppProblemLocked(app);
6375        app.stopFreezingAllLocked();
6376        return handleAppCrashLocked(app);
6377    }
6378
6379    private void makeAppNotRespondingLocked(ProcessRecord app,
6380            String activity, String shortMsg, String longMsg) {
6381        app.notResponding = true;
6382        app.notRespondingReport = generateProcessError(app,
6383                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6384                activity, shortMsg, longMsg, null);
6385        startAppProblemLocked(app);
6386        app.stopFreezingAllLocked();
6387    }
6388
6389    /**
6390     * Generate a process error record, suitable for attachment to a ProcessRecord.
6391     *
6392     * @param app The ProcessRecord in which the error occurred.
6393     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
6394     *                      ActivityManager.AppErrorStateInfo
6395     * @param activity The activity associated with the crash, if known.
6396     * @param shortMsg Short message describing the crash.
6397     * @param longMsg Long message describing the crash.
6398     * @param stackTrace Full crash stack trace, may be null.
6399     *
6400     * @return Returns a fully-formed AppErrorStateInfo record.
6401     */
6402    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
6403            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
6404        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
6405
6406        report.condition = condition;
6407        report.processName = app.processName;
6408        report.pid = app.pid;
6409        report.uid = app.info.uid;
6410        report.tag = activity;
6411        report.shortMsg = shortMsg;
6412        report.longMsg = longMsg;
6413        report.stackTrace = stackTrace;
6414
6415        return report;
6416    }
6417
6418    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
6419        synchronized (this) {
6420            app.crashing = false;
6421            app.crashingReport = null;
6422            app.notResponding = false;
6423            app.notRespondingReport = null;
6424            if (app.anrDialog == fromDialog) {
6425                app.anrDialog = null;
6426            }
6427            if (app.waitDialog == fromDialog) {
6428                app.waitDialog = null;
6429            }
6430            if (app.pid > 0 && app.pid != MY_PID) {
6431                handleAppCrashLocked(app);
6432                Slog.i(ActivityManagerService.TAG, "Killing "
6433                        + app.processName + " (pid=" + app.pid + "): user's request");
6434                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6435                        app.processName, app.setAdj, "user's request after error");
6436                Process.killProcess(app.pid);
6437            }
6438        }
6439    }
6440
6441    private boolean handleAppCrashLocked(ProcessRecord app) {
6442        long now = SystemClock.uptimeMillis();
6443
6444        Long crashTime = mProcessCrashTimes.get(app.info.processName,
6445                app.info.uid);
6446        if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
6447            // This process loses!
6448            Slog.w(TAG, "Process " + app.info.processName
6449                    + " has crashed too many times: killing!");
6450            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
6451                    app.info.processName, app.info.uid);
6452            killServicesLocked(app, false);
6453            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6454                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6455                if (r.app == app) {
6456                    Slog.w(TAG, "  Force finishing activity "
6457                        + r.intent.getComponent().flattenToShortString());
6458                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
6459                }
6460            }
6461            if (!app.persistent) {
6462                // We don't want to start this process again until the user
6463                // explicitly does so...  but for persistent process, we really
6464                // need to keep it running.  If a persistent process is actually
6465                // repeatedly crashing, then badness for everyone.
6466                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
6467                        app.info.processName);
6468                mBadProcesses.put(app.info.processName, app.info.uid, now);
6469                app.bad = true;
6470                mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6471                app.removed = true;
6472                removeProcessLocked(app, false);
6473                return false;
6474            }
6475        } else {
6476            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
6477            if (r.app == app) {
6478                // If the top running activity is from this crashing
6479                // process, then terminate it to avoid getting in a loop.
6480                Slog.w(TAG, "  Force finishing activity "
6481                        + r.intent.getComponent().flattenToShortString());
6482                int index = mMainStack.indexOfTokenLocked(r);
6483                r.stack.finishActivityLocked(r, index,
6484                        Activity.RESULT_CANCELED, null, "crashed");
6485                // Also terminate an activities below it that aren't yet
6486                // stopped, to avoid a situation where one will get
6487                // re-start our crashing activity once it gets resumed again.
6488                index--;
6489                if (index >= 0) {
6490                    r = (ActivityRecord)mMainStack.mHistory.get(index);
6491                    if (r.state == ActivityState.RESUMED
6492                            || r.state == ActivityState.PAUSING
6493                            || r.state == ActivityState.PAUSED) {
6494                        if (!r.isHomeActivity) {
6495                            Slog.w(TAG, "  Force finishing activity "
6496                                    + r.intent.getComponent().flattenToShortString());
6497                            r.stack.finishActivityLocked(r, index,
6498                                    Activity.RESULT_CANCELED, null, "crashed");
6499                        }
6500                    }
6501                }
6502            }
6503        }
6504
6505        // Bump up the crash count of any services currently running in the proc.
6506        if (app.services.size() != 0) {
6507            // Any services running in the application need to be placed
6508            // back in the pending list.
6509            Iterator<ServiceRecord> it = app.services.iterator();
6510            while (it.hasNext()) {
6511                ServiceRecord sr = it.next();
6512                sr.crashCount++;
6513            }
6514        }
6515
6516        // If the crashing process is what we consider to be the "home process" and it has been
6517        // replaced by a third-party app, clear the package preferred activities from packages
6518        // with a home activity running in the process to prevent a repeatedly crashing app
6519        // from blocking the user to manually clear the list.
6520        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6521                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6522            Iterator it = mHomeProcess.activities.iterator();
6523            while (it.hasNext()) {
6524                ActivityRecord r = (ActivityRecord)it.next();
6525                if (r.isHomeActivity) {
6526                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6527                    try {
6528                        ActivityThread.getPackageManager()
6529                                .clearPackagePreferredActivities(r.packageName);
6530                    } catch (RemoteException c) {
6531                        // pm is in same process, this will never happen.
6532                    }
6533                }
6534            }
6535        }
6536
6537        mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6538        return true;
6539    }
6540
6541    void startAppProblemLocked(ProcessRecord app) {
6542        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6543                mContext, app.info.packageName, app.info.flags);
6544        skipCurrentReceiverLocked(app);
6545    }
6546
6547    void skipCurrentReceiverLocked(ProcessRecord app) {
6548        boolean reschedule = false;
6549        BroadcastRecord r = app.curReceiver;
6550        if (r != null) {
6551            // The current broadcast is waiting for this app's receiver
6552            // to be finished.  Looks like that's not going to happen, so
6553            // let the broadcast continue.
6554            logBroadcastReceiverDiscardLocked(r);
6555            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6556                    r.resultExtras, r.resultAbort, true);
6557            reschedule = true;
6558        }
6559        r = mPendingBroadcast;
6560        if (r != null && r.curApp == app) {
6561            if (DEBUG_BROADCAST) Slog.v(TAG,
6562                    "skip & discard pending app " + r);
6563            logBroadcastReceiverDiscardLocked(r);
6564            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6565                    r.resultExtras, r.resultAbort, true);
6566            reschedule = true;
6567        }
6568        if (reschedule) {
6569            scheduleBroadcastsLocked();
6570        }
6571    }
6572
6573    /**
6574     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6575     * The application process will exit immediately after this call returns.
6576     * @param app object of the crashing app, null for the system server
6577     * @param crashInfo describing the exception
6578     */
6579    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
6580        ProcessRecord r = findAppProcess(app);
6581
6582        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6583                app == null ? "system" : (r == null ? "unknown" : r.processName),
6584                r == null ? -1 : r.info.flags,
6585                crashInfo.exceptionClassName,
6586                crashInfo.exceptionMessage,
6587                crashInfo.throwFileName,
6588                crashInfo.throwLineNumber);
6589
6590        addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
6591
6592        crashApplication(r, crashInfo);
6593    }
6594
6595    public void handleApplicationStrictModeViolation(
6596            IBinder app,
6597            int violationMask,
6598            StrictMode.ViolationInfo info) {
6599        ProcessRecord r = findAppProcess(app);
6600
6601        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
6602            Integer stackFingerprint = info.crashInfo.stackTrace.hashCode();
6603            boolean logIt = true;
6604            synchronized (mAlreadyLoggedViolatedStacks) {
6605                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
6606                    logIt = false;
6607                    // TODO: sub-sample into EventLog for these, with
6608                    // the info.durationMillis?  Then we'd get
6609                    // the relative pain numbers, without logging all
6610                    // the stack traces repeatedly.  We'd want to do
6611                    // likewise in the client code, which also does
6612                    // dup suppression, before the Binder call.
6613                } else {
6614                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
6615                        mAlreadyLoggedViolatedStacks.clear();
6616                    }
6617                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
6618                }
6619            }
6620            if (logIt) {
6621                logStrictModeViolationToDropBox(r, info);
6622            }
6623        }
6624
6625        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
6626            AppErrorResult result = new AppErrorResult();
6627            synchronized (this) {
6628                final long origId = Binder.clearCallingIdentity();
6629
6630                Message msg = Message.obtain();
6631                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
6632                HashMap<String, Object> data = new HashMap<String, Object>();
6633                data.put("result", result);
6634                data.put("app", r);
6635                data.put("violationMask", violationMask);
6636                data.put("info", info);
6637                msg.obj = data;
6638                mHandler.sendMessage(msg);
6639
6640                Binder.restoreCallingIdentity(origId);
6641            }
6642            int res = result.get();
6643            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
6644        }
6645    }
6646
6647    // Depending on the policy in effect, there could be a bunch of
6648    // these in quick succession so we try to batch these together to
6649    // minimize disk writes, number of dropbox entries, and maximize
6650    // compression, by having more fewer, larger records.
6651    private void logStrictModeViolationToDropBox(
6652            ProcessRecord process,
6653            StrictMode.ViolationInfo info) {
6654        if (info == null) {
6655            return;
6656        }
6657        final boolean isSystemApp = process == null ||
6658                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
6659                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
6660        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
6661        final DropBoxManager dbox = (DropBoxManager)
6662                mContext.getSystemService(Context.DROPBOX_SERVICE);
6663
6664        // Exit early if the dropbox isn't configured to accept this report type.
6665        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
6666
6667        boolean bufferWasEmpty;
6668        boolean needsFlush;
6669        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
6670        synchronized (sb) {
6671            bufferWasEmpty = sb.length() == 0;
6672            appendDropBoxProcessHeaders(process, sb);
6673            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
6674            sb.append("System-App: ").append(isSystemApp).append("\n");
6675            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
6676            if (info.violationNumThisLoop != 0) {
6677                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
6678            }
6679            if (info.numAnimationsRunning != 0) {
6680                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
6681            }
6682            if (info != null && info.durationMillis != -1) {
6683                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
6684            }
6685            sb.append("\n");
6686            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
6687                sb.append(info.crashInfo.stackTrace);
6688            }
6689            sb.append("\n");
6690
6691            // Only buffer up to ~64k.  Various logging bits truncate
6692            // things at 128k.
6693            needsFlush = (sb.length() > 64 * 1024);
6694        }
6695
6696        // Flush immediately if the buffer's grown too large, or this
6697        // is a non-system app.  Non-system apps are isolated with a
6698        // different tag & policy and not batched.
6699        //
6700        // Batching is useful during internal testing with
6701        // StrictMode settings turned up high.  Without batching,
6702        // thousands of separate files could be created on boot.
6703        if (!isSystemApp || needsFlush) {
6704            new Thread("Error dump: " + dropboxTag) {
6705                @Override
6706                public void run() {
6707                    String report;
6708                    synchronized (sb) {
6709                        report = sb.toString();
6710                        sb.delete(0, sb.length());
6711                        sb.trimToSize();
6712                    }
6713                    if (report.length() != 0) {
6714                        dbox.addText(dropboxTag, report);
6715                    }
6716                }
6717            }.start();
6718            return;
6719        }
6720
6721        // System app batching:
6722        if (!bufferWasEmpty) {
6723            // An existing dropbox-writing thread is outstanding, so
6724            // we don't need to start it up.  The existing thread will
6725            // catch the buffer appends we just did.
6726            return;
6727        }
6728
6729        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
6730        // (After this point, we shouldn't access AMS internal data structures.)
6731        new Thread("Error dump: " + dropboxTag) {
6732            @Override
6733            public void run() {
6734                // 5 second sleep to let stacks arrive and be batched together
6735                try {
6736                    Thread.sleep(5000);  // 5 seconds
6737                } catch (InterruptedException e) {}
6738
6739                String errorReport;
6740                synchronized (mStrictModeBuffer) {
6741                    errorReport = mStrictModeBuffer.toString();
6742                    if (errorReport.length() == 0) {
6743                        return;
6744                    }
6745                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
6746                    mStrictModeBuffer.trimToSize();
6747                }
6748                dbox.addText(dropboxTag, errorReport);
6749            }
6750        }.start();
6751    }
6752
6753    /**
6754     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
6755     * @param app object of the crashing app, null for the system server
6756     * @param tag reported by the caller
6757     * @param crashInfo describing the context of the error
6758     * @return true if the process should exit immediately (WTF is fatal)
6759     */
6760    public boolean handleApplicationWtf(IBinder app, String tag,
6761            ApplicationErrorReport.CrashInfo crashInfo) {
6762        ProcessRecord r = findAppProcess(app);
6763
6764        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
6765                app == null ? "system" : (r == null ? "unknown" : r.processName),
6766                r == null ? -1 : r.info.flags,
6767                tag, crashInfo.exceptionMessage);
6768
6769        addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
6770
6771        if (Settings.Secure.getInt(mContext.getContentResolver(),
6772                Settings.Secure.WTF_IS_FATAL, 0) != 0) {
6773            crashApplication(r, crashInfo);
6774            return true;
6775        } else {
6776            return false;
6777        }
6778    }
6779
6780    /**
6781     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
6782     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
6783     */
6784    private ProcessRecord findAppProcess(IBinder app) {
6785        if (app == null) {
6786            return null;
6787        }
6788
6789        synchronized (this) {
6790            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
6791                final int NA = apps.size();
6792                for (int ia=0; ia<NA; ia++) {
6793                    ProcessRecord p = apps.valueAt(ia);
6794                    if (p.thread != null && p.thread.asBinder() == app) {
6795                        return p;
6796                    }
6797                }
6798            }
6799
6800            Slog.w(TAG, "Can't find mystery application: " + app);
6801            return null;
6802        }
6803    }
6804
6805    /**
6806     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
6807     * to append various headers to the dropbox log text.
6808     */
6809    private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
6810        // Note: ProcessRecord 'process' is guarded by the service
6811        // instance.  (notably process.pkgList, which could otherwise change
6812        // concurrently during execution of this method)
6813        synchronized (this) {
6814            if (process == null || process.pid == MY_PID) {
6815                sb.append("Process: system_server\n");
6816            } else {
6817                sb.append("Process: ").append(process.processName).append("\n");
6818            }
6819            if (process == null) {
6820                return;
6821            }
6822            int flags = process.info.flags;
6823            IPackageManager pm = AppGlobals.getPackageManager();
6824            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
6825            for (String pkg : process.pkgList) {
6826                sb.append("Package: ").append(pkg);
6827                try {
6828                    PackageInfo pi = pm.getPackageInfo(pkg, 0);
6829                    if (pi != null) {
6830                        sb.append(" v").append(pi.versionCode);
6831                        if (pi.versionName != null) {
6832                            sb.append(" (").append(pi.versionName).append(")");
6833                        }
6834                    }
6835                } catch (RemoteException e) {
6836                    Slog.e(TAG, "Error getting package info: " + pkg, e);
6837                }
6838                sb.append("\n");
6839            }
6840        }
6841    }
6842
6843    private static String processClass(ProcessRecord process) {
6844        if (process == null || process.pid == MY_PID) {
6845            return "system_server";
6846        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
6847            return "system_app";
6848        } else {
6849            return "data_app";
6850        }
6851    }
6852
6853    /**
6854     * Write a description of an error (crash, WTF, ANR) to the drop box.
6855     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
6856     * @param process which caused the error, null means the system server
6857     * @param activity which triggered the error, null if unknown
6858     * @param parent activity related to the error, null if unknown
6859     * @param subject line related to the error, null if absent
6860     * @param report in long form describing the error, null if absent
6861     * @param logFile to include in the report, null if none
6862     * @param crashInfo giving an application stack trace, null if absent
6863     */
6864    public void addErrorToDropBox(String eventType,
6865            ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
6866            final String report, final File logFile,
6867            final ApplicationErrorReport.CrashInfo crashInfo) {
6868        // NOTE -- this must never acquire the ActivityManagerService lock,
6869        // otherwise the watchdog may be prevented from resetting the system.
6870
6871        final String dropboxTag = processClass(process) + "_" + eventType;
6872        final DropBoxManager dbox = (DropBoxManager)
6873                mContext.getSystemService(Context.DROPBOX_SERVICE);
6874
6875        // Exit early if the dropbox isn't configured to accept this report type.
6876        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
6877
6878        final StringBuilder sb = new StringBuilder(1024);
6879        appendDropBoxProcessHeaders(process, sb);
6880        if (activity != null) {
6881            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
6882        }
6883        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
6884            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
6885        }
6886        if (parent != null && parent != activity) {
6887            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
6888        }
6889        if (subject != null) {
6890            sb.append("Subject: ").append(subject).append("\n");
6891        }
6892        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
6893        if (Debug.isDebuggerConnected()) {
6894            sb.append("Debugger: Connected\n");
6895        }
6896        sb.append("\n");
6897
6898        // Do the rest in a worker thread to avoid blocking the caller on I/O
6899        // (After this point, we shouldn't access AMS internal data structures.)
6900        Thread worker = new Thread("Error dump: " + dropboxTag) {
6901            @Override
6902            public void run() {
6903                if (report != null) {
6904                    sb.append(report);
6905                }
6906                if (logFile != null) {
6907                    try {
6908                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
6909                    } catch (IOException e) {
6910                        Slog.e(TAG, "Error reading " + logFile, e);
6911                    }
6912                }
6913                if (crashInfo != null && crashInfo.stackTrace != null) {
6914                    sb.append(crashInfo.stackTrace);
6915                }
6916
6917                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
6918                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
6919                if (lines > 0) {
6920                    sb.append("\n");
6921
6922                    // Merge several logcat streams, and take the last N lines
6923                    InputStreamReader input = null;
6924                    try {
6925                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
6926                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
6927                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
6928
6929                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
6930                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
6931                        input = new InputStreamReader(logcat.getInputStream());
6932
6933                        int num;
6934                        char[] buf = new char[8192];
6935                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
6936                    } catch (IOException e) {
6937                        Slog.e(TAG, "Error running logcat", e);
6938                    } finally {
6939                        if (input != null) try { input.close(); } catch (IOException e) {}
6940                    }
6941                }
6942
6943                dbox.addText(dropboxTag, sb.toString());
6944            }
6945        };
6946
6947        if (process == null || process.pid == MY_PID) {
6948            worker.run();  // We may be about to die -- need to run this synchronously
6949        } else {
6950            worker.start();
6951        }
6952    }
6953
6954    /**
6955     * Bring up the "unexpected error" dialog box for a crashing app.
6956     * Deal with edge cases (intercepts from instrumented applications,
6957     * ActivityController, error intent receivers, that sort of thing).
6958     * @param r the application crashing
6959     * @param crashInfo describing the failure
6960     */
6961    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
6962        long timeMillis = System.currentTimeMillis();
6963        String shortMsg = crashInfo.exceptionClassName;
6964        String longMsg = crashInfo.exceptionMessage;
6965        String stackTrace = crashInfo.stackTrace;
6966        if (shortMsg != null && longMsg != null) {
6967            longMsg = shortMsg + ": " + longMsg;
6968        } else if (shortMsg != null) {
6969            longMsg = shortMsg;
6970        }
6971
6972        AppErrorResult result = new AppErrorResult();
6973        synchronized (this) {
6974            if (mController != null) {
6975                try {
6976                    String name = r != null ? r.processName : null;
6977                    int pid = r != null ? r.pid : Binder.getCallingPid();
6978                    if (!mController.appCrashed(name, pid,
6979                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
6980                        Slog.w(TAG, "Force-killing crashed app " + name
6981                                + " at watcher's request");
6982                        Process.killProcess(pid);
6983                        return;
6984                    }
6985                } catch (RemoteException e) {
6986                    mController = null;
6987                }
6988            }
6989
6990            final long origId = Binder.clearCallingIdentity();
6991
6992            // If this process is running instrumentation, finish it.
6993            if (r != null && r.instrumentationClass != null) {
6994                Slog.w(TAG, "Error in app " + r.processName
6995                      + " running instrumentation " + r.instrumentationClass + ":");
6996                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
6997                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
6998                Bundle info = new Bundle();
6999                info.putString("shortMsg", shortMsg);
7000                info.putString("longMsg", longMsg);
7001                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7002                Binder.restoreCallingIdentity(origId);
7003                return;
7004            }
7005
7006            // If we can't identify the process or it's already exceeded its crash quota,
7007            // quit right away without showing a crash dialog.
7008            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
7009                Binder.restoreCallingIdentity(origId);
7010                return;
7011            }
7012
7013            Message msg = Message.obtain();
7014            msg.what = SHOW_ERROR_MSG;
7015            HashMap data = new HashMap();
7016            data.put("result", result);
7017            data.put("app", r);
7018            msg.obj = data;
7019            mHandler.sendMessage(msg);
7020
7021            Binder.restoreCallingIdentity(origId);
7022        }
7023
7024        int res = result.get();
7025
7026        Intent appErrorIntent = null;
7027        synchronized (this) {
7028            if (r != null) {
7029                mProcessCrashTimes.put(r.info.processName, r.info.uid,
7030                        SystemClock.uptimeMillis());
7031            }
7032            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
7033                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
7034            }
7035        }
7036
7037        if (appErrorIntent != null) {
7038            try {
7039                mContext.startActivity(appErrorIntent);
7040            } catch (ActivityNotFoundException e) {
7041                Slog.w(TAG, "bug report receiver dissappeared", e);
7042            }
7043        }
7044    }
7045
7046    Intent createAppErrorIntentLocked(ProcessRecord r,
7047            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7048        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
7049        if (report == null) {
7050            return null;
7051        }
7052        Intent result = new Intent(Intent.ACTION_APP_ERROR);
7053        result.setComponent(r.errorReportReceiver);
7054        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7055        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7056        return result;
7057    }
7058
7059    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7060            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7061        if (r.errorReportReceiver == null) {
7062            return null;
7063        }
7064
7065        if (!r.crashing && !r.notResponding) {
7066            return null;
7067        }
7068
7069        ApplicationErrorReport report = new ApplicationErrorReport();
7070        report.packageName = r.info.packageName;
7071        report.installerPackageName = r.errorReportReceiver.getPackageName();
7072        report.processName = r.processName;
7073        report.time = timeMillis;
7074        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
7075
7076        if (r.crashing) {
7077            report.type = ApplicationErrorReport.TYPE_CRASH;
7078            report.crashInfo = crashInfo;
7079        } else if (r.notResponding) {
7080            report.type = ApplicationErrorReport.TYPE_ANR;
7081            report.anrInfo = new ApplicationErrorReport.AnrInfo();
7082
7083            report.anrInfo.activity = r.notRespondingReport.tag;
7084            report.anrInfo.cause = r.notRespondingReport.shortMsg;
7085            report.anrInfo.info = r.notRespondingReport.longMsg;
7086        }
7087
7088        return report;
7089    }
7090
7091    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7092        // assume our apps are happy - lazy create the list
7093        List<ActivityManager.ProcessErrorStateInfo> errList = null;
7094
7095        synchronized (this) {
7096
7097            // iterate across all processes
7098            for (int i=mLruProcesses.size()-1; i>=0; i--) {
7099                ProcessRecord app = mLruProcesses.get(i);
7100                if ((app.thread != null) && (app.crashing || app.notResponding)) {
7101                    // This one's in trouble, so we'll generate a report for it
7102                    // crashes are higher priority (in case there's a crash *and* an anr)
7103                    ActivityManager.ProcessErrorStateInfo report = null;
7104                    if (app.crashing) {
7105                        report = app.crashingReport;
7106                    } else if (app.notResponding) {
7107                        report = app.notRespondingReport;
7108                    }
7109
7110                    if (report != null) {
7111                        if (errList == null) {
7112                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7113                        }
7114                        errList.add(report);
7115                    } else {
7116                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
7117                                " crashing = " + app.crashing +
7118                                " notResponding = " + app.notResponding);
7119                    }
7120                }
7121            }
7122        }
7123
7124        return errList;
7125    }
7126
7127    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7128        // Lazy instantiation of list
7129        List<ActivityManager.RunningAppProcessInfo> runList = null;
7130        synchronized (this) {
7131            // Iterate across all processes
7132            for (int i=mLruProcesses.size()-1; i>=0; i--) {
7133                ProcessRecord app = mLruProcesses.get(i);
7134                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7135                    // Generate process state info for running application
7136                    ActivityManager.RunningAppProcessInfo currApp =
7137                        new ActivityManager.RunningAppProcessInfo(app.processName,
7138                                app.pid, app.getPackageList());
7139                    currApp.uid = app.info.uid;
7140                    if (mHeavyWeightProcess == app) {
7141                        currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
7142                    }
7143                    if (app.persistent) {
7144                        currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7145                    }
7146                    int adj = app.curAdj;
7147                    if (adj >= EMPTY_APP_ADJ) {
7148                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7149                    } else if (adj >= HIDDEN_APP_MIN_ADJ) {
7150                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7151                        currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
7152                    } else if (adj >= HOME_APP_ADJ) {
7153                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7154                        currApp.lru = 0;
7155                    } else if (adj >= SECONDARY_SERVER_ADJ) {
7156                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7157                    } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
7158                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7159                    } else if (adj >= PERCEPTIBLE_APP_ADJ) {
7160                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7161                    } else if (adj >= VISIBLE_APP_ADJ) {
7162                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7163                    } else {
7164                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7165                    }
7166                    currApp.importanceReasonCode = app.adjTypeCode;
7167                    if (app.adjSource instanceof ProcessRecord) {
7168                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
7169                    } else if (app.adjSource instanceof ActivityRecord) {
7170                        ActivityRecord r = (ActivityRecord)app.adjSource;
7171                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7172                    }
7173                    if (app.adjTarget instanceof ComponentName) {
7174                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7175                    }
7176                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
7177                    //        + " lru=" + currApp.lru);
7178                    if (runList == null) {
7179                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7180                    }
7181                    runList.add(currApp);
7182                }
7183            }
7184        }
7185        return runList;
7186    }
7187
7188    public List<ApplicationInfo> getRunningExternalApplications() {
7189        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7190        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7191        if (runningApps != null && runningApps.size() > 0) {
7192            Set<String> extList = new HashSet<String>();
7193            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7194                if (app.pkgList != null) {
7195                    for (String pkg : app.pkgList) {
7196                        extList.add(pkg);
7197                    }
7198                }
7199            }
7200            IPackageManager pm = AppGlobals.getPackageManager();
7201            for (String pkg : extList) {
7202                try {
7203                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7204                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7205                        retList.add(info);
7206                    }
7207                } catch (RemoteException e) {
7208                }
7209            }
7210        }
7211        return retList;
7212    }
7213
7214    @Override
7215    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
7216        if (checkCallingPermission(android.Manifest.permission.DUMP)
7217                != PackageManager.PERMISSION_GRANTED) {
7218            pw.println("Permission Denial: can't dump ActivityManager from from pid="
7219                    + Binder.getCallingPid()
7220                    + ", uid=" + Binder.getCallingUid()
7221                    + " without permission "
7222                    + android.Manifest.permission.DUMP);
7223            return;
7224        }
7225
7226        boolean dumpAll = false;
7227
7228        int opti = 0;
7229        while (opti < args.length) {
7230            String opt = args[opti];
7231            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7232                break;
7233            }
7234            opti++;
7235            if ("-a".equals(opt)) {
7236                dumpAll = true;
7237            } else if ("-h".equals(opt)) {
7238                pw.println("Activity manager dump options:");
7239                pw.println("  [-a] [-h] [cmd] ...");
7240                pw.println("  cmd may be one of:");
7241                pw.println("    a[ctivities]: activity stack state");
7242                pw.println("    b[roadcasts]: broadcast state");
7243                pw.println("    i[ntents]: pending intent state");
7244                pw.println("    p[rocesses]: process state");
7245                pw.println("    o[om]: out of memory management");
7246                pw.println("    prov[iders]: content provider state");
7247                pw.println("    s[ervices]: service state");
7248                pw.println("    service [name]: service client-side state");
7249                return;
7250            } else {
7251                pw.println("Unknown argument: " + opt + "; use -h for help");
7252            }
7253        }
7254
7255        // Is the caller requesting to dump a particular piece of data?
7256        if (opti < args.length) {
7257            String cmd = args[opti];
7258            opti++;
7259            if ("activities".equals(cmd) || "a".equals(cmd)) {
7260                synchronized (this) {
7261                    dumpActivitiesLocked(fd, pw, args, opti, true, true);
7262                }
7263                return;
7264            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7265                synchronized (this) {
7266                    dumpBroadcastsLocked(fd, pw, args, opti, true);
7267                }
7268                return;
7269            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7270                synchronized (this) {
7271                    dumpPendingIntentsLocked(fd, pw, args, opti, true);
7272                }
7273                return;
7274            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7275                synchronized (this) {
7276                    dumpProcessesLocked(fd, pw, args, opti, true);
7277                }
7278                return;
7279            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7280                synchronized (this) {
7281                    dumpOomLocked(fd, pw, args, opti, true);
7282                }
7283                return;
7284            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7285                synchronized (this) {
7286                    dumpProvidersLocked(fd, pw, args, opti, true);
7287                }
7288                return;
7289            } else if ("service".equals(cmd)) {
7290                dumpService(fd, pw, args, opti);
7291                return;
7292            } else if ("services".equals(cmd) || "s".equals(cmd)) {
7293                synchronized (this) {
7294                    dumpServicesLocked(fd, pw, args, opti, true);
7295                }
7296                return;
7297            } else {
7298                // Dumping a single activity?
7299                if (dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7300                    return;
7301                }
7302                pw.println("Bad activity command: " + cmd);
7303            }
7304        }
7305
7306        // No piece of data specified, dump everything.
7307        synchronized (this) {
7308            boolean needSep;
7309            if (dumpAll) {
7310                pw.println("Providers in Current Activity Manager State:");
7311            }
7312            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
7313            if (needSep) {
7314                pw.println(" ");
7315            }
7316            if (dumpAll) {
7317                pw.println("-------------------------------------------------------------------------------");
7318                pw.println("Broadcasts in Current Activity Manager State:");
7319            }
7320            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7321            if (needSep) {
7322                pw.println(" ");
7323            }
7324            if (dumpAll) {
7325                pw.println("-------------------------------------------------------------------------------");
7326                pw.println("Services in Current Activity Manager State:");
7327            }
7328            needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll);
7329            if (needSep) {
7330                pw.println(" ");
7331            }
7332            if (dumpAll) {
7333                pw.println("-------------------------------------------------------------------------------");
7334                pw.println("PendingIntents in Current Activity Manager State:");
7335            }
7336            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
7337            if (needSep) {
7338                pw.println(" ");
7339            }
7340            if (dumpAll) {
7341                pw.println("-------------------------------------------------------------------------------");
7342                pw.println("Activities in Current Activity Manager State:");
7343            }
7344            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, !dumpAll);
7345            if (needSep) {
7346                pw.println(" ");
7347            }
7348            if (dumpAll) {
7349                pw.println("-------------------------------------------------------------------------------");
7350                pw.println("Processes in Current Activity Manager State:");
7351            }
7352            dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7353        }
7354    }
7355
7356    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7357            int opti, boolean dumpAll, boolean needHeader) {
7358        if (needHeader) {
7359            pw.println("  Activity stack:");
7360        }
7361        dumpHistoryList(pw, mMainStack.mHistory, "  ", "Hist", true);
7362        pw.println(" ");
7363        pw.println("  Running activities (most recent first):");
7364        dumpHistoryList(pw, mMainStack.mLRUActivities, "  ", "Run", false);
7365        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
7366            pw.println(" ");
7367            pw.println("  Activities waiting for another to become visible:");
7368            dumpHistoryList(pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false);
7369        }
7370        if (mMainStack.mStoppingActivities.size() > 0) {
7371            pw.println(" ");
7372            pw.println("  Activities waiting to stop:");
7373            dumpHistoryList(pw, mMainStack.mStoppingActivities, "  ", "Stop", false);
7374        }
7375        if (mMainStack.mFinishingActivities.size() > 0) {
7376            pw.println(" ");
7377            pw.println("  Activities waiting to finish:");
7378            dumpHistoryList(pw, mMainStack.mFinishingActivities, "  ", "Fin", false);
7379        }
7380
7381        pw.println(" ");
7382        pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
7383        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
7384        pw.println("  mFocusedActivity: " + mFocusedActivity);
7385        pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7386
7387        if (dumpAll && mRecentTasks.size() > 0) {
7388            pw.println(" ");
7389            pw.println("Recent tasks in Current Activity Manager State:");
7390
7391            final int N = mRecentTasks.size();
7392            for (int i=0; i<N; i++) {
7393                TaskRecord tr = mRecentTasks.get(i);
7394                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
7395                        pw.println(tr);
7396                mRecentTasks.get(i).dump(pw, "    ");
7397            }
7398        }
7399
7400        pw.println(" ");
7401        pw.println("  mCurTask: " + mCurTask);
7402
7403        return true;
7404    }
7405
7406    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7407            int opti, boolean dumpAll) {
7408        boolean needSep = false;
7409        int numPers = 0;
7410
7411        if (dumpAll) {
7412            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7413                final int NA = procs.size();
7414                for (int ia=0; ia<NA; ia++) {
7415                    if (!needSep) {
7416                        pw.println("  All known processes:");
7417                        needSep = true;
7418                    }
7419                    ProcessRecord r = procs.valueAt(ia);
7420                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
7421                        pw.print(" UID "); pw.print(procs.keyAt(ia));
7422                        pw.print(" "); pw.println(r);
7423                    r.dump(pw, "    ");
7424                    if (r.persistent) {
7425                        numPers++;
7426                    }
7427                }
7428            }
7429        }
7430
7431        if (mLruProcesses.size() > 0) {
7432            if (needSep) pw.println(" ");
7433            needSep = true;
7434            pw.println("  Running processes (most recent first):");
7435            dumpProcessOomList(pw, this, mLruProcesses, "    ",
7436                    "Proc", "PERS", false);
7437            needSep = true;
7438        }
7439
7440        synchronized (mPidsSelfLocked) {
7441            if (mPidsSelfLocked.size() > 0) {
7442                if (needSep) pw.println(" ");
7443                needSep = true;
7444                pw.println("  PID mappings:");
7445                for (int i=0; i<mPidsSelfLocked.size(); i++) {
7446                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7447                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7448                }
7449            }
7450        }
7451
7452        if (mForegroundProcesses.size() > 0) {
7453            if (needSep) pw.println(" ");
7454            needSep = true;
7455            pw.println("  Foreground Processes:");
7456            for (int i=0; i<mForegroundProcesses.size(); i++) {
7457                pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
7458                        pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
7459            }
7460        }
7461
7462        if (mPersistentStartingProcesses.size() > 0) {
7463            if (needSep) pw.println(" ");
7464            needSep = true;
7465            pw.println("  Persisent processes that are starting:");
7466            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
7467                    "Starting Norm", "Restarting PERS");
7468        }
7469
7470        if (mStartingProcesses.size() > 0) {
7471            if (needSep) pw.println(" ");
7472            needSep = true;
7473            pw.println("  Processes that are starting:");
7474            dumpProcessList(pw, this, mStartingProcesses, "    ",
7475                    "Starting Norm", "Starting PERS");
7476        }
7477
7478        if (mRemovedProcesses.size() > 0) {
7479            if (needSep) pw.println(" ");
7480            needSep = true;
7481            pw.println("  Processes that are being removed:");
7482            dumpProcessList(pw, this, mRemovedProcesses, "    ",
7483                    "Removed Norm", "Removed PERS");
7484        }
7485
7486        if (mProcessesOnHold.size() > 0) {
7487            if (needSep) pw.println(" ");
7488            needSep = true;
7489            pw.println("  Processes that are on old until the system is ready:");
7490            dumpProcessList(pw, this, mProcessesOnHold, "    ",
7491                    "OnHold Norm", "OnHold PERS");
7492        }
7493
7494        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
7495
7496        if (mProcessCrashTimes.getMap().size() > 0) {
7497            if (needSep) pw.println(" ");
7498            needSep = true;
7499            pw.println("  Time since processes crashed:");
7500            long now = SystemClock.uptimeMillis();
7501            for (Map.Entry<String, SparseArray<Long>> procs
7502                    : mProcessCrashTimes.getMap().entrySet()) {
7503                SparseArray<Long> uids = procs.getValue();
7504                final int N = uids.size();
7505                for (int i=0; i<N; i++) {
7506                    pw.print("    Process "); pw.print(procs.getKey());
7507                            pw.print(" uid "); pw.print(uids.keyAt(i));
7508                            pw.print(": last crashed ");
7509                            pw.print((now-uids.valueAt(i)));
7510                            pw.println(" ms ago");
7511                }
7512            }
7513        }
7514
7515        if (mBadProcesses.getMap().size() > 0) {
7516            if (needSep) pw.println(" ");
7517            needSep = true;
7518            pw.println("  Bad processes:");
7519            for (Map.Entry<String, SparseArray<Long>> procs
7520                    : mBadProcesses.getMap().entrySet()) {
7521                SparseArray<Long> uids = procs.getValue();
7522                final int N = uids.size();
7523                for (int i=0; i<N; i++) {
7524                    pw.print("    Bad process "); pw.print(procs.getKey());
7525                            pw.print(" uid "); pw.print(uids.keyAt(i));
7526                            pw.print(": crashed at time ");
7527                            pw.println(uids.valueAt(i));
7528                }
7529            }
7530        }
7531
7532        pw.println(" ");
7533        pw.println("  mHomeProcess: " + mHomeProcess);
7534        if (mHeavyWeightProcess != null) {
7535            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
7536        }
7537        pw.println("  mConfiguration: " + mConfiguration);
7538        pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
7539        pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
7540        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
7541                || mOrigWaitForDebugger) {
7542            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
7543                    + " mDebugTransient=" + mDebugTransient
7544                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
7545        }
7546        if (mAlwaysFinishActivities || mController != null) {
7547            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
7548                    + " mController=" + mController);
7549        }
7550        if (dumpAll) {
7551            pw.println("  Total persistent processes: " + numPers);
7552            pw.println("  mStartRunning=" + mStartRunning
7553                    + " mProcessesReady=" + mProcessesReady
7554                    + " mSystemReady=" + mSystemReady);
7555            pw.println("  mBooting=" + mBooting
7556                    + " mBooted=" + mBooted
7557                    + " mFactoryTest=" + mFactoryTest);
7558            pw.print("  mLastPowerCheckRealtime=");
7559                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
7560                    pw.println("");
7561            pw.print("  mLastPowerCheckUptime=");
7562                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
7563                    pw.println("");
7564            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
7565            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
7566            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
7567        }
7568
7569        return true;
7570    }
7571
7572    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
7573            int opti, boolean needSep, boolean dumpAll) {
7574        if (mProcessesToGc.size() > 0) {
7575            if (needSep) pw.println(" ");
7576            needSep = true;
7577            pw.println("  Processes that are waiting to GC:");
7578            long now = SystemClock.uptimeMillis();
7579            for (int i=0; i<mProcessesToGc.size(); i++) {
7580                ProcessRecord proc = mProcessesToGc.get(i);
7581                pw.print("    Process "); pw.println(proc);
7582                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
7583                        pw.print(", last gced=");
7584                        pw.print(now-proc.lastRequestedGc);
7585                        pw.print(" ms ago, last lowMem=");
7586                        pw.print(now-proc.lastLowMemory);
7587                        pw.println(" ms ago");
7588
7589            }
7590        }
7591        return needSep;
7592    }
7593
7594    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7595            int opti, boolean dumpAll) {
7596        boolean needSep = false;
7597
7598        if (mLruProcesses.size() > 0) {
7599            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
7600
7601            Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
7602                @Override
7603                public int compare(ProcessRecord object1, ProcessRecord object2) {
7604                    if (object1.setAdj != object2.setAdj) {
7605                        return object1.setAdj > object2.setAdj ? -1 : 1;
7606                    }
7607                    if (object1.setSchedGroup != object2.setSchedGroup) {
7608                        return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
7609                    }
7610                    if (object1.keeping != object2.keeping) {
7611                        return object1.keeping ? -1 : 1;
7612                    }
7613                    if (object1.pid != object2.pid) {
7614                        return object1.pid > object2.pid ? -1 : 1;
7615                    }
7616                    return 0;
7617                }
7618            };
7619
7620            Collections.sort(procs, comparator);
7621
7622            if (needSep) pw.println(" ");
7623            needSep = true;
7624            pw.println("  Process OOM control:");
7625            dumpProcessOomList(pw, this, procs, "    ",
7626                    "Proc", "PERS", true);
7627            needSep = true;
7628        }
7629
7630        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
7631
7632        pw.println(" ");
7633        pw.println("  mHomeProcess: " + mHomeProcess);
7634        if (mHeavyWeightProcess != null) {
7635            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
7636        }
7637
7638        return true;
7639    }
7640
7641    /**
7642     * There are three ways to call this:
7643     *  - no service specified: dump all the services
7644     *  - a flattened component name that matched an existing service was specified as the
7645     *    first arg: dump that one service
7646     *  - the first arg isn't the flattened component name of an existing service:
7647     *    dump all services whose component contains the first arg as a substring
7648     */
7649    protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args, int opti) {
7650        String[] newArgs;
7651        String componentNameString;
7652        ServiceRecord r;
7653        if (opti >= args.length) {
7654            componentNameString = null;
7655            newArgs = EMPTY_STRING_ARRAY;
7656            r = null;
7657        } else {
7658            componentNameString = args[opti];
7659            opti++;
7660            ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
7661            synchronized (this) {
7662                r = componentName != null ? mServices.get(componentName) : null;
7663            }
7664            newArgs = new String[args.length - opti];
7665            if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7666        }
7667
7668        if (r != null) {
7669            dumpService(fd, pw, r, newArgs);
7670        } else {
7671            ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
7672            synchronized (this) {
7673                for (ServiceRecord r1 : mServices.values()) {
7674                    if (componentNameString == null
7675                            || r1.name.flattenToString().contains(componentNameString)) {
7676                        services.add(r1);
7677                    }
7678                }
7679            }
7680            for (int i=0; i<services.size(); i++) {
7681                dumpService(fd, pw, services.get(i), newArgs);
7682            }
7683        }
7684    }
7685
7686    /**
7687     * Invokes IApplicationThread.dumpService() on the thread of the specified service if
7688     * there is a thread associated with the service.
7689     */
7690    private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) {
7691        pw.println("------------------------------------------------------------"
7692                + "-------------------");
7693        pw.println("APP SERVICE: " + r.name.flattenToString());
7694        if (r.app != null && r.app.thread != null) {
7695            try {
7696                // flush anything that is already in the PrintWriter since the thread is going
7697                // to write to the file descriptor directly
7698                pw.flush();
7699                r.app.thread.dumpService(fd, r, args);
7700                pw.print("\n");
7701                pw.flush();
7702            } catch (RemoteException e) {
7703                pw.println("got a RemoteException while dumping the service");
7704            }
7705        }
7706    }
7707
7708    /**
7709     * There are three things that cmd can be:
7710     *  - a flattened component name that matched an existing activity
7711     *  - the cmd arg isn't the flattened component name of an existing activity:
7712     *    dump all activity whose component contains the cmd as a substring
7713     *  - A hex number of the ActivityRecord object instance.
7714     */
7715    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
7716            int opti, boolean dumpAll) {
7717        String[] newArgs;
7718        ComponentName componentName = ComponentName.unflattenFromString(name);
7719        int objectId = 0;
7720        try {
7721            objectId = Integer.parseInt(name, 16);
7722            name = null;
7723            componentName = null;
7724        } catch (RuntimeException e) {
7725        }
7726        newArgs = new String[args.length - opti];
7727        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7728
7729        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
7730        synchronized (this) {
7731            for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
7732                if (componentName != null) {
7733                    if (r1.intent.getComponent().equals(componentName)) {
7734                        activities.add(r1);
7735                    }
7736                } else if (name != null) {
7737                    if (r1.intent.getComponent().flattenToString().contains(name)) {
7738                        activities.add(r1);
7739                    }
7740                } else if (System.identityHashCode(this) == objectId) {
7741                    activities.add(r1);
7742                }
7743            }
7744        }
7745
7746        if (activities.size() <= 0) {
7747            return false;
7748        }
7749
7750        for (int i=0; i<activities.size(); i++) {
7751            dumpActivity(fd, pw, activities.get(i), newArgs, dumpAll);
7752        }
7753        return true;
7754    }
7755
7756    /**
7757     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
7758     * there is a thread associated with the activity.
7759     */
7760    private void dumpActivity(FileDescriptor fd, PrintWriter pw, ActivityRecord r, String[] args,
7761            boolean dumpAll) {
7762        pw.println("  Activity " + r.intent.getComponent().flattenToString());
7763        if (dumpAll) {
7764            synchronized (this) {
7765                pw.print("  * "); pw.println(r);
7766                r.dump(pw, "    ");
7767            }
7768            pw.println("");
7769        }
7770        if (r.app != null && r.app.thread != null) {
7771            try {
7772                // flush anything that is already in the PrintWriter since the thread is going
7773                // to write to the file descriptor directly
7774                pw.flush();
7775                r.app.thread.dumpActivity(fd, r, args);
7776                pw.print("\n");
7777                pw.flush();
7778            } catch (RemoteException e) {
7779                pw.println("got a RemoteException while dumping the activity");
7780            }
7781        }
7782    }
7783
7784    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7785            int opti, boolean dumpAll) {
7786        boolean needSep = false;
7787
7788        if (dumpAll) {
7789            if (mRegisteredReceivers.size() > 0) {
7790                pw.println(" ");
7791                pw.println("  Registered Receivers:");
7792                Iterator it = mRegisteredReceivers.values().iterator();
7793                while (it.hasNext()) {
7794                    ReceiverList r = (ReceiverList)it.next();
7795                    pw.print("  * "); pw.println(r);
7796                    r.dump(pw, "    ");
7797                }
7798            }
7799
7800            pw.println(" ");
7801            pw.println("Receiver Resolver Table:");
7802            mReceiverResolver.dump(pw, null, "  ", null, false);
7803            needSep = true;
7804        }
7805
7806        if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
7807                || mPendingBroadcast != null) {
7808            if (mParallelBroadcasts.size() > 0) {
7809                pw.println(" ");
7810                pw.println("  Active broadcasts:");
7811            }
7812            for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
7813                pw.println("  Broadcast #" + i + ":");
7814                mParallelBroadcasts.get(i).dump(pw, "    ");
7815            }
7816            if (mOrderedBroadcasts.size() > 0) {
7817                pw.println(" ");
7818                pw.println("  Active ordered broadcasts:");
7819            }
7820            for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
7821                pw.println("  Serialized Broadcast #" + i + ":");
7822                mOrderedBroadcasts.get(i).dump(pw, "    ");
7823            }
7824            pw.println(" ");
7825            pw.println("  Pending broadcast:");
7826            if (mPendingBroadcast != null) {
7827                mPendingBroadcast.dump(pw, "    ");
7828            } else {
7829                pw.println("    (null)");
7830            }
7831            needSep = true;
7832        }
7833
7834        if (dumpAll) {
7835            pw.println(" ");
7836            pw.println("  Historical broadcasts:");
7837            for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
7838                BroadcastRecord r = mBroadcastHistory[i];
7839                if (r == null) {
7840                    break;
7841                }
7842                pw.println("  Historical Broadcast #" + i + ":");
7843                r.dump(pw, "    ");
7844            }
7845            needSep = true;
7846        }
7847
7848        if (mStickyBroadcasts != null) {
7849            pw.println(" ");
7850            pw.println("  Sticky broadcasts:");
7851            StringBuilder sb = new StringBuilder(128);
7852            for (Map.Entry<String, ArrayList<Intent>> ent
7853                    : mStickyBroadcasts.entrySet()) {
7854                pw.print("  * Sticky action "); pw.print(ent.getKey());
7855                        pw.println(":");
7856                ArrayList<Intent> intents = ent.getValue();
7857                final int N = intents.size();
7858                for (int i=0; i<N; i++) {
7859                    sb.setLength(0);
7860                    sb.append("    Intent: ");
7861                    intents.get(i).toShortString(sb, true, false);
7862                    pw.println(sb.toString());
7863                    Bundle bundle = intents.get(i).getExtras();
7864                    if (bundle != null) {
7865                        pw.print("      ");
7866                        pw.println(bundle.toString());
7867                    }
7868                }
7869            }
7870            needSep = true;
7871        }
7872
7873        if (dumpAll) {
7874            pw.println(" ");
7875            pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
7876            pw.println("  mHandler:");
7877            mHandler.dump(new PrintWriterPrinter(pw), "    ");
7878            needSep = true;
7879        }
7880
7881        return needSep;
7882    }
7883
7884    boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7885            int opti, boolean dumpAll) {
7886        boolean needSep = false;
7887
7888        if (dumpAll) {
7889            if (mServices.size() > 0) {
7890                pw.println("  Active services:");
7891                Iterator<ServiceRecord> it = mServices.values().iterator();
7892                while (it.hasNext()) {
7893                    ServiceRecord r = it.next();
7894                    pw.print("  * "); pw.println(r);
7895                    r.dump(pw, "    ");
7896                }
7897                needSep = true;
7898            }
7899        }
7900
7901        if (mPendingServices.size() > 0) {
7902            if (needSep) pw.println(" ");
7903            pw.println("  Pending services:");
7904            for (int i=0; i<mPendingServices.size(); i++) {
7905                ServiceRecord r = mPendingServices.get(i);
7906                pw.print("  * Pending "); pw.println(r);
7907                r.dump(pw, "    ");
7908            }
7909            needSep = true;
7910        }
7911
7912        if (mRestartingServices.size() > 0) {
7913            if (needSep) pw.println(" ");
7914            pw.println("  Restarting services:");
7915            for (int i=0; i<mRestartingServices.size(); i++) {
7916                ServiceRecord r = mRestartingServices.get(i);
7917                pw.print("  * Restarting "); pw.println(r);
7918                r.dump(pw, "    ");
7919            }
7920            needSep = true;
7921        }
7922
7923        if (mStoppingServices.size() > 0) {
7924            if (needSep) pw.println(" ");
7925            pw.println("  Stopping services:");
7926            for (int i=0; i<mStoppingServices.size(); i++) {
7927                ServiceRecord r = mStoppingServices.get(i);
7928                pw.print("  * Stopping "); pw.println(r);
7929                r.dump(pw, "    ");
7930            }
7931            needSep = true;
7932        }
7933
7934        if (dumpAll) {
7935            if (mServiceConnections.size() > 0) {
7936                if (needSep) pw.println(" ");
7937                pw.println("  Connection bindings to services:");
7938                Iterator<ArrayList<ConnectionRecord>> it
7939                        = mServiceConnections.values().iterator();
7940                while (it.hasNext()) {
7941                    ArrayList<ConnectionRecord> r = it.next();
7942                    for (int i=0; i<r.size(); i++) {
7943                        pw.print("  * "); pw.println(r.get(i));
7944                        r.get(i).dump(pw, "    ");
7945                    }
7946                }
7947                needSep = true;
7948            }
7949        }
7950
7951        return needSep;
7952    }
7953
7954    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7955            int opti, boolean dumpAll) {
7956        boolean needSep = false;
7957
7958        if (dumpAll) {
7959            if (mProvidersByClass.size() > 0) {
7960                if (needSep) pw.println(" ");
7961                pw.println("  Published content providers (by class):");
7962                Iterator<Map.Entry<String, ContentProviderRecord>> it
7963                        = mProvidersByClass.entrySet().iterator();
7964                while (it.hasNext()) {
7965                    Map.Entry<String, ContentProviderRecord> e = it.next();
7966                    ContentProviderRecord r = e.getValue();
7967                    pw.print("  * "); pw.println(r);
7968                    r.dump(pw, "    ");
7969                }
7970                needSep = true;
7971            }
7972
7973            if (mProvidersByName.size() > 0) {
7974                pw.println(" ");
7975                pw.println("  Authority to provider mappings:");
7976                Iterator<Map.Entry<String, ContentProviderRecord>> it
7977                        = mProvidersByName.entrySet().iterator();
7978                while (it.hasNext()) {
7979                    Map.Entry<String, ContentProviderRecord> e = it.next();
7980                    ContentProviderRecord r = e.getValue();
7981                    pw.print("  "); pw.print(e.getKey()); pw.print(": ");
7982                            pw.println(r);
7983                }
7984                needSep = true;
7985            }
7986        }
7987
7988        if (mLaunchingProviders.size() > 0) {
7989            if (needSep) pw.println(" ");
7990            pw.println("  Launching content providers:");
7991            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
7992                pw.print("  Launching #"); pw.print(i); pw.print(": ");
7993                        pw.println(mLaunchingProviders.get(i));
7994            }
7995            needSep = true;
7996        }
7997
7998        if (mGrantedUriPermissions.size() > 0) {
7999            pw.println();
8000            pw.println("Granted Uri Permissions:");
8001            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8002                int uid = mGrantedUriPermissions.keyAt(i);
8003                HashMap<Uri, UriPermission> perms
8004                        = mGrantedUriPermissions.valueAt(i);
8005                pw.print("  * UID "); pw.print(uid);
8006                        pw.println(" holds:");
8007                for (UriPermission perm : perms.values()) {
8008                    pw.print("    "); pw.println(perm);
8009                    perm.dump(pw, "      ");
8010                }
8011            }
8012            needSep = true;
8013        }
8014
8015        return needSep;
8016    }
8017
8018    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8019            int opti, boolean dumpAll) {
8020        boolean needSep = false;
8021
8022        if (dumpAll) {
8023            if (this.mIntentSenderRecords.size() > 0) {
8024                Iterator<WeakReference<PendingIntentRecord>> it
8025                        = mIntentSenderRecords.values().iterator();
8026                while (it.hasNext()) {
8027                    WeakReference<PendingIntentRecord> ref = it.next();
8028                    PendingIntentRecord rec = ref != null ? ref.get(): null;
8029                    needSep = true;
8030                    if (rec != null) {
8031                        pw.print("  * "); pw.println(rec);
8032                        rec.dump(pw, "    ");
8033                    } else {
8034                        pw.print("  * "); pw.print(ref);
8035                    }
8036                }
8037            }
8038        }
8039
8040        return needSep;
8041    }
8042
8043    private static final void dumpHistoryList(PrintWriter pw, List list,
8044            String prefix, String label, boolean complete) {
8045        TaskRecord lastTask = null;
8046        for (int i=list.size()-1; i>=0; i--) {
8047            ActivityRecord r = (ActivityRecord)list.get(i);
8048            final boolean full = complete || !r.inHistory;
8049            if (lastTask != r.task) {
8050                lastTask = r.task;
8051                pw.print(prefix);
8052                pw.print(full ? "* " : "  ");
8053                pw.println(lastTask);
8054                if (full) {
8055                    lastTask.dump(pw, prefix + "  ");
8056                }
8057            }
8058            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
8059            pw.print(" #"); pw.print(i); pw.print(": ");
8060            pw.println(r);
8061            if (full) {
8062                r.dump(pw, prefix + "      ");
8063            }
8064        }
8065    }
8066
8067    private static String buildOomTag(String prefix, String space, int val, int base) {
8068        if (val == base) {
8069            if (space == null) return prefix;
8070            return prefix + "  ";
8071        }
8072        return prefix + "+" + Integer.toString(val-base);
8073    }
8074
8075    private static final int dumpProcessList(PrintWriter pw,
8076            ActivityManagerService service, List list,
8077            String prefix, String normalLabel, String persistentLabel) {
8078        int numPers = 0;
8079        final int N = list.size()-1;
8080        for (int i=N; i>=0; i--) {
8081            ProcessRecord r = (ProcessRecord)list.get(i);
8082            pw.println(String.format("%s%s #%2d: %s",
8083                    prefix, (r.persistent ? persistentLabel : normalLabel),
8084                    i, r.toString()));
8085            if (r.persistent) {
8086                numPers++;
8087            }
8088        }
8089        return numPers;
8090    }
8091
8092    private static final void dumpProcessOomList(PrintWriter pw,
8093            ActivityManagerService service, List<ProcessRecord> list,
8094            String prefix, String normalLabel, String persistentLabel,
8095            boolean inclDetails) {
8096
8097        final long curRealtime = SystemClock.elapsedRealtime();
8098        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8099        final long curUptime = SystemClock.uptimeMillis();
8100        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8101
8102        final int N = list.size()-1;
8103        for (int i=N; i>=0; i--) {
8104            ProcessRecord r = list.get(i);
8105            String oomAdj;
8106            if (r.setAdj >= EMPTY_APP_ADJ) {
8107                oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
8108            } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
8109                oomAdj = buildOomTag("bak", "  ", r.setAdj, HIDDEN_APP_MIN_ADJ);
8110            } else if (r.setAdj >= HOME_APP_ADJ) {
8111                oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
8112            } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
8113                oomAdj = buildOomTag("svc", "  ", r.setAdj, SECONDARY_SERVER_ADJ);
8114            } else if (r.setAdj >= BACKUP_APP_ADJ) {
8115                oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
8116            } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
8117                oomAdj = buildOomTag("hvy  ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
8118            } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
8119                oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
8120            } else if (r.setAdj >= VISIBLE_APP_ADJ) {
8121                oomAdj = buildOomTag("vis  ", null, r.setAdj, VISIBLE_APP_ADJ);
8122            } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
8123                oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
8124            } else if (r.setAdj >= CORE_SERVER_ADJ) {
8125                oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
8126            } else if (r.setAdj >= SYSTEM_ADJ) {
8127                oomAdj = buildOomTag("sys  ", null, r.setAdj, SYSTEM_ADJ);
8128            } else {
8129                oomAdj = Integer.toString(r.setAdj);
8130            }
8131            String schedGroup;
8132            switch (r.setSchedGroup) {
8133                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8134                    schedGroup = "B";
8135                    break;
8136                case Process.THREAD_GROUP_DEFAULT:
8137                    schedGroup = "F";
8138                    break;
8139                default:
8140                    schedGroup = Integer.toString(r.setSchedGroup);
8141                    break;
8142            }
8143            pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
8144                    prefix, (r.persistent ? persistentLabel : normalLabel),
8145                    N-i, oomAdj, schedGroup, r.toShortString(), r.adjType));
8146            if (r.adjSource != null || r.adjTarget != null) {
8147                pw.print(prefix);
8148                pw.print("          ");
8149                if (r.adjTarget instanceof ComponentName) {
8150                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8151                } else if (r.adjTarget != null) {
8152                    pw.print(r.adjTarget.toString());
8153                } else {
8154                    pw.print("{null}");
8155                }
8156                pw.print("<=");
8157                if (r.adjSource instanceof ProcessRecord) {
8158                    pw.print("Proc{");
8159                    pw.print(((ProcessRecord)r.adjSource).toShortString());
8160                    pw.println("}");
8161                } else if (r.adjSource != null) {
8162                    pw.println(r.adjSource.toString());
8163                } else {
8164                    pw.println("{null}");
8165                }
8166            }
8167            if (inclDetails) {
8168                pw.print(prefix);
8169                pw.print("    ");
8170                pw.print("oom: max="); pw.print(r.maxAdj);
8171                pw.print(" hidden="); pw.print(r.hiddenAdj);
8172                pw.print(" curRaw="); pw.print(r.curRawAdj);
8173                pw.print(" setRaw="); pw.print(r.setRawAdj);
8174                pw.print(" cur="); pw.print(r.curAdj);
8175                pw.print(" set="); pw.println(r.setAdj);
8176                pw.print(prefix);
8177                pw.print("    ");
8178                pw.print("keeping="); pw.print(r.keeping);
8179                pw.print(" hidden="); pw.print(r.hidden);
8180                pw.print(" empty="); pw.println(r.empty);
8181
8182                if (!r.keeping) {
8183                    if (r.lastWakeTime != 0) {
8184                        long wtime;
8185                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8186                        synchronized (stats) {
8187                            wtime = stats.getProcessWakeTime(r.info.uid,
8188                                    r.pid, curRealtime);
8189                        }
8190                        long timeUsed = wtime - r.lastWakeTime;
8191                        pw.print(prefix);
8192                        pw.print("    ");
8193                        pw.print("keep awake over ");
8194                        TimeUtils.formatDuration(realtimeSince, pw);
8195                        pw.print(" used ");
8196                        TimeUtils.formatDuration(timeUsed, pw);
8197                        pw.print(" (");
8198                        pw.print((timeUsed*100)/realtimeSince);
8199                        pw.println("%)");
8200                    }
8201                    if (r.lastCpuTime != 0) {
8202                        long timeUsed = r.curCpuTime - r.lastCpuTime;
8203                        pw.print(prefix);
8204                        pw.print("    ");
8205                        pw.print("run cpu over ");
8206                        TimeUtils.formatDuration(uptimeSince, pw);
8207                        pw.print(" used ");
8208                        TimeUtils.formatDuration(timeUsed, pw);
8209                        pw.print(" (");
8210                        pw.print((timeUsed*100)/uptimeSince);
8211                        pw.println("%)");
8212                    }
8213                }
8214            }
8215        }
8216    }
8217
8218    static final void dumpApplicationMemoryUsage(FileDescriptor fd,
8219            PrintWriter pw, List list, String prefix, String[] args) {
8220        final boolean isCheckinRequest = scanArgs(args, "--checkin");
8221        long uptime = SystemClock.uptimeMillis();
8222        long realtime = SystemClock.elapsedRealtime();
8223
8224        if (isCheckinRequest) {
8225            // short checkin version
8226            pw.println(uptime + "," + realtime);
8227            pw.flush();
8228        } else {
8229            pw.println("Applications Memory Usage (kB):");
8230            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8231        }
8232        for (int i = list.size() - 1 ; i >= 0 ; i--) {
8233            ProcessRecord r = (ProcessRecord)list.get(i);
8234            if (r.thread != null) {
8235                if (!isCheckinRequest) {
8236                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
8237                    pw.flush();
8238                }
8239                try {
8240                    r.thread.asBinder().dump(fd, args);
8241                } catch (RemoteException e) {
8242                    if (!isCheckinRequest) {
8243                        pw.println("Got RemoteException!");
8244                        pw.flush();
8245                    }
8246                }
8247            }
8248        }
8249    }
8250
8251    /**
8252     * Searches array of arguments for the specified string
8253     * @param args array of argument strings
8254     * @param value value to search for
8255     * @return true if the value is contained in the array
8256     */
8257    private static boolean scanArgs(String[] args, String value) {
8258        if (args != null) {
8259            for (String arg : args) {
8260                if (value.equals(arg)) {
8261                    return true;
8262                }
8263            }
8264        }
8265        return false;
8266    }
8267
8268    private final void killServicesLocked(ProcessRecord app,
8269            boolean allowRestart) {
8270        // Report disconnected services.
8271        if (false) {
8272            // XXX we are letting the client link to the service for
8273            // death notifications.
8274            if (app.services.size() > 0) {
8275                Iterator<ServiceRecord> it = app.services.iterator();
8276                while (it.hasNext()) {
8277                    ServiceRecord r = it.next();
8278                    if (r.connections.size() > 0) {
8279                        Iterator<ArrayList<ConnectionRecord>> jt
8280                                = r.connections.values().iterator();
8281                        while (jt.hasNext()) {
8282                            ArrayList<ConnectionRecord> cl = jt.next();
8283                            for (int i=0; i<cl.size(); i++) {
8284                                ConnectionRecord c = cl.get(i);
8285                                if (c.binding.client != app) {
8286                                    try {
8287                                        //c.conn.connected(r.className, null);
8288                                    } catch (Exception e) {
8289                                        // todo: this should be asynchronous!
8290                                        Slog.w(TAG, "Exception thrown disconnected servce "
8291                                              + r.shortName
8292                                              + " from app " + app.processName, e);
8293                                    }
8294                                }
8295                            }
8296                        }
8297                    }
8298                }
8299            }
8300        }
8301
8302        // Clean up any connections this application has to other services.
8303        if (app.connections.size() > 0) {
8304            Iterator<ConnectionRecord> it = app.connections.iterator();
8305            while (it.hasNext()) {
8306                ConnectionRecord r = it.next();
8307                removeConnectionLocked(r, app, null);
8308            }
8309        }
8310        app.connections.clear();
8311
8312        if (app.services.size() != 0) {
8313            // Any services running in the application need to be placed
8314            // back in the pending list.
8315            Iterator<ServiceRecord> it = app.services.iterator();
8316            while (it.hasNext()) {
8317                ServiceRecord sr = it.next();
8318                synchronized (sr.stats.getBatteryStats()) {
8319                    sr.stats.stopLaunchedLocked();
8320                }
8321                sr.app = null;
8322                sr.executeNesting = 0;
8323                if (mStoppingServices.remove(sr)) {
8324                    if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
8325                }
8326
8327                boolean hasClients = sr.bindings.size() > 0;
8328                if (hasClients) {
8329                    Iterator<IntentBindRecord> bindings
8330                            = sr.bindings.values().iterator();
8331                    while (bindings.hasNext()) {
8332                        IntentBindRecord b = bindings.next();
8333                        if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
8334                                + ": shouldUnbind=" + b.hasBound);
8335                        b.binder = null;
8336                        b.requested = b.received = b.hasBound = false;
8337                    }
8338                }
8339
8340                if (sr.crashCount >= 2) {
8341                    Slog.w(TAG, "Service crashed " + sr.crashCount
8342                            + " times, stopping: " + sr);
8343                    EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
8344                            sr.crashCount, sr.shortName, app.pid);
8345                    bringDownServiceLocked(sr, true);
8346                } else if (!allowRestart) {
8347                    bringDownServiceLocked(sr, true);
8348                } else {
8349                    boolean canceled = scheduleServiceRestartLocked(sr, true);
8350
8351                    // Should the service remain running?  Note that in the
8352                    // extreme case of so many attempts to deliver a command
8353                    // that it failed, that we also will stop it here.
8354                    if (sr.startRequested && (sr.stopIfKilled || canceled)) {
8355                        if (sr.pendingStarts.size() == 0) {
8356                            sr.startRequested = false;
8357                            if (!hasClients) {
8358                                // Whoops, no reason to restart!
8359                                bringDownServiceLocked(sr, true);
8360                            }
8361                        }
8362                    }
8363                }
8364            }
8365
8366            if (!allowRestart) {
8367                app.services.clear();
8368            }
8369        }
8370
8371        // Make sure we have no more records on the stopping list.
8372        int i = mStoppingServices.size();
8373        while (i > 0) {
8374            i--;
8375            ServiceRecord sr = mStoppingServices.get(i);
8376            if (sr.app == app) {
8377                mStoppingServices.remove(i);
8378                if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
8379            }
8380        }
8381
8382        app.executingServices.clear();
8383    }
8384
8385    private final void removeDyingProviderLocked(ProcessRecord proc,
8386            ContentProviderRecord cpr) {
8387        synchronized (cpr) {
8388            cpr.launchingApp = null;
8389            cpr.notifyAll();
8390        }
8391
8392        mProvidersByClass.remove(cpr.info.name);
8393        String names[] = cpr.info.authority.split(";");
8394        for (int j = 0; j < names.length; j++) {
8395            mProvidersByName.remove(names[j]);
8396        }
8397
8398        Iterator<ProcessRecord> cit = cpr.clients.iterator();
8399        while (cit.hasNext()) {
8400            ProcessRecord capp = cit.next();
8401            if (!capp.persistent && capp.thread != null
8402                    && capp.pid != 0
8403                    && capp.pid != MY_PID) {
8404                Slog.i(TAG, "Kill " + capp.processName
8405                        + " (pid " + capp.pid + "): provider " + cpr.info.name
8406                        + " in dying process " + proc.processName);
8407                EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
8408                        capp.processName, capp.setAdj, "dying provider " + proc.processName);
8409                Process.killProcess(capp.pid);
8410            }
8411        }
8412
8413        mLaunchingProviders.remove(cpr);
8414    }
8415
8416    /**
8417     * Main code for cleaning up a process when it has gone away.  This is
8418     * called both as a result of the process dying, or directly when stopping
8419     * a process when running in single process mode.
8420     */
8421    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
8422            boolean restarting, int index) {
8423        if (index >= 0) {
8424            mLruProcesses.remove(index);
8425        }
8426
8427        mProcessesToGc.remove(app);
8428
8429        // Dismiss any open dialogs.
8430        if (app.crashDialog != null) {
8431            app.crashDialog.dismiss();
8432            app.crashDialog = null;
8433        }
8434        if (app.anrDialog != null) {
8435            app.anrDialog.dismiss();
8436            app.anrDialog = null;
8437        }
8438        if (app.waitDialog != null) {
8439            app.waitDialog.dismiss();
8440            app.waitDialog = null;
8441        }
8442
8443        app.crashing = false;
8444        app.notResponding = false;
8445
8446        app.resetPackageList();
8447        app.thread = null;
8448        app.forcingToForeground = null;
8449        app.foregroundServices = false;
8450
8451        killServicesLocked(app, true);
8452
8453        boolean restart = false;
8454
8455        int NL = mLaunchingProviders.size();
8456
8457        // Remove published content providers.
8458        if (!app.pubProviders.isEmpty()) {
8459            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
8460            while (it.hasNext()) {
8461                ContentProviderRecord cpr = it.next();
8462                cpr.provider = null;
8463                cpr.app = null;
8464
8465                // See if someone is waiting for this provider...  in which
8466                // case we don't remove it, but just let it restart.
8467                int i = 0;
8468                if (!app.bad) {
8469                    for (; i<NL; i++) {
8470                        if (mLaunchingProviders.get(i) == cpr) {
8471                            restart = true;
8472                            break;
8473                        }
8474                    }
8475                } else {
8476                    i = NL;
8477                }
8478
8479                if (i >= NL) {
8480                    removeDyingProviderLocked(app, cpr);
8481                    NL = mLaunchingProviders.size();
8482                }
8483            }
8484            app.pubProviders.clear();
8485        }
8486
8487        // Take care of any launching providers waiting for this process.
8488        if (checkAppInLaunchingProvidersLocked(app, false)) {
8489            restart = true;
8490        }
8491
8492        // Unregister from connected content providers.
8493        if (!app.conProviders.isEmpty()) {
8494            Iterator it = app.conProviders.keySet().iterator();
8495            while (it.hasNext()) {
8496                ContentProviderRecord cpr = (ContentProviderRecord)it.next();
8497                cpr.clients.remove(app);
8498            }
8499            app.conProviders.clear();
8500        }
8501
8502        // At this point there may be remaining entries in mLaunchingProviders
8503        // where we were the only one waiting, so they are no longer of use.
8504        // Look for these and clean up if found.
8505        // XXX Commented out for now.  Trying to figure out a way to reproduce
8506        // the actual situation to identify what is actually going on.
8507        if (false) {
8508            for (int i=0; i<NL; i++) {
8509                ContentProviderRecord cpr = (ContentProviderRecord)
8510                        mLaunchingProviders.get(i);
8511                if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
8512                    synchronized (cpr) {
8513                        cpr.launchingApp = null;
8514                        cpr.notifyAll();
8515                    }
8516                }
8517            }
8518        }
8519
8520        skipCurrentReceiverLocked(app);
8521
8522        // Unregister any receivers.
8523        if (app.receivers.size() > 0) {
8524            Iterator<ReceiverList> it = app.receivers.iterator();
8525            while (it.hasNext()) {
8526                removeReceiverLocked(it.next());
8527            }
8528            app.receivers.clear();
8529        }
8530
8531        // If the app is undergoing backup, tell the backup manager about it
8532        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
8533            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
8534            try {
8535                IBackupManager bm = IBackupManager.Stub.asInterface(
8536                        ServiceManager.getService(Context.BACKUP_SERVICE));
8537                bm.agentDisconnected(app.info.packageName);
8538            } catch (RemoteException e) {
8539                // can't happen; backup manager is local
8540            }
8541        }
8542
8543        // If the caller is restarting this app, then leave it in its
8544        // current lists and let the caller take care of it.
8545        if (restarting) {
8546            return;
8547        }
8548
8549        if (!app.persistent) {
8550            if (DEBUG_PROCESSES) Slog.v(TAG,
8551                    "Removing non-persistent process during cleanup: " + app);
8552            mProcessNames.remove(app.processName, app.info.uid);
8553            if (mHeavyWeightProcess == app) {
8554                mHeavyWeightProcess = null;
8555                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
8556            }
8557        } else if (!app.removed) {
8558            // This app is persistent, so we need to keep its record around.
8559            // If it is not already on the pending app list, add it there
8560            // and start a new process for it.
8561            app.thread = null;
8562            app.forcingToForeground = null;
8563            app.foregroundServices = false;
8564            if (mPersistentStartingProcesses.indexOf(app) < 0) {
8565                mPersistentStartingProcesses.add(app);
8566                restart = true;
8567            }
8568        }
8569        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
8570                "Clean-up removing on hold: " + app);
8571        mProcessesOnHold.remove(app);
8572
8573        if (app == mHomeProcess) {
8574            mHomeProcess = null;
8575        }
8576
8577        if (restart) {
8578            // We have components that still need to be running in the
8579            // process, so re-launch it.
8580            mProcessNames.put(app.processName, app.info.uid, app);
8581            startProcessLocked(app, "restart", app.processName);
8582        } else if (app.pid > 0 && app.pid != MY_PID) {
8583            // Goodbye!
8584            synchronized (mPidsSelfLocked) {
8585                mPidsSelfLocked.remove(app.pid);
8586                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
8587            }
8588            app.setPid(0);
8589        }
8590    }
8591
8592    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
8593        // Look through the content providers we are waiting to have launched,
8594        // and if any run in this process then either schedule a restart of
8595        // the process or kill the client waiting for it if this process has
8596        // gone bad.
8597        int NL = mLaunchingProviders.size();
8598        boolean restart = false;
8599        for (int i=0; i<NL; i++) {
8600            ContentProviderRecord cpr = mLaunchingProviders.get(i);
8601            if (cpr.launchingApp == app) {
8602                if (!alwaysBad && !app.bad) {
8603                    restart = true;
8604                } else {
8605                    removeDyingProviderLocked(app, cpr);
8606                    NL = mLaunchingProviders.size();
8607                }
8608            }
8609        }
8610        return restart;
8611    }
8612
8613    // =========================================================
8614    // SERVICES
8615    // =========================================================
8616
8617    ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
8618        ActivityManager.RunningServiceInfo info =
8619            new ActivityManager.RunningServiceInfo();
8620        info.service = r.name;
8621        if (r.app != null) {
8622            info.pid = r.app.pid;
8623        }
8624        info.uid = r.appInfo.uid;
8625        info.process = r.processName;
8626        info.foreground = r.isForeground;
8627        info.activeSince = r.createTime;
8628        info.started = r.startRequested;
8629        info.clientCount = r.connections.size();
8630        info.crashCount = r.crashCount;
8631        info.lastActivityTime = r.lastActivity;
8632        if (r.isForeground) {
8633            info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
8634        }
8635        if (r.startRequested) {
8636            info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
8637        }
8638        if (r.app != null && r.app.pid == MY_PID) {
8639            info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
8640        }
8641        if (r.app != null && r.app.persistent) {
8642            info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
8643        }
8644
8645        for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
8646            for (int i=0; i<connl.size(); i++) {
8647                ConnectionRecord conn = connl.get(i);
8648                if (conn.clientLabel != 0) {
8649                    info.clientPackage = conn.binding.client.info.packageName;
8650                    info.clientLabel = conn.clientLabel;
8651                    return info;
8652                }
8653            }
8654        }
8655        return info;
8656    }
8657
8658    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
8659            int flags) {
8660        synchronized (this) {
8661            ArrayList<ActivityManager.RunningServiceInfo> res
8662                    = new ArrayList<ActivityManager.RunningServiceInfo>();
8663
8664            if (mServices.size() > 0) {
8665                Iterator<ServiceRecord> it = mServices.values().iterator();
8666                while (it.hasNext() && res.size() < maxNum) {
8667                    res.add(makeRunningServiceInfoLocked(it.next()));
8668                }
8669            }
8670
8671            for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
8672                ServiceRecord r = mRestartingServices.get(i);
8673                ActivityManager.RunningServiceInfo info =
8674                        makeRunningServiceInfoLocked(r);
8675                info.restarting = r.nextRestartTime;
8676                res.add(info);
8677            }
8678
8679            return res;
8680        }
8681    }
8682
8683    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
8684        synchronized (this) {
8685            ServiceRecord r = mServices.get(name);
8686            if (r != null) {
8687                for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
8688                    for (int i=0; i<conn.size(); i++) {
8689                        if (conn.get(i).clientIntent != null) {
8690                            return conn.get(i).clientIntent;
8691                        }
8692                    }
8693                }
8694            }
8695        }
8696        return null;
8697    }
8698
8699    private final ServiceRecord findServiceLocked(ComponentName name,
8700            IBinder token) {
8701        ServiceRecord r = mServices.get(name);
8702        return r == token ? r : null;
8703    }
8704
8705    private final class ServiceLookupResult {
8706        final ServiceRecord record;
8707        final String permission;
8708
8709        ServiceLookupResult(ServiceRecord _record, String _permission) {
8710            record = _record;
8711            permission = _permission;
8712        }
8713    };
8714
8715    private ServiceLookupResult findServiceLocked(Intent service,
8716            String resolvedType) {
8717        ServiceRecord r = null;
8718        if (service.getComponent() != null) {
8719            r = mServices.get(service.getComponent());
8720        }
8721        if (r == null) {
8722            Intent.FilterComparison filter = new Intent.FilterComparison(service);
8723            r = mServicesByIntent.get(filter);
8724        }
8725
8726        if (r == null) {
8727            try {
8728                ResolveInfo rInfo =
8729                    AppGlobals.getPackageManager().resolveService(
8730                            service, resolvedType, 0);
8731                ServiceInfo sInfo =
8732                    rInfo != null ? rInfo.serviceInfo : null;
8733                if (sInfo == null) {
8734                    return null;
8735                }
8736
8737                ComponentName name = new ComponentName(
8738                        sInfo.applicationInfo.packageName, sInfo.name);
8739                r = mServices.get(name);
8740            } catch (RemoteException ex) {
8741                // pm is in same process, this will never happen.
8742            }
8743        }
8744        if (r != null) {
8745            int callingPid = Binder.getCallingPid();
8746            int callingUid = Binder.getCallingUid();
8747            if (checkComponentPermission(r.permission,
8748                    callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
8749                    != PackageManager.PERMISSION_GRANTED) {
8750                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
8751                        + " from pid=" + callingPid
8752                        + ", uid=" + callingUid
8753                        + " requires " + r.permission);
8754                return new ServiceLookupResult(null, r.permission);
8755            }
8756            return new ServiceLookupResult(r, null);
8757        }
8758        return null;
8759    }
8760
8761    private class ServiceRestarter implements Runnable {
8762        private ServiceRecord mService;
8763
8764        void setService(ServiceRecord service) {
8765            mService = service;
8766        }
8767
8768        public void run() {
8769            synchronized(ActivityManagerService.this) {
8770                performServiceRestartLocked(mService);
8771            }
8772        }
8773    }
8774
8775    private ServiceLookupResult retrieveServiceLocked(Intent service,
8776            String resolvedType, int callingPid, int callingUid) {
8777        ServiceRecord r = null;
8778        if (service.getComponent() != null) {
8779            r = mServices.get(service.getComponent());
8780        }
8781        Intent.FilterComparison filter = new Intent.FilterComparison(service);
8782        r = mServicesByIntent.get(filter);
8783        if (r == null) {
8784            try {
8785                ResolveInfo rInfo =
8786                    AppGlobals.getPackageManager().resolveService(
8787                            service, resolvedType, STOCK_PM_FLAGS);
8788                ServiceInfo sInfo =
8789                    rInfo != null ? rInfo.serviceInfo : null;
8790                if (sInfo == null) {
8791                    Slog.w(TAG, "Unable to start service " + service +
8792                          ": not found");
8793                    return null;
8794                }
8795
8796                ComponentName name = new ComponentName(
8797                        sInfo.applicationInfo.packageName, sInfo.name);
8798                r = mServices.get(name);
8799                if (r == null) {
8800                    filter = new Intent.FilterComparison(service.cloneFilter());
8801                    ServiceRestarter res = new ServiceRestarter();
8802                    BatteryStatsImpl.Uid.Pkg.Serv ss = null;
8803                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8804                    synchronized (stats) {
8805                        ss = stats.getServiceStatsLocked(
8806                                sInfo.applicationInfo.uid, sInfo.packageName,
8807                                sInfo.name);
8808                    }
8809                    r = new ServiceRecord(this, ss, name, filter, sInfo, res);
8810                    res.setService(r);
8811                    mServices.put(name, r);
8812                    mServicesByIntent.put(filter, r);
8813
8814                    // Make sure this component isn't in the pending list.
8815                    int N = mPendingServices.size();
8816                    for (int i=0; i<N; i++) {
8817                        ServiceRecord pr = mPendingServices.get(i);
8818                        if (pr.name.equals(name)) {
8819                            mPendingServices.remove(i);
8820                            i--;
8821                            N--;
8822                        }
8823                    }
8824                }
8825            } catch (RemoteException ex) {
8826                // pm is in same process, this will never happen.
8827            }
8828        }
8829        if (r != null) {
8830            if (checkComponentPermission(r.permission,
8831                    callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
8832                    != PackageManager.PERMISSION_GRANTED) {
8833                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
8834                        + " from pid=" + Binder.getCallingPid()
8835                        + ", uid=" + Binder.getCallingUid()
8836                        + " requires " + r.permission);
8837                return new ServiceLookupResult(null, r.permission);
8838            }
8839            return new ServiceLookupResult(r, null);
8840        }
8841        return null;
8842    }
8843
8844    private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
8845        if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
8846                + why + " of " + r + " in app " + r.app);
8847        else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
8848                + why + " of " + r.shortName);
8849        long now = SystemClock.uptimeMillis();
8850        if (r.executeNesting == 0 && r.app != null) {
8851            if (r.app.executingServices.size() == 0) {
8852                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
8853                msg.obj = r.app;
8854                mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
8855            }
8856            r.app.executingServices.add(r);
8857        }
8858        r.executeNesting++;
8859        r.executingStart = now;
8860    }
8861
8862    private final void sendServiceArgsLocked(ServiceRecord r,
8863            boolean oomAdjusted) {
8864        final int N = r.pendingStarts.size();
8865        if (N == 0) {
8866            return;
8867        }
8868
8869        while (r.pendingStarts.size() > 0) {
8870            try {
8871                ServiceRecord.StartItem si = r.pendingStarts.remove(0);
8872                if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
8873                        + r + " " + r.intent + " args=" + si.intent);
8874                if (si.intent == null) {
8875                    // If somehow we got a dummy start at the front, then
8876                    // just drop it here.
8877                    continue;
8878                }
8879                si.deliveredTime = SystemClock.uptimeMillis();
8880                r.deliveredStarts.add(si);
8881                si.deliveryCount++;
8882                if (si.targetPermissionUid >= 0) {
8883                    grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
8884                            r.packageName, si.intent, si.getUriPermissionsLocked());
8885                }
8886                bumpServiceExecutingLocked(r, "start");
8887                if (!oomAdjusted) {
8888                    oomAdjusted = true;
8889                    updateOomAdjLocked(r.app);
8890                }
8891                int flags = 0;
8892                if (si.deliveryCount > 0) {
8893                    flags |= Service.START_FLAG_RETRY;
8894                }
8895                if (si.doneExecutingCount > 0) {
8896                    flags |= Service.START_FLAG_REDELIVERY;
8897                }
8898                r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent);
8899            } catch (RemoteException e) {
8900                // Remote process gone...  we'll let the normal cleanup take
8901                // care of this.
8902                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
8903                break;
8904            } catch (Exception e) {
8905                Slog.w(TAG, "Unexpected exception", e);
8906                break;
8907            }
8908        }
8909    }
8910
8911    private final boolean requestServiceBindingLocked(ServiceRecord r,
8912            IntentBindRecord i, boolean rebind) {
8913        if (r.app == null || r.app.thread == null) {
8914            // If service is not currently running, can't yet bind.
8915            return false;
8916        }
8917        if ((!i.requested || rebind) && i.apps.size() > 0) {
8918            try {
8919                bumpServiceExecutingLocked(r, "bind");
8920                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
8921                if (!rebind) {
8922                    i.requested = true;
8923                }
8924                i.hasBound = true;
8925                i.doRebind = false;
8926            } catch (RemoteException e) {
8927                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
8928                return false;
8929            }
8930        }
8931        return true;
8932    }
8933
8934    private final void requestServiceBindingsLocked(ServiceRecord r) {
8935        Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
8936        while (bindings.hasNext()) {
8937            IntentBindRecord i = bindings.next();
8938            if (!requestServiceBindingLocked(r, i, false)) {
8939                break;
8940            }
8941        }
8942    }
8943
8944    private final void realStartServiceLocked(ServiceRecord r,
8945            ProcessRecord app) throws RemoteException {
8946        if (app.thread == null) {
8947            throw new RemoteException();
8948        }
8949
8950        r.app = app;
8951        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
8952
8953        app.services.add(r);
8954        bumpServiceExecutingLocked(r, "create");
8955        updateLruProcessLocked(app, true, true);
8956
8957        boolean created = false;
8958        try {
8959            mStringBuilder.setLength(0);
8960            r.intent.getIntent().toShortString(mStringBuilder, false, true);
8961            EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
8962                    System.identityHashCode(r), r.shortName,
8963                    mStringBuilder.toString(), r.app.pid);
8964            synchronized (r.stats.getBatteryStats()) {
8965                r.stats.startLaunchedLocked();
8966            }
8967            ensurePackageDexOpt(r.serviceInfo.packageName);
8968            app.thread.scheduleCreateService(r, r.serviceInfo);
8969            r.postNotification();
8970            created = true;
8971        } finally {
8972            if (!created) {
8973                app.services.remove(r);
8974                scheduleServiceRestartLocked(r, false);
8975            }
8976        }
8977
8978        requestServiceBindingsLocked(r);
8979
8980        // If the service is in the started state, and there are no
8981        // pending arguments, then fake up one so its onStartCommand() will
8982        // be called.
8983        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
8984            r.lastStartId++;
8985            if (r.lastStartId < 1) {
8986                r.lastStartId = 1;
8987            }
8988            r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId, null, -1));
8989        }
8990
8991        sendServiceArgsLocked(r, true);
8992    }
8993
8994    private final boolean scheduleServiceRestartLocked(ServiceRecord r,
8995            boolean allowCancel) {
8996        boolean canceled = false;
8997
8998        final long now = SystemClock.uptimeMillis();
8999        long minDuration = SERVICE_RESTART_DURATION;
9000        long resetTime = SERVICE_RESET_RUN_DURATION;
9001
9002        // Any delivered but not yet finished starts should be put back
9003        // on the pending list.
9004        final int N = r.deliveredStarts.size();
9005        if (N > 0) {
9006            for (int i=N-1; i>=0; i--) {
9007                ServiceRecord.StartItem si = r.deliveredStarts.get(i);
9008                si.removeUriPermissionsLocked();
9009                if (si.intent == null) {
9010                    // We'll generate this again if needed.
9011                } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
9012                        && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
9013                    r.pendingStarts.add(0, si);
9014                    long dur = SystemClock.uptimeMillis() - si.deliveredTime;
9015                    dur *= 2;
9016                    if (minDuration < dur) minDuration = dur;
9017                    if (resetTime < dur) resetTime = dur;
9018                } else {
9019                    Slog.w(TAG, "Canceling start item " + si.intent + " in service "
9020                            + r.name);
9021                    canceled = true;
9022                }
9023            }
9024            r.deliveredStarts.clear();
9025        }
9026
9027        r.totalRestartCount++;
9028        if (r.restartDelay == 0) {
9029            r.restartCount++;
9030            r.restartDelay = minDuration;
9031        } else {
9032            // If it has been a "reasonably long time" since the service
9033            // was started, then reset our restart duration back to
9034            // the beginning, so we don't infinitely increase the duration
9035            // on a service that just occasionally gets killed (which is
9036            // a normal case, due to process being killed to reclaim memory).
9037            if (now > (r.restartTime+resetTime)) {
9038                r.restartCount = 1;
9039                r.restartDelay = minDuration;
9040            } else {
9041                r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
9042                if (r.restartDelay < minDuration) {
9043                    r.restartDelay = minDuration;
9044                }
9045            }
9046        }
9047
9048        r.nextRestartTime = now + r.restartDelay;
9049
9050        // Make sure that we don't end up restarting a bunch of services
9051        // all at the same time.
9052        boolean repeat;
9053        do {
9054            repeat = false;
9055            for (int i=mRestartingServices.size()-1; i>=0; i--) {
9056                ServiceRecord r2 = mRestartingServices.get(i);
9057                if (r2 != r && r.nextRestartTime
9058                        >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
9059                        && r.nextRestartTime
9060                        < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
9061                    r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
9062                    r.restartDelay = r.nextRestartTime - now;
9063                    repeat = true;
9064                    break;
9065                }
9066            }
9067        } while (repeat);
9068
9069        if (!mRestartingServices.contains(r)) {
9070            mRestartingServices.add(r);
9071        }
9072
9073        r.cancelNotification();
9074
9075        mHandler.removeCallbacks(r.restarter);
9076        mHandler.postAtTime(r.restarter, r.nextRestartTime);
9077        r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
9078        Slog.w(TAG, "Scheduling restart of crashed service "
9079                + r.shortName + " in " + r.restartDelay + "ms");
9080        EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
9081                r.shortName, r.restartDelay);
9082
9083        return canceled;
9084    }
9085
9086    final void performServiceRestartLocked(ServiceRecord r) {
9087        if (!mRestartingServices.contains(r)) {
9088            return;
9089        }
9090        bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9091    }
9092
9093    private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9094        if (r.restartDelay == 0) {
9095            return false;
9096        }
9097        r.resetRestartCounter();
9098        mRestartingServices.remove(r);
9099        mHandler.removeCallbacks(r.restarter);
9100        return true;
9101    }
9102
9103    private final boolean bringUpServiceLocked(ServiceRecord r,
9104            int intentFlags, boolean whileRestarting) {
9105        //Slog.i(TAG, "Bring up service:");
9106        //r.dump("  ");
9107
9108        if (r.app != null && r.app.thread != null) {
9109            sendServiceArgsLocked(r, false);
9110            return true;
9111        }
9112
9113        if (!whileRestarting && r.restartDelay > 0) {
9114            // If waiting for a restart, then do nothing.
9115            return true;
9116        }
9117
9118        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
9119
9120        // We are now bringing the service up, so no longer in the
9121        // restarting state.
9122        mRestartingServices.remove(r);
9123
9124        final String appName = r.processName;
9125        ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
9126        if (app != null && app.thread != null) {
9127            try {
9128                realStartServiceLocked(r, app);
9129                return true;
9130            } catch (RemoteException e) {
9131                Slog.w(TAG, "Exception when starting service " + r.shortName, e);
9132            }
9133
9134            // If a dead object exception was thrown -- fall through to
9135            // restart the application.
9136        }
9137
9138        // Not running -- get it started, and enqueue this service record
9139        // to be executed when the app comes up.
9140        if (startProcessLocked(appName, r.appInfo, true, intentFlags,
9141                "service", r.name, false) == null) {
9142            Slog.w(TAG, "Unable to launch app "
9143                    + r.appInfo.packageName + "/"
9144                    + r.appInfo.uid + " for service "
9145                    + r.intent.getIntent() + ": process is bad");
9146            bringDownServiceLocked(r, true);
9147            return false;
9148        }
9149
9150        if (!mPendingServices.contains(r)) {
9151            mPendingServices.add(r);
9152        }
9153
9154        return true;
9155    }
9156
9157    private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
9158        //Slog.i(TAG, "Bring down service:");
9159        //r.dump("  ");
9160
9161        // Does it still need to run?
9162        if (!force && r.startRequested) {
9163            return;
9164        }
9165        if (r.connections.size() > 0) {
9166            if (!force) {
9167                // XXX should probably keep a count of the number of auto-create
9168                // connections directly in the service.
9169                Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
9170                while (it.hasNext()) {
9171                    ArrayList<ConnectionRecord> cr = it.next();
9172                    for (int i=0; i<cr.size(); i++) {
9173                        if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
9174                            return;
9175                        }
9176                    }
9177                }
9178            }
9179
9180            // Report to all of the connections that the service is no longer
9181            // available.
9182            Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
9183            while (it.hasNext()) {
9184                ArrayList<ConnectionRecord> c = it.next();
9185                for (int i=0; i<c.size(); i++) {
9186                    try {
9187                        c.get(i).conn.connected(r.name, null);
9188                    } catch (Exception e) {
9189                        Slog.w(TAG, "Failure disconnecting service " + r.name +
9190                              " to connection " + c.get(i).conn.asBinder() +
9191                              " (in " + c.get(i).binding.client.processName + ")", e);
9192                    }
9193                }
9194            }
9195        }
9196
9197        // Tell the service that it has been unbound.
9198        if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
9199            Iterator<IntentBindRecord> it = r.bindings.values().iterator();
9200            while (it.hasNext()) {
9201                IntentBindRecord ibr = it.next();
9202                if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
9203                        + ": hasBound=" + ibr.hasBound);
9204                if (r.app != null && r.app.thread != null && ibr.hasBound) {
9205                    try {
9206                        bumpServiceExecutingLocked(r, "bring down unbind");
9207                        updateOomAdjLocked(r.app);
9208                        ibr.hasBound = false;
9209                        r.app.thread.scheduleUnbindService(r,
9210                                ibr.intent.getIntent());
9211                    } catch (Exception e) {
9212                        Slog.w(TAG, "Exception when unbinding service "
9213                                + r.shortName, e);
9214                        serviceDoneExecutingLocked(r, true);
9215                    }
9216                }
9217            }
9218        }
9219
9220        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
9221        EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
9222                System.identityHashCode(r), r.shortName,
9223                (r.app != null) ? r.app.pid : -1);
9224
9225        mServices.remove(r.name);
9226        mServicesByIntent.remove(r.intent);
9227        r.totalRestartCount = 0;
9228        unscheduleServiceRestartLocked(r);
9229
9230        // Also make sure it is not on the pending list.
9231        int N = mPendingServices.size();
9232        for (int i=0; i<N; i++) {
9233            if (mPendingServices.get(i) == r) {
9234                mPendingServices.remove(i);
9235                if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
9236                i--;
9237                N--;
9238            }
9239        }
9240
9241        r.cancelNotification();
9242        r.isForeground = false;
9243        r.foregroundId = 0;
9244        r.foregroundNoti = null;
9245
9246        // Clear start entries.
9247        r.clearDeliveredStartsLocked();
9248        r.pendingStarts.clear();
9249
9250        if (r.app != null) {
9251            synchronized (r.stats.getBatteryStats()) {
9252                r.stats.stopLaunchedLocked();
9253            }
9254            r.app.services.remove(r);
9255            if (r.app.thread != null) {
9256                try {
9257                    bumpServiceExecutingLocked(r, "stop");
9258                    mStoppingServices.add(r);
9259                    updateOomAdjLocked(r.app);
9260                    r.app.thread.scheduleStopService(r);
9261                } catch (Exception e) {
9262                    Slog.w(TAG, "Exception when stopping service "
9263                            + r.shortName, e);
9264                    serviceDoneExecutingLocked(r, true);
9265                }
9266                updateServiceForegroundLocked(r.app, false);
9267            } else {
9268                if (DEBUG_SERVICE) Slog.v(
9269                    TAG, "Removed service that has no process: " + r);
9270            }
9271        } else {
9272            if (DEBUG_SERVICE) Slog.v(
9273                TAG, "Removed service that is not running: " + r);
9274        }
9275    }
9276
9277    ComponentName startServiceLocked(IApplicationThread caller,
9278            Intent service, String resolvedType,
9279            int callingPid, int callingUid) {
9280        synchronized(this) {
9281            if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
9282                    + " type=" + resolvedType + " args=" + service.getExtras());
9283
9284            if (caller != null) {
9285                final ProcessRecord callerApp = getRecordForAppLocked(caller);
9286                if (callerApp == null) {
9287                    throw new SecurityException(
9288                            "Unable to find app for caller " + caller
9289                            + " (pid=" + Binder.getCallingPid()
9290                            + ") when starting service " + service);
9291                }
9292            }
9293
9294            ServiceLookupResult res =
9295                retrieveServiceLocked(service, resolvedType,
9296                        callingPid, callingUid);
9297            if (res == null) {
9298                return null;
9299            }
9300            if (res.record == null) {
9301                return new ComponentName("!", res.permission != null
9302                        ? res.permission : "private to package");
9303            }
9304            ServiceRecord r = res.record;
9305            int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
9306                    callingUid, r.packageName, service);
9307            if (unscheduleServiceRestartLocked(r)) {
9308                if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
9309            }
9310            r.startRequested = true;
9311            r.callStart = false;
9312            r.lastStartId++;
9313            if (r.lastStartId < 1) {
9314                r.lastStartId = 1;
9315            }
9316            r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId,
9317                    service, targetPermissionUid));
9318            r.lastActivity = SystemClock.uptimeMillis();
9319            synchronized (r.stats.getBatteryStats()) {
9320                r.stats.startRunningLocked();
9321            }
9322            if (!bringUpServiceLocked(r, service.getFlags(), false)) {
9323                return new ComponentName("!", "Service process is bad");
9324            }
9325            return r.name;
9326        }
9327    }
9328
9329    public ComponentName startService(IApplicationThread caller, Intent service,
9330            String resolvedType) {
9331        // Refuse possible leaked file descriptors
9332        if (service != null && service.hasFileDescriptors() == true) {
9333            throw new IllegalArgumentException("File descriptors passed in Intent");
9334        }
9335
9336        synchronized(this) {
9337            final int callingPid = Binder.getCallingPid();
9338            final int callingUid = Binder.getCallingUid();
9339            final long origId = Binder.clearCallingIdentity();
9340            ComponentName res = startServiceLocked(caller, service,
9341                    resolvedType, callingPid, callingUid);
9342            Binder.restoreCallingIdentity(origId);
9343            return res;
9344        }
9345    }
9346
9347    ComponentName startServiceInPackage(int uid,
9348            Intent service, String resolvedType) {
9349        synchronized(this) {
9350            final long origId = Binder.clearCallingIdentity();
9351            ComponentName res = startServiceLocked(null, service,
9352                    resolvedType, -1, uid);
9353            Binder.restoreCallingIdentity(origId);
9354            return res;
9355        }
9356    }
9357
9358    public int stopService(IApplicationThread caller, Intent service,
9359            String resolvedType) {
9360        // Refuse possible leaked file descriptors
9361        if (service != null && service.hasFileDescriptors() == true) {
9362            throw new IllegalArgumentException("File descriptors passed in Intent");
9363        }
9364
9365        synchronized(this) {
9366            if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
9367                    + " type=" + resolvedType);
9368
9369            final ProcessRecord callerApp = getRecordForAppLocked(caller);
9370            if (caller != null && callerApp == null) {
9371                throw new SecurityException(
9372                        "Unable to find app for caller " + caller
9373                        + " (pid=" + Binder.getCallingPid()
9374                        + ") when stopping service " + service);
9375            }
9376
9377            // If this service is active, make sure it is stopped.
9378            ServiceLookupResult r = findServiceLocked(service, resolvedType);
9379            if (r != null) {
9380                if (r.record != null) {
9381                    synchronized (r.record.stats.getBatteryStats()) {
9382                        r.record.stats.stopRunningLocked();
9383                    }
9384                    r.record.startRequested = false;
9385                    r.record.callStart = false;
9386                    final long origId = Binder.clearCallingIdentity();
9387                    bringDownServiceLocked(r.record, false);
9388                    Binder.restoreCallingIdentity(origId);
9389                    return 1;
9390                }
9391                return -1;
9392            }
9393        }
9394
9395        return 0;
9396    }
9397
9398    public IBinder peekService(Intent service, String resolvedType) {
9399        // Refuse possible leaked file descriptors
9400        if (service != null && service.hasFileDescriptors() == true) {
9401            throw new IllegalArgumentException("File descriptors passed in Intent");
9402        }
9403
9404        IBinder ret = null;
9405
9406        synchronized(this) {
9407            ServiceLookupResult r = findServiceLocked(service, resolvedType);
9408
9409            if (r != null) {
9410                // r.record is null if findServiceLocked() failed the caller permission check
9411                if (r.record == null) {
9412                    throw new SecurityException(
9413                            "Permission Denial: Accessing service " + r.record.name
9414                            + " from pid=" + Binder.getCallingPid()
9415                            + ", uid=" + Binder.getCallingUid()
9416                            + " requires " + r.permission);
9417                }
9418                IntentBindRecord ib = r.record.bindings.get(r.record.intent);
9419                if (ib != null) {
9420                    ret = ib.binder;
9421                }
9422            }
9423        }
9424
9425        return ret;
9426    }
9427
9428    public boolean stopServiceToken(ComponentName className, IBinder token,
9429            int startId) {
9430        synchronized(this) {
9431            if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
9432                    + " " + token + " startId=" + startId);
9433            ServiceRecord r = findServiceLocked(className, token);
9434            if (r != null) {
9435                if (startId >= 0) {
9436                    // Asked to only stop if done with all work.  Note that
9437                    // to avoid leaks, we will take this as dropping all
9438                    // start items up to and including this one.
9439                    ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
9440                    if (si != null) {
9441                        while (r.deliveredStarts.size() > 0) {
9442                            ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
9443                            cur.removeUriPermissionsLocked();
9444                            if (cur == si) {
9445                                break;
9446                            }
9447                        }
9448                    }
9449
9450                    if (r.lastStartId != startId) {
9451                        return false;
9452                    }
9453
9454                    if (r.deliveredStarts.size() > 0) {
9455                        Slog.w(TAG, "stopServiceToken startId " + startId
9456                                + " is last, but have " + r.deliveredStarts.size()
9457                                + " remaining args");
9458                    }
9459                }
9460
9461                synchronized (r.stats.getBatteryStats()) {
9462                    r.stats.stopRunningLocked();
9463                    r.startRequested = false;
9464                    r.callStart = false;
9465                }
9466                final long origId = Binder.clearCallingIdentity();
9467                bringDownServiceLocked(r, false);
9468                Binder.restoreCallingIdentity(origId);
9469                return true;
9470            }
9471        }
9472        return false;
9473    }
9474
9475    public void setServiceForeground(ComponentName className, IBinder token,
9476            int id, Notification notification, boolean removeNotification) {
9477        final long origId = Binder.clearCallingIdentity();
9478        try {
9479        synchronized(this) {
9480            ServiceRecord r = findServiceLocked(className, token);
9481            if (r != null) {
9482                if (id != 0) {
9483                    if (notification == null) {
9484                        throw new IllegalArgumentException("null notification");
9485                    }
9486                    if (r.foregroundId != id) {
9487                        r.cancelNotification();
9488                        r.foregroundId = id;
9489                    }
9490                    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
9491                    r.foregroundNoti = notification;
9492                    r.isForeground = true;
9493                    r.postNotification();
9494                    if (r.app != null) {
9495                        updateServiceForegroundLocked(r.app, true);
9496                    }
9497                } else {
9498                    if (r.isForeground) {
9499                        r.isForeground = false;
9500                        if (r.app != null) {
9501                            updateLruProcessLocked(r.app, false, true);
9502                            updateServiceForegroundLocked(r.app, true);
9503                        }
9504                    }
9505                    if (removeNotification) {
9506                        r.cancelNotification();
9507                        r.foregroundId = 0;
9508                        r.foregroundNoti = null;
9509                    }
9510                }
9511            }
9512        }
9513        } finally {
9514            Binder.restoreCallingIdentity(origId);
9515        }
9516    }
9517
9518    public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
9519        boolean anyForeground = false;
9520        for (ServiceRecord sr : proc.services) {
9521            if (sr.isForeground) {
9522                anyForeground = true;
9523                break;
9524            }
9525        }
9526        if (anyForeground != proc.foregroundServices) {
9527            proc.foregroundServices = anyForeground;
9528            if (oomAdj) {
9529                updateOomAdjLocked();
9530            }
9531        }
9532    }
9533
9534    public int bindService(IApplicationThread caller, IBinder token,
9535            Intent service, String resolvedType,
9536            IServiceConnection connection, int flags) {
9537        // Refuse possible leaked file descriptors
9538        if (service != null && service.hasFileDescriptors() == true) {
9539            throw new IllegalArgumentException("File descriptors passed in Intent");
9540        }
9541
9542        synchronized(this) {
9543            if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
9544                    + " type=" + resolvedType + " conn=" + connection.asBinder()
9545                    + " flags=0x" + Integer.toHexString(flags));
9546            final ProcessRecord callerApp = getRecordForAppLocked(caller);
9547            if (callerApp == null) {
9548                throw new SecurityException(
9549                        "Unable to find app for caller " + caller
9550                        + " (pid=" + Binder.getCallingPid()
9551                        + ") when binding service " + service);
9552            }
9553
9554            ActivityRecord activity = null;
9555            if (token != null) {
9556                int aindex = mMainStack.indexOfTokenLocked(token);
9557                if (aindex < 0) {
9558                    Slog.w(TAG, "Binding with unknown activity: " + token);
9559                    return 0;
9560                }
9561                activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
9562            }
9563
9564            int clientLabel = 0;
9565            PendingIntent clientIntent = null;
9566
9567            if (callerApp.info.uid == Process.SYSTEM_UID) {
9568                // Hacky kind of thing -- allow system stuff to tell us
9569                // what they are, so we can report this elsewhere for
9570                // others to know why certain services are running.
9571                try {
9572                    clientIntent = (PendingIntent)service.getParcelableExtra(
9573                            Intent.EXTRA_CLIENT_INTENT);
9574                } catch (RuntimeException e) {
9575                }
9576                if (clientIntent != null) {
9577                    clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
9578                    if (clientLabel != 0) {
9579                        // There are no useful extras in the intent, trash them.
9580                        // System code calling with this stuff just needs to know
9581                        // this will happen.
9582                        service = service.cloneFilter();
9583                    }
9584                }
9585            }
9586
9587            ServiceLookupResult res =
9588                retrieveServiceLocked(service, resolvedType,
9589                        Binder.getCallingPid(), Binder.getCallingUid());
9590            if (res == null) {
9591                return 0;
9592            }
9593            if (res.record == null) {
9594                return -1;
9595            }
9596            ServiceRecord s = res.record;
9597
9598            final long origId = Binder.clearCallingIdentity();
9599
9600            if (unscheduleServiceRestartLocked(s)) {
9601                if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
9602                        + s);
9603            }
9604
9605            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
9606            ConnectionRecord c = new ConnectionRecord(b, activity,
9607                    connection, flags, clientLabel, clientIntent);
9608
9609            IBinder binder = connection.asBinder();
9610            ArrayList<ConnectionRecord> clist = s.connections.get(binder);
9611            if (clist == null) {
9612                clist = new ArrayList<ConnectionRecord>();
9613                s.connections.put(binder, clist);
9614            }
9615            clist.add(c);
9616            b.connections.add(c);
9617            if (activity != null) {
9618                if (activity.connections == null) {
9619                    activity.connections = new HashSet<ConnectionRecord>();
9620                }
9621                activity.connections.add(c);
9622            }
9623            b.client.connections.add(c);
9624            clist = mServiceConnections.get(binder);
9625            if (clist == null) {
9626                clist = new ArrayList<ConnectionRecord>();
9627                mServiceConnections.put(binder, clist);
9628            }
9629            clist.add(c);
9630
9631            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
9632                s.lastActivity = SystemClock.uptimeMillis();
9633                if (!bringUpServiceLocked(s, service.getFlags(), false)) {
9634                    return 0;
9635                }
9636            }
9637
9638            if (s.app != null) {
9639                // This could have made the service more important.
9640                updateOomAdjLocked(s.app);
9641            }
9642
9643            if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
9644                    + ": received=" + b.intent.received
9645                    + " apps=" + b.intent.apps.size()
9646                    + " doRebind=" + b.intent.doRebind);
9647
9648            if (s.app != null && b.intent.received) {
9649                // Service is already running, so we can immediately
9650                // publish the connection.
9651                try {
9652                    c.conn.connected(s.name, b.intent.binder);
9653                } catch (Exception e) {
9654                    Slog.w(TAG, "Failure sending service " + s.shortName
9655                            + " to connection " + c.conn.asBinder()
9656                            + " (in " + c.binding.client.processName + ")", e);
9657                }
9658
9659                // If this is the first app connected back to this binding,
9660                // and the service had previously asked to be told when
9661                // rebound, then do so.
9662                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
9663                    requestServiceBindingLocked(s, b.intent, true);
9664                }
9665            } else if (!b.intent.requested) {
9666                requestServiceBindingLocked(s, b.intent, false);
9667            }
9668
9669            Binder.restoreCallingIdentity(origId);
9670        }
9671
9672        return 1;
9673    }
9674
9675    void removeConnectionLocked(
9676        ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
9677        IBinder binder = c.conn.asBinder();
9678        AppBindRecord b = c.binding;
9679        ServiceRecord s = b.service;
9680        ArrayList<ConnectionRecord> clist = s.connections.get(binder);
9681        if (clist != null) {
9682            clist.remove(c);
9683            if (clist.size() == 0) {
9684                s.connections.remove(binder);
9685            }
9686        }
9687        b.connections.remove(c);
9688        if (c.activity != null && c.activity != skipAct) {
9689            if (c.activity.connections != null) {
9690                c.activity.connections.remove(c);
9691            }
9692        }
9693        if (b.client != skipApp) {
9694            b.client.connections.remove(c);
9695        }
9696        clist = mServiceConnections.get(binder);
9697        if (clist != null) {
9698            clist.remove(c);
9699            if (clist.size() == 0) {
9700                mServiceConnections.remove(binder);
9701            }
9702        }
9703
9704        if (b.connections.size() == 0) {
9705            b.intent.apps.remove(b.client);
9706        }
9707
9708        if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
9709                + ": shouldUnbind=" + b.intent.hasBound);
9710        if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
9711                && b.intent.hasBound) {
9712            try {
9713                bumpServiceExecutingLocked(s, "unbind");
9714                updateOomAdjLocked(s.app);
9715                b.intent.hasBound = false;
9716                // Assume the client doesn't want to know about a rebind;
9717                // we will deal with that later if it asks for one.
9718                b.intent.doRebind = false;
9719                s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
9720            } catch (Exception e) {
9721                Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
9722                serviceDoneExecutingLocked(s, true);
9723            }
9724        }
9725
9726        if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
9727            bringDownServiceLocked(s, false);
9728        }
9729    }
9730
9731    public boolean unbindService(IServiceConnection connection) {
9732        synchronized (this) {
9733            IBinder binder = connection.asBinder();
9734            if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
9735            ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
9736            if (clist == null) {
9737                Slog.w(TAG, "Unbind failed: could not find connection for "
9738                      + connection.asBinder());
9739                return false;
9740            }
9741
9742            final long origId = Binder.clearCallingIdentity();
9743
9744            while (clist.size() > 0) {
9745                ConnectionRecord r = clist.get(0);
9746                removeConnectionLocked(r, null, null);
9747
9748                if (r.binding.service.app != null) {
9749                    // This could have made the service less important.
9750                    updateOomAdjLocked(r.binding.service.app);
9751                }
9752            }
9753
9754            Binder.restoreCallingIdentity(origId);
9755        }
9756
9757        return true;
9758    }
9759
9760    public void publishService(IBinder token, Intent intent, IBinder service) {
9761        // Refuse possible leaked file descriptors
9762        if (intent != null && intent.hasFileDescriptors() == true) {
9763            throw new IllegalArgumentException("File descriptors passed in Intent");
9764        }
9765
9766        synchronized(this) {
9767            if (!(token instanceof ServiceRecord)) {
9768                throw new IllegalArgumentException("Invalid service token");
9769            }
9770            ServiceRecord r = (ServiceRecord)token;
9771
9772            final long origId = Binder.clearCallingIdentity();
9773
9774            if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
9775                    + " " + intent + ": " + service);
9776            if (r != null) {
9777                Intent.FilterComparison filter
9778                        = new Intent.FilterComparison(intent);
9779                IntentBindRecord b = r.bindings.get(filter);
9780                if (b != null && !b.received) {
9781                    b.binder = service;
9782                    b.requested = true;
9783                    b.received = true;
9784                    if (r.connections.size() > 0) {
9785                        Iterator<ArrayList<ConnectionRecord>> it
9786                                = r.connections.values().iterator();
9787                        while (it.hasNext()) {
9788                            ArrayList<ConnectionRecord> clist = it.next();
9789                            for (int i=0; i<clist.size(); i++) {
9790                                ConnectionRecord c = clist.get(i);
9791                                if (!filter.equals(c.binding.intent.intent)) {
9792                                    if (DEBUG_SERVICE) Slog.v(
9793                                            TAG, "Not publishing to: " + c);
9794                                    if (DEBUG_SERVICE) Slog.v(
9795                                            TAG, "Bound intent: " + c.binding.intent.intent);
9796                                    if (DEBUG_SERVICE) Slog.v(
9797                                            TAG, "Published intent: " + intent);
9798                                    continue;
9799                                }
9800                                if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
9801                                try {
9802                                    c.conn.connected(r.name, service);
9803                                } catch (Exception e) {
9804                                    Slog.w(TAG, "Failure sending service " + r.name +
9805                                          " to connection " + c.conn.asBinder() +
9806                                          " (in " + c.binding.client.processName + ")", e);
9807                                }
9808                            }
9809                        }
9810                    }
9811                }
9812
9813                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
9814
9815                Binder.restoreCallingIdentity(origId);
9816            }
9817        }
9818    }
9819
9820    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
9821        // Refuse possible leaked file descriptors
9822        if (intent != null && intent.hasFileDescriptors() == true) {
9823            throw new IllegalArgumentException("File descriptors passed in Intent");
9824        }
9825
9826        synchronized(this) {
9827            if (!(token instanceof ServiceRecord)) {
9828                throw new IllegalArgumentException("Invalid service token");
9829            }
9830            ServiceRecord r = (ServiceRecord)token;
9831
9832            final long origId = Binder.clearCallingIdentity();
9833
9834            if (r != null) {
9835                Intent.FilterComparison filter
9836                        = new Intent.FilterComparison(intent);
9837                IntentBindRecord b = r.bindings.get(filter);
9838                if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
9839                        + " at " + b + ": apps="
9840                        + (b != null ? b.apps.size() : 0));
9841                if (b != null) {
9842                    if (b.apps.size() > 0) {
9843                        // Applications have already bound since the last
9844                        // unbind, so just rebind right here.
9845                        requestServiceBindingLocked(r, b, true);
9846                    } else {
9847                        // Note to tell the service the next time there is
9848                        // a new client.
9849                        b.doRebind = true;
9850                    }
9851                }
9852
9853                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
9854
9855                Binder.restoreCallingIdentity(origId);
9856            }
9857        }
9858    }
9859
9860    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
9861        synchronized(this) {
9862            if (!(token instanceof ServiceRecord)) {
9863                throw new IllegalArgumentException("Invalid service token");
9864            }
9865            ServiceRecord r = (ServiceRecord)token;
9866            boolean inStopping = mStoppingServices.contains(token);
9867            if (r != null) {
9868                if (r != token) {
9869                    Slog.w(TAG, "Done executing service " + r.name
9870                          + " with incorrect token: given " + token
9871                          + ", expected " + r);
9872                    return;
9873                }
9874
9875                if (type == 1) {
9876                    // This is a call from a service start...  take care of
9877                    // book-keeping.
9878                    r.callStart = true;
9879                    switch (res) {
9880                        case Service.START_STICKY_COMPATIBILITY:
9881                        case Service.START_STICKY: {
9882                            // We are done with the associated start arguments.
9883                            r.findDeliveredStart(startId, true);
9884                            // Don't stop if killed.
9885                            r.stopIfKilled = false;
9886                            break;
9887                        }
9888                        case Service.START_NOT_STICKY: {
9889                            // We are done with the associated start arguments.
9890                            r.findDeliveredStart(startId, true);
9891                            if (r.lastStartId == startId) {
9892                                // There is no more work, and this service
9893                                // doesn't want to hang around if killed.
9894                                r.stopIfKilled = true;
9895                            }
9896                            break;
9897                        }
9898                        case Service.START_REDELIVER_INTENT: {
9899                            // We'll keep this item until they explicitly
9900                            // call stop for it, but keep track of the fact
9901                            // that it was delivered.
9902                            ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
9903                            if (si != null) {
9904                                si.deliveryCount = 0;
9905                                si.doneExecutingCount++;
9906                                // Don't stop if killed.
9907                                r.stopIfKilled = true;
9908                            }
9909                            break;
9910                        }
9911                        default:
9912                            throw new IllegalArgumentException(
9913                                    "Unknown service start result: " + res);
9914                    }
9915                    if (res == Service.START_STICKY_COMPATIBILITY) {
9916                        r.callStart = false;
9917                    }
9918                }
9919
9920                final long origId = Binder.clearCallingIdentity();
9921                serviceDoneExecutingLocked(r, inStopping);
9922                Binder.restoreCallingIdentity(origId);
9923            } else {
9924                Slog.w(TAG, "Done executing unknown service from pid "
9925                        + Binder.getCallingPid());
9926            }
9927        }
9928    }
9929
9930    public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
9931        if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
9932                + ": nesting=" + r.executeNesting
9933                + ", inStopping=" + inStopping + ", app=" + r.app);
9934        else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
9935        r.executeNesting--;
9936        if (r.executeNesting <= 0 && r.app != null) {
9937            if (DEBUG_SERVICE) Slog.v(TAG,
9938                    "Nesting at 0 of " + r.shortName);
9939            r.app.executingServices.remove(r);
9940            if (r.app.executingServices.size() == 0) {
9941                if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
9942                        "No more executingServices of " + r.shortName);
9943                mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
9944            }
9945            if (inStopping) {
9946                if (DEBUG_SERVICE) Slog.v(TAG,
9947                        "doneExecuting remove stopping " + r);
9948                mStoppingServices.remove(r);
9949            }
9950            updateOomAdjLocked(r.app);
9951        }
9952    }
9953
9954    void serviceTimeout(ProcessRecord proc) {
9955        String anrMessage = null;
9956
9957        synchronized(this) {
9958            if (proc.executingServices.size() == 0 || proc.thread == null) {
9959                return;
9960            }
9961            long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
9962            Iterator<ServiceRecord> it = proc.executingServices.iterator();
9963            ServiceRecord timeout = null;
9964            long nextTime = 0;
9965            while (it.hasNext()) {
9966                ServiceRecord sr = it.next();
9967                if (sr.executingStart < maxTime) {
9968                    timeout = sr;
9969                    break;
9970                }
9971                if (sr.executingStart > nextTime) {
9972                    nextTime = sr.executingStart;
9973                }
9974            }
9975            if (timeout != null && mLruProcesses.contains(proc)) {
9976                Slog.w(TAG, "Timeout executing service: " + timeout);
9977                anrMessage = "Executing service " + timeout.shortName;
9978            } else {
9979                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9980                msg.obj = proc;
9981                mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
9982            }
9983        }
9984
9985        if (anrMessage != null) {
9986            appNotResponding(proc, null, null, anrMessage);
9987        }
9988    }
9989
9990    // =========================================================
9991    // BACKUP AND RESTORE
9992    // =========================================================
9993
9994    // Cause the target app to be launched if necessary and its backup agent
9995    // instantiated.  The backup agent will invoke backupAgentCreated() on the
9996    // activity manager to announce its creation.
9997    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
9998        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
9999        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10000
10001        synchronized(this) {
10002            // !!! TODO: currently no check here that we're already bound
10003            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10004            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10005            synchronized (stats) {
10006                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10007            }
10008
10009            BackupRecord r = new BackupRecord(ss, app, backupMode);
10010            ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
10011            // startProcessLocked() returns existing proc's record if it's already running
10012            ProcessRecord proc = startProcessLocked(app.processName, app,
10013                    false, 0, "backup", hostingName, false);
10014            if (proc == null) {
10015                Slog.e(TAG, "Unable to start backup agent process " + r);
10016                return false;
10017            }
10018
10019            r.app = proc;
10020            mBackupTarget = r;
10021            mBackupAppName = app.packageName;
10022
10023            // Try not to kill the process during backup
10024            updateOomAdjLocked(proc);
10025
10026            // If the process is already attached, schedule the creation of the backup agent now.
10027            // If it is not yet live, this will be done when it attaches to the framework.
10028            if (proc.thread != null) {
10029                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
10030                try {
10031                    proc.thread.scheduleCreateBackupAgent(app, backupMode);
10032                } catch (RemoteException e) {
10033                    // Will time out on the backup manager side
10034                }
10035            } else {
10036                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
10037            }
10038            // Invariants: at this point, the target app process exists and the application
10039            // is either already running or in the process of coming up.  mBackupTarget and
10040            // mBackupAppName describe the app, so that when it binds back to the AM we
10041            // know that it's scheduled for a backup-agent operation.
10042        }
10043
10044        return true;
10045    }
10046
10047    // A backup agent has just come up
10048    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10049        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
10050                + " = " + agent);
10051
10052        synchronized(this) {
10053            if (!agentPackageName.equals(mBackupAppName)) {
10054                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10055                return;
10056            }
10057        }
10058
10059        long oldIdent = Binder.clearCallingIdentity();
10060        try {
10061            IBackupManager bm = IBackupManager.Stub.asInterface(
10062                    ServiceManager.getService(Context.BACKUP_SERVICE));
10063            bm.agentConnected(agentPackageName, agent);
10064        } catch (RemoteException e) {
10065            // can't happen; the backup manager service is local
10066        } catch (Exception e) {
10067            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10068            e.printStackTrace();
10069        } finally {
10070            Binder.restoreCallingIdentity(oldIdent);
10071        }
10072    }
10073
10074    // done with this agent
10075    public void unbindBackupAgent(ApplicationInfo appInfo) {
10076        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
10077        if (appInfo == null) {
10078            Slog.w(TAG, "unbind backup agent for null app");
10079            return;
10080        }
10081
10082        synchronized(this) {
10083            if (mBackupAppName == null) {
10084                Slog.w(TAG, "Unbinding backup agent with no active backup");
10085                return;
10086            }
10087
10088            if (!mBackupAppName.equals(appInfo.packageName)) {
10089                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
10090                return;
10091            }
10092
10093            ProcessRecord proc = mBackupTarget.app;
10094            mBackupTarget = null;
10095            mBackupAppName = null;
10096
10097            // Not backing this app up any more; reset its OOM adjustment
10098            updateOomAdjLocked(proc);
10099
10100            // If the app crashed during backup, 'thread' will be null here
10101            if (proc.thread != null) {
10102                try {
10103                    proc.thread.scheduleDestroyBackupAgent(appInfo);
10104                } catch (Exception e) {
10105                    Slog.e(TAG, "Exception when unbinding backup agent:");
10106                    e.printStackTrace();
10107                }
10108            }
10109        }
10110    }
10111    // =========================================================
10112    // BROADCASTS
10113    // =========================================================
10114
10115    private final List getStickiesLocked(String action, IntentFilter filter,
10116            List cur) {
10117        final ContentResolver resolver = mContext.getContentResolver();
10118        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10119        if (list == null) {
10120            return cur;
10121        }
10122        int N = list.size();
10123        for (int i=0; i<N; i++) {
10124            Intent intent = list.get(i);
10125            if (filter.match(resolver, intent, true, TAG) >= 0) {
10126                if (cur == null) {
10127                    cur = new ArrayList<Intent>();
10128                }
10129                cur.add(intent);
10130            }
10131        }
10132        return cur;
10133    }
10134
10135    private final void scheduleBroadcastsLocked() {
10136        if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
10137                + mBroadcastsScheduled);
10138
10139        if (mBroadcastsScheduled) {
10140            return;
10141        }
10142        mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
10143        mBroadcastsScheduled = true;
10144    }
10145
10146    public Intent registerReceiver(IApplicationThread caller,
10147            IIntentReceiver receiver, IntentFilter filter, String permission) {
10148        synchronized(this) {
10149            ProcessRecord callerApp = null;
10150            if (caller != null) {
10151                callerApp = getRecordForAppLocked(caller);
10152                if (callerApp == null) {
10153                    throw new SecurityException(
10154                            "Unable to find app for caller " + caller
10155                            + " (pid=" + Binder.getCallingPid()
10156                            + ") when registering receiver " + receiver);
10157                }
10158            }
10159
10160            List allSticky = null;
10161
10162            // Look for any matching sticky broadcasts...
10163            Iterator actions = filter.actionsIterator();
10164            if (actions != null) {
10165                while (actions.hasNext()) {
10166                    String action = (String)actions.next();
10167                    allSticky = getStickiesLocked(action, filter, allSticky);
10168                }
10169            } else {
10170                allSticky = getStickiesLocked(null, filter, allSticky);
10171            }
10172
10173            // The first sticky in the list is returned directly back to
10174            // the client.
10175            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10176
10177            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
10178                    + ": " + sticky);
10179
10180            if (receiver == null) {
10181                return sticky;
10182            }
10183
10184            ReceiverList rl
10185                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10186            if (rl == null) {
10187                rl = new ReceiverList(this, callerApp,
10188                        Binder.getCallingPid(),
10189                        Binder.getCallingUid(), receiver);
10190                if (rl.app != null) {
10191                    rl.app.receivers.add(rl);
10192                } else {
10193                    try {
10194                        receiver.asBinder().linkToDeath(rl, 0);
10195                    } catch (RemoteException e) {
10196                        return sticky;
10197                    }
10198                    rl.linkedToDeath = true;
10199                }
10200                mRegisteredReceivers.put(receiver.asBinder(), rl);
10201            }
10202            BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
10203            rl.add(bf);
10204            if (!bf.debugCheck()) {
10205                Slog.w(TAG, "==> For Dynamic broadast");
10206            }
10207            mReceiverResolver.addFilter(bf);
10208
10209            // Enqueue broadcasts for all existing stickies that match
10210            // this filter.
10211            if (allSticky != null) {
10212                ArrayList receivers = new ArrayList();
10213                receivers.add(bf);
10214
10215                int N = allSticky.size();
10216                for (int i=0; i<N; i++) {
10217                    Intent intent = (Intent)allSticky.get(i);
10218                    BroadcastRecord r = new BroadcastRecord(intent, null,
10219                            null, -1, -1, null, receivers, null, 0, null, null,
10220                            false, true, true);
10221                    if (mParallelBroadcasts.size() == 0) {
10222                        scheduleBroadcastsLocked();
10223                    }
10224                    mParallelBroadcasts.add(r);
10225                }
10226            }
10227
10228            return sticky;
10229        }
10230    }
10231
10232    public void unregisterReceiver(IIntentReceiver receiver) {
10233        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
10234
10235        boolean doNext = false;
10236
10237        synchronized(this) {
10238            ReceiverList rl
10239                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10240            if (rl != null) {
10241                if (rl.curBroadcast != null) {
10242                    BroadcastRecord r = rl.curBroadcast;
10243                    doNext = finishReceiverLocked(
10244                        receiver.asBinder(), r.resultCode, r.resultData,
10245                        r.resultExtras, r.resultAbort, true);
10246                }
10247
10248                if (rl.app != null) {
10249                    rl.app.receivers.remove(rl);
10250                }
10251                removeReceiverLocked(rl);
10252                if (rl.linkedToDeath) {
10253                    rl.linkedToDeath = false;
10254                    rl.receiver.asBinder().unlinkToDeath(rl, 0);
10255                }
10256            }
10257        }
10258
10259        if (!doNext) {
10260            return;
10261        }
10262
10263        final long origId = Binder.clearCallingIdentity();
10264        processNextBroadcast(false);
10265        trimApplications();
10266        Binder.restoreCallingIdentity(origId);
10267    }
10268
10269    void removeReceiverLocked(ReceiverList rl) {
10270        mRegisteredReceivers.remove(rl.receiver.asBinder());
10271        int N = rl.size();
10272        for (int i=0; i<N; i++) {
10273            mReceiverResolver.removeFilter(rl.get(i));
10274        }
10275    }
10276
10277    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
10278        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10279            ProcessRecord r = mLruProcesses.get(i);
10280            if (r.thread != null) {
10281                try {
10282                    r.thread.dispatchPackageBroadcast(cmd, packages);
10283                } catch (RemoteException ex) {
10284                }
10285            }
10286        }
10287    }
10288
10289    private final int broadcastIntentLocked(ProcessRecord callerApp,
10290            String callerPackage, Intent intent, String resolvedType,
10291            IIntentReceiver resultTo, int resultCode, String resultData,
10292            Bundle map, String requiredPermission,
10293            boolean ordered, boolean sticky, int callingPid, int callingUid) {
10294        intent = new Intent(intent);
10295
10296        if (DEBUG_BROADCAST_LIGHT) Slog.v(
10297            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
10298            + " ordered=" + ordered);
10299        if ((resultTo != null) && !ordered) {
10300            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
10301        }
10302
10303        // Handle special intents: if this broadcast is from the package
10304        // manager about a package being removed, we need to remove all of
10305        // its activities from the history stack.
10306        final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals(
10307                intent.getAction());
10308        if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
10309                || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
10310                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
10311                || uidRemoved) {
10312            if (checkComponentPermission(
10313                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
10314                    callingPid, callingUid, -1)
10315                    == PackageManager.PERMISSION_GRANTED) {
10316                if (uidRemoved) {
10317                    final Bundle intentExtras = intent.getExtras();
10318                    final int uid = intentExtras != null
10319                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
10320                    if (uid >= 0) {
10321                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
10322                        synchronized (bs) {
10323                            bs.removeUidStatsLocked(uid);
10324                        }
10325                    }
10326                } else {
10327                    // If resources are unvailble just force stop all
10328                    // those packages and flush the attribute cache as well.
10329                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
10330                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
10331                        if (list != null && (list.length > 0)) {
10332                            for (String pkg : list) {
10333                                forceStopPackageLocked(pkg, -1, false, true, true);
10334                            }
10335                            sendPackageBroadcastLocked(
10336                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
10337                        }
10338                    } else {
10339                        Uri data = intent.getData();
10340                        String ssp;
10341                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
10342                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
10343                                forceStopPackageLocked(ssp,
10344                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
10345                            }
10346                            if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
10347                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
10348                                        new String[] {ssp});
10349                            }
10350                        }
10351                    }
10352                }
10353            } else {
10354                String msg = "Permission Denial: " + intent.getAction()
10355                        + " broadcast from " + callerPackage + " (pid=" + callingPid
10356                        + ", uid=" + callingUid + ")"
10357                        + " requires "
10358                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
10359                Slog.w(TAG, msg);
10360                throw new SecurityException(msg);
10361            }
10362        }
10363
10364        /*
10365         * If this is the time zone changed action, queue up a message that will reset the timezone
10366         * of all currently running processes. This message will get queued up before the broadcast
10367         * happens.
10368         */
10369        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
10370            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
10371        }
10372
10373        /*
10374         * Prevent non-system code (defined here to be non-persistent
10375         * processes) from sending protected broadcasts.
10376         */
10377        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
10378                || callingUid == Process.SHELL_UID || callingUid == 0) {
10379            // Always okay.
10380        } else if (callerApp == null || !callerApp.persistent) {
10381            try {
10382                if (AppGlobals.getPackageManager().isProtectedBroadcast(
10383                        intent.getAction())) {
10384                    String msg = "Permission Denial: not allowed to send broadcast "
10385                            + intent.getAction() + " from pid="
10386                            + callingPid + ", uid=" + callingUid;
10387                    Slog.w(TAG, msg);
10388                    throw new SecurityException(msg);
10389                }
10390            } catch (RemoteException e) {
10391                Slog.w(TAG, "Remote exception", e);
10392                return BROADCAST_SUCCESS;
10393            }
10394        }
10395
10396        // Add to the sticky list if requested.
10397        if (sticky) {
10398            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
10399                    callingPid, callingUid)
10400                    != PackageManager.PERMISSION_GRANTED) {
10401                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
10402                        + callingPid + ", uid=" + callingUid
10403                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
10404                Slog.w(TAG, msg);
10405                throw new SecurityException(msg);
10406            }
10407            if (requiredPermission != null) {
10408                Slog.w(TAG, "Can't broadcast sticky intent " + intent
10409                        + " and enforce permission " + requiredPermission);
10410                return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
10411            }
10412            if (intent.getComponent() != null) {
10413                throw new SecurityException(
10414                        "Sticky broadcasts can't target a specific component");
10415            }
10416            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
10417            if (list == null) {
10418                list = new ArrayList<Intent>();
10419                mStickyBroadcasts.put(intent.getAction(), list);
10420            }
10421            int N = list.size();
10422            int i;
10423            for (i=0; i<N; i++) {
10424                if (intent.filterEquals(list.get(i))) {
10425                    // This sticky already exists, replace it.
10426                    list.set(i, new Intent(intent));
10427                    break;
10428                }
10429            }
10430            if (i >= N) {
10431                list.add(new Intent(intent));
10432            }
10433        }
10434
10435        // Figure out who all will receive this broadcast.
10436        List receivers = null;
10437        List<BroadcastFilter> registeredReceivers = null;
10438        try {
10439            if (intent.getComponent() != null) {
10440                // Broadcast is going to one specific receiver class...
10441                ActivityInfo ai = AppGlobals.getPackageManager().
10442                    getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
10443                if (ai != null) {
10444                    receivers = new ArrayList();
10445                    ResolveInfo ri = new ResolveInfo();
10446                    ri.activityInfo = ai;
10447                    receivers.add(ri);
10448                }
10449            } else {
10450                // Need to resolve the intent to interested receivers...
10451                if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
10452                         == 0) {
10453                    receivers =
10454                        AppGlobals.getPackageManager().queryIntentReceivers(
10455                                intent, resolvedType, STOCK_PM_FLAGS);
10456                }
10457                registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
10458            }
10459        } catch (RemoteException ex) {
10460            // pm is in same process, this will never happen.
10461        }
10462
10463        final boolean replacePending =
10464                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
10465
10466        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
10467                + " replacePending=" + replacePending);
10468
10469        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
10470        if (!ordered && NR > 0) {
10471            // If we are not serializing this broadcast, then send the
10472            // registered receivers separately so they don't wait for the
10473            // components to be launched.
10474            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
10475                    callerPackage, callingPid, callingUid, requiredPermission,
10476                    registeredReceivers, resultTo, resultCode, resultData, map,
10477                    ordered, sticky, false);
10478            if (DEBUG_BROADCAST) Slog.v(
10479                    TAG, "Enqueueing parallel broadcast " + r
10480                    + ": prev had " + mParallelBroadcasts.size());
10481            boolean replaced = false;
10482            if (replacePending) {
10483                for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
10484                    if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
10485                        if (DEBUG_BROADCAST) Slog.v(TAG,
10486                                "***** DROPPING PARALLEL: " + intent);
10487                        mParallelBroadcasts.set(i, r);
10488                        replaced = true;
10489                        break;
10490                    }
10491                }
10492            }
10493            if (!replaced) {
10494                mParallelBroadcasts.add(r);
10495                scheduleBroadcastsLocked();
10496            }
10497            registeredReceivers = null;
10498            NR = 0;
10499        }
10500
10501        // Merge into one list.
10502        int ir = 0;
10503        if (receivers != null) {
10504            // A special case for PACKAGE_ADDED: do not allow the package
10505            // being added to see this broadcast.  This prevents them from
10506            // using this as a back door to get run as soon as they are
10507            // installed.  Maybe in the future we want to have a special install
10508            // broadcast or such for apps, but we'd like to deliberately make
10509            // this decision.
10510            String skipPackages[] = null;
10511            if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
10512                    || intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
10513                    || intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
10514                Uri data = intent.getData();
10515                if (data != null) {
10516                    String pkgName = data.getSchemeSpecificPart();
10517                    if (pkgName != null) {
10518                        skipPackages = new String[] { pkgName };
10519                    }
10520                }
10521            } else if (intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
10522                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
10523            }
10524            if (skipPackages != null && (skipPackages.length > 0)) {
10525                for (String skipPackage : skipPackages) {
10526                    if (skipPackage != null) {
10527                        int NT = receivers.size();
10528                        for (int it=0; it<NT; it++) {
10529                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
10530                            if (curt.activityInfo.packageName.equals(skipPackage)) {
10531                                receivers.remove(it);
10532                                it--;
10533                                NT--;
10534                            }
10535                        }
10536                    }
10537                }
10538            }
10539
10540            int NT = receivers != null ? receivers.size() : 0;
10541            int it = 0;
10542            ResolveInfo curt = null;
10543            BroadcastFilter curr = null;
10544            while (it < NT && ir < NR) {
10545                if (curt == null) {
10546                    curt = (ResolveInfo)receivers.get(it);
10547                }
10548                if (curr == null) {
10549                    curr = registeredReceivers.get(ir);
10550                }
10551                if (curr.getPriority() >= curt.priority) {
10552                    // Insert this broadcast record into the final list.
10553                    receivers.add(it, curr);
10554                    ir++;
10555                    curr = null;
10556                    it++;
10557                    NT++;
10558                } else {
10559                    // Skip to the next ResolveInfo in the final list.
10560                    it++;
10561                    curt = null;
10562                }
10563            }
10564        }
10565        while (ir < NR) {
10566            if (receivers == null) {
10567                receivers = new ArrayList();
10568            }
10569            receivers.add(registeredReceivers.get(ir));
10570            ir++;
10571        }
10572
10573        if ((receivers != null && receivers.size() > 0)
10574                || resultTo != null) {
10575            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
10576                    callerPackage, callingPid, callingUid, requiredPermission,
10577                    receivers, resultTo, resultCode, resultData, map, ordered,
10578                    sticky, false);
10579            if (DEBUG_BROADCAST) Slog.v(
10580                    TAG, "Enqueueing ordered broadcast " + r
10581                    + ": prev had " + mOrderedBroadcasts.size());
10582            if (DEBUG_BROADCAST) {
10583                int seq = r.intent.getIntExtra("seq", -1);
10584                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
10585            }
10586            boolean replaced = false;
10587            if (replacePending) {
10588                for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
10589                    if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
10590                        if (DEBUG_BROADCAST) Slog.v(TAG,
10591                                "***** DROPPING ORDERED: " + intent);
10592                        mOrderedBroadcasts.set(i, r);
10593                        replaced = true;
10594                        break;
10595                    }
10596                }
10597            }
10598            if (!replaced) {
10599                mOrderedBroadcasts.add(r);
10600                scheduleBroadcastsLocked();
10601            }
10602        }
10603
10604        return BROADCAST_SUCCESS;
10605    }
10606
10607    final Intent verifyBroadcastLocked(Intent intent) {
10608        // Refuse possible leaked file descriptors
10609        if (intent != null && intent.hasFileDescriptors() == true) {
10610            throw new IllegalArgumentException("File descriptors passed in Intent");
10611        }
10612
10613        int flags = intent.getFlags();
10614
10615        if (!mProcessesReady) {
10616            // if the caller really truly claims to know what they're doing, go
10617            // ahead and allow the broadcast without launching any receivers
10618            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
10619                intent = new Intent(intent);
10620                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10621            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
10622                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
10623                        + " before boot completion");
10624                throw new IllegalStateException("Cannot broadcast before boot completed");
10625            }
10626        }
10627
10628        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
10629            throw new IllegalArgumentException(
10630                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
10631        }
10632
10633        return intent;
10634    }
10635
10636    public final int broadcastIntent(IApplicationThread caller,
10637            Intent intent, String resolvedType, IIntentReceiver resultTo,
10638            int resultCode, String resultData, Bundle map,
10639            String requiredPermission, boolean serialized, boolean sticky) {
10640        synchronized(this) {
10641            intent = verifyBroadcastLocked(intent);
10642
10643            final ProcessRecord callerApp = getRecordForAppLocked(caller);
10644            final int callingPid = Binder.getCallingPid();
10645            final int callingUid = Binder.getCallingUid();
10646            final long origId = Binder.clearCallingIdentity();
10647            int res = broadcastIntentLocked(callerApp,
10648                    callerApp != null ? callerApp.info.packageName : null,
10649                    intent, resolvedType, resultTo,
10650                    resultCode, resultData, map, requiredPermission, serialized,
10651                    sticky, callingPid, callingUid);
10652            Binder.restoreCallingIdentity(origId);
10653            return res;
10654        }
10655    }
10656
10657    int broadcastIntentInPackage(String packageName, int uid,
10658            Intent intent, String resolvedType, IIntentReceiver resultTo,
10659            int resultCode, String resultData, Bundle map,
10660            String requiredPermission, boolean serialized, boolean sticky) {
10661        synchronized(this) {
10662            intent = verifyBroadcastLocked(intent);
10663
10664            final long origId = Binder.clearCallingIdentity();
10665            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
10666                    resultTo, resultCode, resultData, map, requiredPermission,
10667                    serialized, sticky, -1, uid);
10668            Binder.restoreCallingIdentity(origId);
10669            return res;
10670        }
10671    }
10672
10673    public final void unbroadcastIntent(IApplicationThread caller,
10674            Intent intent) {
10675        // Refuse possible leaked file descriptors
10676        if (intent != null && intent.hasFileDescriptors() == true) {
10677            throw new IllegalArgumentException("File descriptors passed in Intent");
10678        }
10679
10680        synchronized(this) {
10681            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
10682                    != PackageManager.PERMISSION_GRANTED) {
10683                String msg = "Permission Denial: unbroadcastIntent() from pid="
10684                        + Binder.getCallingPid()
10685                        + ", uid=" + Binder.getCallingUid()
10686                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
10687                Slog.w(TAG, msg);
10688                throw new SecurityException(msg);
10689            }
10690            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
10691            if (list != null) {
10692                int N = list.size();
10693                int i;
10694                for (i=0; i<N; i++) {
10695                    if (intent.filterEquals(list.get(i))) {
10696                        list.remove(i);
10697                        break;
10698                    }
10699                }
10700            }
10701        }
10702    }
10703
10704    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
10705            String resultData, Bundle resultExtras, boolean resultAbort,
10706            boolean explicit) {
10707        if (mOrderedBroadcasts.size() == 0) {
10708            if (explicit) {
10709                Slog.w(TAG, "finishReceiver called but no pending broadcasts");
10710            }
10711            return false;
10712        }
10713        BroadcastRecord r = mOrderedBroadcasts.get(0);
10714        if (r.receiver == null) {
10715            if (explicit) {
10716                Slog.w(TAG, "finishReceiver called but none active");
10717            }
10718            return false;
10719        }
10720        if (r.receiver != receiver) {
10721            Slog.w(TAG, "finishReceiver called but active receiver is different");
10722            return false;
10723        }
10724        int state = r.state;
10725        r.state = r.IDLE;
10726        if (state == r.IDLE) {
10727            if (explicit) {
10728                Slog.w(TAG, "finishReceiver called but state is IDLE");
10729            }
10730        }
10731        r.receiver = null;
10732        r.intent.setComponent(null);
10733        if (r.curApp != null) {
10734            r.curApp.curReceiver = null;
10735        }
10736        if (r.curFilter != null) {
10737            r.curFilter.receiverList.curBroadcast = null;
10738        }
10739        r.curFilter = null;
10740        r.curApp = null;
10741        r.curComponent = null;
10742        r.curReceiver = null;
10743        mPendingBroadcast = null;
10744
10745        r.resultCode = resultCode;
10746        r.resultData = resultData;
10747        r.resultExtras = resultExtras;
10748        r.resultAbort = resultAbort;
10749
10750        // We will process the next receiver right now if this is finishing
10751        // an app receiver (which is always asynchronous) or after we have
10752        // come back from calling a receiver.
10753        return state == BroadcastRecord.APP_RECEIVE
10754                || state == BroadcastRecord.CALL_DONE_RECEIVE;
10755    }
10756
10757    public void finishReceiver(IBinder who, int resultCode, String resultData,
10758            Bundle resultExtras, boolean resultAbort) {
10759        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
10760
10761        // Refuse possible leaked file descriptors
10762        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
10763            throw new IllegalArgumentException("File descriptors passed in Bundle");
10764        }
10765
10766        boolean doNext;
10767
10768        final long origId = Binder.clearCallingIdentity();
10769
10770        synchronized(this) {
10771            doNext = finishReceiverLocked(
10772                who, resultCode, resultData, resultExtras, resultAbort, true);
10773        }
10774
10775        if (doNext) {
10776            processNextBroadcast(false);
10777        }
10778        trimApplications();
10779
10780        Binder.restoreCallingIdentity(origId);
10781    }
10782
10783    private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
10784        if (r.nextReceiver > 0) {
10785            Object curReceiver = r.receivers.get(r.nextReceiver-1);
10786            if (curReceiver instanceof BroadcastFilter) {
10787                BroadcastFilter bf = (BroadcastFilter) curReceiver;
10788                EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
10789                        System.identityHashCode(r),
10790                        r.intent.getAction(),
10791                        r.nextReceiver - 1,
10792                        System.identityHashCode(bf));
10793            } else {
10794                EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
10795                        System.identityHashCode(r),
10796                        r.intent.getAction(),
10797                        r.nextReceiver - 1,
10798                        ((ResolveInfo)curReceiver).toString());
10799            }
10800        } else {
10801            Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
10802                    + r);
10803            EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
10804                    System.identityHashCode(r),
10805                    r.intent.getAction(),
10806                    r.nextReceiver,
10807                    "NONE");
10808        }
10809    }
10810
10811    private final void setBroadcastTimeoutLocked(long timeoutTime) {
10812        if (! mPendingBroadcastTimeoutMessage) {
10813            Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
10814            mHandler.sendMessageAtTime(msg, timeoutTime);
10815            mPendingBroadcastTimeoutMessage = true;
10816        }
10817    }
10818
10819    private final void cancelBroadcastTimeoutLocked() {
10820        if (mPendingBroadcastTimeoutMessage) {
10821            mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
10822            mPendingBroadcastTimeoutMessage = false;
10823        }
10824    }
10825
10826    private final void broadcastTimeoutLocked(boolean fromMsg) {
10827        if (fromMsg) {
10828            mPendingBroadcastTimeoutMessage = false;
10829        }
10830
10831        if (mOrderedBroadcasts.size() == 0) {
10832            return;
10833        }
10834
10835        long now = SystemClock.uptimeMillis();
10836        BroadcastRecord r = mOrderedBroadcasts.get(0);
10837        if (fromMsg) {
10838            if (mDidDexOpt) {
10839                // Delay timeouts until dexopt finishes.
10840                mDidDexOpt = false;
10841                long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
10842                setBroadcastTimeoutLocked(timeoutTime);
10843                return;
10844            }
10845            if (! mProcessesReady) {
10846                // Only process broadcast timeouts if the system is ready. That way
10847                // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
10848                // to do heavy lifting for system up.
10849                return;
10850            }
10851
10852            long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
10853            if (timeoutTime > now) {
10854                // We can observe premature timeouts because we do not cancel and reset the
10855                // broadcast timeout message after each receiver finishes.  Instead, we set up
10856                // an initial timeout then kick it down the road a little further as needed
10857                // when it expires.
10858                if (DEBUG_BROADCAST) Slog.v(TAG,
10859                        "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
10860                        + timeoutTime);
10861                setBroadcastTimeoutLocked(timeoutTime);
10862                return;
10863            }
10864        }
10865
10866        Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
10867                + ", started " + (now - r.receiverTime) + "ms ago");
10868        r.receiverTime = now;
10869        r.anrCount++;
10870
10871        // Current receiver has passed its expiration date.
10872        if (r.nextReceiver <= 0) {
10873            Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
10874            return;
10875        }
10876
10877        ProcessRecord app = null;
10878        String anrMessage = null;
10879
10880        Object curReceiver = r.receivers.get(r.nextReceiver-1);
10881        Slog.w(TAG, "Receiver during timeout: " + curReceiver);
10882        logBroadcastReceiverDiscardLocked(r);
10883        if (curReceiver instanceof BroadcastFilter) {
10884            BroadcastFilter bf = (BroadcastFilter)curReceiver;
10885            if (bf.receiverList.pid != 0
10886                    && bf.receiverList.pid != MY_PID) {
10887                synchronized (this.mPidsSelfLocked) {
10888                    app = this.mPidsSelfLocked.get(
10889                            bf.receiverList.pid);
10890                }
10891            }
10892        } else {
10893            app = r.curApp;
10894        }
10895
10896        if (app != null) {
10897            anrMessage = "Broadcast of " + r.intent.toString();
10898        }
10899
10900        if (mPendingBroadcast == r) {
10901            mPendingBroadcast = null;
10902        }
10903
10904        // Move on to the next receiver.
10905        finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
10906                r.resultExtras, r.resultAbort, true);
10907        scheduleBroadcastsLocked();
10908
10909        if (anrMessage != null) {
10910            // Post the ANR to the handler since we do not want to process ANRs while
10911            // potentially holding our lock.
10912            mHandler.post(new AppNotResponding(app, anrMessage));
10913        }
10914    }
10915
10916    private final void processCurBroadcastLocked(BroadcastRecord r,
10917            ProcessRecord app) throws RemoteException {
10918        if (DEBUG_BROADCAST)  Slog.v(TAG,
10919                "Process cur broadcast " + r + " for app " + app);
10920        if (app.thread == null) {
10921            throw new RemoteException();
10922        }
10923        r.receiver = app.thread.asBinder();
10924        r.curApp = app;
10925        app.curReceiver = r;
10926        updateLruProcessLocked(app, true, true);
10927
10928        // Tell the application to launch this receiver.
10929        r.intent.setComponent(r.curComponent);
10930
10931        boolean started = false;
10932        try {
10933            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
10934                    "Delivering to component " + r.curComponent
10935                    + ": " + r);
10936            ensurePackageDexOpt(r.intent.getComponent().getPackageName());
10937            app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
10938                    r.resultCode, r.resultData, r.resultExtras, r.ordered);
10939            if (DEBUG_BROADCAST)  Slog.v(TAG,
10940                    "Process cur broadcast " + r + " DELIVERED for app " + app);
10941            started = true;
10942        } finally {
10943            if (!started) {
10944                if (DEBUG_BROADCAST)  Slog.v(TAG,
10945                        "Process cur broadcast " + r + ": NOT STARTED!");
10946                r.receiver = null;
10947                r.curApp = null;
10948                app.curReceiver = null;
10949            }
10950        }
10951
10952    }
10953
10954    static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
10955            Intent intent, int resultCode, String data, Bundle extras,
10956            boolean ordered, boolean sticky) throws RemoteException {
10957        // Send the intent to the receiver asynchronously using one-way binder calls.
10958        if (app != null && app.thread != null) {
10959            // If we have an app thread, do the call through that so it is
10960            // correctly ordered with other one-way calls.
10961            app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
10962                    data, extras, ordered, sticky);
10963        } else {
10964            receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
10965        }
10966    }
10967
10968    private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
10969            BroadcastFilter filter, boolean ordered) {
10970        boolean skip = false;
10971        if (filter.requiredPermission != null) {
10972            int perm = checkComponentPermission(filter.requiredPermission,
10973                    r.callingPid, r.callingUid, -1);
10974            if (perm != PackageManager.PERMISSION_GRANTED) {
10975                Slog.w(TAG, "Permission Denial: broadcasting "
10976                        + r.intent.toString()
10977                        + " from " + r.callerPackage + " (pid="
10978                        + r.callingPid + ", uid=" + r.callingUid + ")"
10979                        + " requires " + filter.requiredPermission
10980                        + " due to registered receiver " + filter);
10981                skip = true;
10982            }
10983        }
10984        if (r.requiredPermission != null) {
10985            int perm = checkComponentPermission(r.requiredPermission,
10986                    filter.receiverList.pid, filter.receiverList.uid, -1);
10987            if (perm != PackageManager.PERMISSION_GRANTED) {
10988                Slog.w(TAG, "Permission Denial: receiving "
10989                        + r.intent.toString()
10990                        + " to " + filter.receiverList.app
10991                        + " (pid=" + filter.receiverList.pid
10992                        + ", uid=" + filter.receiverList.uid + ")"
10993                        + " requires " + r.requiredPermission
10994                        + " due to sender " + r.callerPackage
10995                        + " (uid " + r.callingUid + ")");
10996                skip = true;
10997            }
10998        }
10999
11000        if (!skip) {
11001            // If this is not being sent as an ordered broadcast, then we
11002            // don't want to touch the fields that keep track of the current
11003            // state of ordered broadcasts.
11004            if (ordered) {
11005                r.receiver = filter.receiverList.receiver.asBinder();
11006                r.curFilter = filter;
11007                filter.receiverList.curBroadcast = r;
11008                r.state = BroadcastRecord.CALL_IN_RECEIVE;
11009                if (filter.receiverList.app != null) {
11010                    // Bump hosting application to no longer be in background
11011                    // scheduling class.  Note that we can't do that if there
11012                    // isn't an app...  but we can only be in that case for
11013                    // things that directly call the IActivityManager API, which
11014                    // are already core system stuff so don't matter for this.
11015                    r.curApp = filter.receiverList.app;
11016                    filter.receiverList.app.curReceiver = r;
11017                    updateOomAdjLocked();
11018                }
11019            }
11020            try {
11021                if (DEBUG_BROADCAST_LIGHT) {
11022                    int seq = r.intent.getIntExtra("seq", -1);
11023                    Slog.i(TAG, "Delivering to " + filter
11024                            + " (seq=" + seq + "): " + r);
11025                }
11026                performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
11027                    new Intent(r.intent), r.resultCode,
11028                    r.resultData, r.resultExtras, r.ordered, r.initialSticky);
11029                if (ordered) {
11030                    r.state = BroadcastRecord.CALL_DONE_RECEIVE;
11031                }
11032            } catch (RemoteException e) {
11033                Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
11034                if (ordered) {
11035                    r.receiver = null;
11036                    r.curFilter = null;
11037                    filter.receiverList.curBroadcast = null;
11038                    if (filter.receiverList.app != null) {
11039                        filter.receiverList.app.curReceiver = null;
11040                    }
11041                }
11042            }
11043        }
11044    }
11045
11046    private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
11047        if (r.callingUid < 0) {
11048            // This was from a registerReceiver() call; ignore it.
11049            return;
11050        }
11051        System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
11052                MAX_BROADCAST_HISTORY-1);
11053        r.finishTime = SystemClock.uptimeMillis();
11054        mBroadcastHistory[0] = r;
11055    }
11056
11057    private final void processNextBroadcast(boolean fromMsg) {
11058        synchronized(this) {
11059            BroadcastRecord r;
11060
11061            if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
11062                    + mParallelBroadcasts.size() + " broadcasts, "
11063                    + mOrderedBroadcasts.size() + " ordered broadcasts");
11064
11065            updateCpuStats();
11066
11067            if (fromMsg) {
11068                mBroadcastsScheduled = false;
11069            }
11070
11071            // First, deliver any non-serialized broadcasts right away.
11072            while (mParallelBroadcasts.size() > 0) {
11073                r = mParallelBroadcasts.remove(0);
11074                r.dispatchTime = SystemClock.uptimeMillis();
11075                final int N = r.receivers.size();
11076                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
11077                        + r);
11078                for (int i=0; i<N; i++) {
11079                    Object target = r.receivers.get(i);
11080                    if (DEBUG_BROADCAST)  Slog.v(TAG,
11081                            "Delivering non-ordered to registered "
11082                            + target + ": " + r);
11083                    deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
11084                }
11085                addBroadcastToHistoryLocked(r);
11086                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
11087                        + r);
11088            }
11089
11090            // Now take care of the next serialized one...
11091
11092            // If we are waiting for a process to come up to handle the next
11093            // broadcast, then do nothing at this point.  Just in case, we
11094            // check that the process we're waiting for still exists.
11095            if (mPendingBroadcast != null) {
11096                if (DEBUG_BROADCAST_LIGHT) {
11097                    Slog.v(TAG, "processNextBroadcast: waiting for "
11098                            + mPendingBroadcast.curApp);
11099                }
11100
11101                boolean isDead;
11102                synchronized (mPidsSelfLocked) {
11103                    isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
11104                }
11105                if (!isDead) {
11106                    // It's still alive, so keep waiting
11107                    return;
11108                } else {
11109                    Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
11110                            + " died before responding to broadcast");
11111                    mPendingBroadcast.state = BroadcastRecord.IDLE;
11112                    mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
11113                    mPendingBroadcast = null;
11114                }
11115            }
11116
11117            boolean looped = false;
11118
11119            do {
11120                if (mOrderedBroadcasts.size() == 0) {
11121                    // No more broadcasts pending, so all done!
11122                    scheduleAppGcsLocked();
11123                    if (looped) {
11124                        // If we had finished the last ordered broadcast, then
11125                        // make sure all processes have correct oom and sched
11126                        // adjustments.
11127                        updateOomAdjLocked();
11128                    }
11129                    return;
11130                }
11131                r = mOrderedBroadcasts.get(0);
11132                boolean forceReceive = false;
11133
11134                // Ensure that even if something goes awry with the timeout
11135                // detection, we catch "hung" broadcasts here, discard them,
11136                // and continue to make progress.
11137                //
11138                // This is only done if the system is ready so that PRE_BOOT_COMPLETED
11139                // receivers don't get executed with timeouts. They're intended for
11140                // one time heavy lifting after system upgrades and can take
11141                // significant amounts of time.
11142                int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
11143                if (mProcessesReady && r.dispatchTime > 0) {
11144                    long now = SystemClock.uptimeMillis();
11145                    if ((numReceivers > 0) &&
11146                            (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
11147                        Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
11148                                + " now=" + now
11149                                + " dispatchTime=" + r.dispatchTime
11150                                + " startTime=" + r.receiverTime
11151                                + " intent=" + r.intent
11152                                + " numReceivers=" + numReceivers
11153                                + " nextReceiver=" + r.nextReceiver
11154                                + " state=" + r.state);
11155                        broadcastTimeoutLocked(false); // forcibly finish this broadcast
11156                        forceReceive = true;
11157                        r.state = BroadcastRecord.IDLE;
11158                    }
11159                }
11160
11161                if (r.state != BroadcastRecord.IDLE) {
11162                    if (DEBUG_BROADCAST) Slog.d(TAG,
11163                            "processNextBroadcast() called when not idle (state="
11164                            + r.state + ")");
11165                    return;
11166                }
11167
11168                if (r.receivers == null || r.nextReceiver >= numReceivers
11169                        || r.resultAbort || forceReceive) {
11170                    // No more receivers for this broadcast!  Send the final
11171                    // result if requested...
11172                    if (r.resultTo != null) {
11173                        try {
11174                            if (DEBUG_BROADCAST) {
11175                                int seq = r.intent.getIntExtra("seq", -1);
11176                                Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
11177                                        + " seq=" + seq + " app=" + r.callerApp);
11178                            }
11179                            performReceiveLocked(r.callerApp, r.resultTo,
11180                                new Intent(r.intent), r.resultCode,
11181                                r.resultData, r.resultExtras, false, false);
11182                        } catch (RemoteException e) {
11183                            Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
11184                        }
11185                    }
11186
11187                    if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
11188                    cancelBroadcastTimeoutLocked();
11189
11190                    if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
11191                            + r);
11192
11193                    // ... and on to the next...
11194                    addBroadcastToHistoryLocked(r);
11195                    mOrderedBroadcasts.remove(0);
11196                    r = null;
11197                    looped = true;
11198                    continue;
11199                }
11200            } while (r == null);
11201
11202            // Get the next receiver...
11203            int recIdx = r.nextReceiver++;
11204
11205            // Keep track of when this receiver started, and make sure there
11206            // is a timeout message pending to kill it if need be.
11207            r.receiverTime = SystemClock.uptimeMillis();
11208            if (recIdx == 0) {
11209                r.dispatchTime = r.receiverTime;
11210
11211                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
11212                        + r);
11213            }
11214            if (! mPendingBroadcastTimeoutMessage) {
11215                long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11216                if (DEBUG_BROADCAST) Slog.v(TAG,
11217                        "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
11218                setBroadcastTimeoutLocked(timeoutTime);
11219            }
11220
11221            Object nextReceiver = r.receivers.get(recIdx);
11222            if (nextReceiver instanceof BroadcastFilter) {
11223                // Simple case: this is a registered receiver who gets
11224                // a direct call.
11225                BroadcastFilter filter = (BroadcastFilter)nextReceiver;
11226                if (DEBUG_BROADCAST)  Slog.v(TAG,
11227                        "Delivering ordered to registered "
11228                        + filter + ": " + r);
11229                deliverToRegisteredReceiverLocked(r, filter, r.ordered);
11230                if (r.receiver == null || !r.ordered) {
11231                    // The receiver has already finished, so schedule to
11232                    // process the next one.
11233                    if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
11234                            + r.ordered + " receiver=" + r.receiver);
11235                    r.state = BroadcastRecord.IDLE;
11236                    scheduleBroadcastsLocked();
11237                }
11238                return;
11239            }
11240
11241            // Hard case: need to instantiate the receiver, possibly
11242            // starting its application process to host it.
11243
11244            ResolveInfo info =
11245                (ResolveInfo)nextReceiver;
11246
11247            boolean skip = false;
11248            int perm = checkComponentPermission(info.activityInfo.permission,
11249                    r.callingPid, r.callingUid,
11250                    info.activityInfo.exported
11251                            ? -1 : info.activityInfo.applicationInfo.uid);
11252            if (perm != PackageManager.PERMISSION_GRANTED) {
11253                Slog.w(TAG, "Permission Denial: broadcasting "
11254                        + r.intent.toString()
11255                        + " from " + r.callerPackage + " (pid=" + r.callingPid
11256                        + ", uid=" + r.callingUid + ")"
11257                        + " requires " + info.activityInfo.permission
11258                        + " due to receiver " + info.activityInfo.packageName
11259                        + "/" + info.activityInfo.name);
11260                skip = true;
11261            }
11262            if (r.callingUid != Process.SYSTEM_UID &&
11263                r.requiredPermission != null) {
11264                try {
11265                    perm = AppGlobals.getPackageManager().
11266                            checkPermission(r.requiredPermission,
11267                                    info.activityInfo.applicationInfo.packageName);
11268                } catch (RemoteException e) {
11269                    perm = PackageManager.PERMISSION_DENIED;
11270                }
11271                if (perm != PackageManager.PERMISSION_GRANTED) {
11272                    Slog.w(TAG, "Permission Denial: receiving "
11273                            + r.intent + " to "
11274                            + info.activityInfo.applicationInfo.packageName
11275                            + " requires " + r.requiredPermission
11276                            + " due to sender " + r.callerPackage
11277                            + " (uid " + r.callingUid + ")");
11278                    skip = true;
11279                }
11280            }
11281            if (r.curApp != null && r.curApp.crashing) {
11282                // If the target process is crashing, just skip it.
11283                if (DEBUG_BROADCAST)  Slog.v(TAG,
11284                        "Skipping deliver ordered " + r + " to " + r.curApp
11285                        + ": process crashing");
11286                skip = true;
11287            }
11288
11289            if (skip) {
11290                if (DEBUG_BROADCAST)  Slog.v(TAG,
11291                        "Skipping delivery of ordered " + r + " for whatever reason");
11292                r.receiver = null;
11293                r.curFilter = null;
11294                r.state = BroadcastRecord.IDLE;
11295                scheduleBroadcastsLocked();
11296                return;
11297            }
11298
11299            r.state = BroadcastRecord.APP_RECEIVE;
11300            String targetProcess = info.activityInfo.processName;
11301            r.curComponent = new ComponentName(
11302                    info.activityInfo.applicationInfo.packageName,
11303                    info.activityInfo.name);
11304            r.curReceiver = info.activityInfo;
11305
11306            // Is this receiver's application already running?
11307            ProcessRecord app = getProcessRecordLocked(targetProcess,
11308                    info.activityInfo.applicationInfo.uid);
11309            if (app != null && app.thread != null) {
11310                try {
11311                    processCurBroadcastLocked(r, app);
11312                    return;
11313                } catch (RemoteException e) {
11314                    Slog.w(TAG, "Exception when sending broadcast to "
11315                          + r.curComponent, e);
11316                }
11317
11318                // If a dead object exception was thrown -- fall through to
11319                // restart the application.
11320            }
11321
11322            // Not running -- get it started, to be executed when the app comes up.
11323            if (DEBUG_BROADCAST)  Slog.v(TAG,
11324                    "Need to start app " + targetProcess + " for broadcast " + r);
11325            if ((r.curApp=startProcessLocked(targetProcess,
11326                    info.activityInfo.applicationInfo, true,
11327                    r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
11328                    "broadcast", r.curComponent,
11329                    (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
11330                            == null) {
11331                // Ah, this recipient is unavailable.  Finish it if necessary,
11332                // and mark the broadcast record as ready for the next.
11333                Slog.w(TAG, "Unable to launch app "
11334                        + info.activityInfo.applicationInfo.packageName + "/"
11335                        + info.activityInfo.applicationInfo.uid + " for broadcast "
11336                        + r.intent + ": process is bad");
11337                logBroadcastReceiverDiscardLocked(r);
11338                finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11339                        r.resultExtras, r.resultAbort, true);
11340                scheduleBroadcastsLocked();
11341                r.state = BroadcastRecord.IDLE;
11342                return;
11343            }
11344
11345            mPendingBroadcast = r;
11346            mPendingBroadcastRecvIndex = recIdx;
11347        }
11348    }
11349
11350    // =========================================================
11351    // INSTRUMENTATION
11352    // =========================================================
11353
11354    public boolean startInstrumentation(ComponentName className,
11355            String profileFile, int flags, Bundle arguments,
11356            IInstrumentationWatcher watcher) {
11357        // Refuse possible leaked file descriptors
11358        if (arguments != null && arguments.hasFileDescriptors()) {
11359            throw new IllegalArgumentException("File descriptors passed in Bundle");
11360        }
11361
11362        synchronized(this) {
11363            InstrumentationInfo ii = null;
11364            ApplicationInfo ai = null;
11365            try {
11366                ii = mContext.getPackageManager().getInstrumentationInfo(
11367                    className, STOCK_PM_FLAGS);
11368                ai = mContext.getPackageManager().getApplicationInfo(
11369                    ii.targetPackage, STOCK_PM_FLAGS);
11370            } catch (PackageManager.NameNotFoundException e) {
11371            }
11372            if (ii == null) {
11373                reportStartInstrumentationFailure(watcher, className,
11374                        "Unable to find instrumentation info for: " + className);
11375                return false;
11376            }
11377            if (ai == null) {
11378                reportStartInstrumentationFailure(watcher, className,
11379                        "Unable to find instrumentation target package: " + ii.targetPackage);
11380                return false;
11381            }
11382
11383            int match = mContext.getPackageManager().checkSignatures(
11384                    ii.targetPackage, ii.packageName);
11385            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11386                String msg = "Permission Denial: starting instrumentation "
11387                        + className + " from pid="
11388                        + Binder.getCallingPid()
11389                        + ", uid=" + Binder.getCallingPid()
11390                        + " not allowed because package " + ii.packageName
11391                        + " does not have a signature matching the target "
11392                        + ii.targetPackage;
11393                reportStartInstrumentationFailure(watcher, className, msg);
11394                throw new SecurityException(msg);
11395            }
11396
11397            final long origId = Binder.clearCallingIdentity();
11398            forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
11399            ProcessRecord app = addAppLocked(ai);
11400            app.instrumentationClass = className;
11401            app.instrumentationInfo = ai;
11402            app.instrumentationProfileFile = profileFile;
11403            app.instrumentationArguments = arguments;
11404            app.instrumentationWatcher = watcher;
11405            app.instrumentationResultClass = className;
11406            Binder.restoreCallingIdentity(origId);
11407        }
11408
11409        return true;
11410    }
11411
11412    /**
11413     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11414     * error to the logs, but if somebody is watching, send the report there too.  This enables
11415     * the "am" command to report errors with more information.
11416     *
11417     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11418     * @param cn The component name of the instrumentation.
11419     * @param report The error report.
11420     */
11421    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11422            ComponentName cn, String report) {
11423        Slog.w(TAG, report);
11424        try {
11425            if (watcher != null) {
11426                Bundle results = new Bundle();
11427                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11428                results.putString("Error", report);
11429                watcher.instrumentationStatus(cn, -1, results);
11430            }
11431        } catch (RemoteException e) {
11432            Slog.w(TAG, e);
11433        }
11434    }
11435
11436    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11437        if (app.instrumentationWatcher != null) {
11438            try {
11439                // NOTE:  IInstrumentationWatcher *must* be oneway here
11440                app.instrumentationWatcher.instrumentationFinished(
11441                    app.instrumentationClass,
11442                    resultCode,
11443                    results);
11444            } catch (RemoteException e) {
11445            }
11446        }
11447        app.instrumentationWatcher = null;
11448        app.instrumentationClass = null;
11449        app.instrumentationInfo = null;
11450        app.instrumentationProfileFile = null;
11451        app.instrumentationArguments = null;
11452
11453        forceStopPackageLocked(app.processName, -1, false, false, true);
11454    }
11455
11456    public void finishInstrumentation(IApplicationThread target,
11457            int resultCode, Bundle results) {
11458        // Refuse possible leaked file descriptors
11459        if (results != null && results.hasFileDescriptors()) {
11460            throw new IllegalArgumentException("File descriptors passed in Intent");
11461        }
11462
11463        synchronized(this) {
11464            ProcessRecord app = getRecordForAppLocked(target);
11465            if (app == null) {
11466                Slog.w(TAG, "finishInstrumentation: no app for " + target);
11467                return;
11468            }
11469            final long origId = Binder.clearCallingIdentity();
11470            finishInstrumentationLocked(app, resultCode, results);
11471            Binder.restoreCallingIdentity(origId);
11472        }
11473    }
11474
11475    // =========================================================
11476    // CONFIGURATION
11477    // =========================================================
11478
11479    public ConfigurationInfo getDeviceConfigurationInfo() {
11480        ConfigurationInfo config = new ConfigurationInfo();
11481        synchronized (this) {
11482            config.reqTouchScreen = mConfiguration.touchscreen;
11483            config.reqKeyboardType = mConfiguration.keyboard;
11484            config.reqNavigation = mConfiguration.navigation;
11485            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11486                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
11487                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11488            }
11489            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11490                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
11491                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11492            }
11493            config.reqGlEsVersion = GL_ES_VERSION;
11494        }
11495        return config;
11496    }
11497
11498    public Configuration getConfiguration() {
11499        Configuration ci;
11500        synchronized(this) {
11501            ci = new Configuration(mConfiguration);
11502        }
11503        return ci;
11504    }
11505
11506    public void updateConfiguration(Configuration values) {
11507        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11508                "updateConfiguration()");
11509
11510        synchronized(this) {
11511            if (values == null && mWindowManager != null) {
11512                // sentinel: fetch the current configuration from the window manager
11513                values = mWindowManager.computeNewConfiguration();
11514            }
11515
11516            final long origId = Binder.clearCallingIdentity();
11517            updateConfigurationLocked(values, null);
11518            Binder.restoreCallingIdentity(origId);
11519        }
11520    }
11521
11522    /**
11523     * Do either or both things: (1) change the current configuration, and (2)
11524     * make sure the given activity is running with the (now) current
11525     * configuration.  Returns true if the activity has been left running, or
11526     * false if <var>starting</var> is being destroyed to match the new
11527     * configuration.
11528     */
11529    public boolean updateConfigurationLocked(Configuration values,
11530            ActivityRecord starting) {
11531        int changes = 0;
11532
11533        boolean kept = true;
11534
11535        if (values != null) {
11536            Configuration newConfig = new Configuration(mConfiguration);
11537            changes = newConfig.updateFrom(values);
11538            if (changes != 0) {
11539                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
11540                    Slog.i(TAG, "Updating configuration to: " + values);
11541                }
11542
11543                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
11544
11545                if (values.locale != null) {
11546                    saveLocaleLocked(values.locale,
11547                                     !values.locale.equals(mConfiguration.locale),
11548                                     values.userSetLocale);
11549                }
11550
11551                mConfigurationSeq++;
11552                if (mConfigurationSeq <= 0) {
11553                    mConfigurationSeq = 1;
11554                }
11555                newConfig.seq = mConfigurationSeq;
11556                mConfiguration = newConfig;
11557                Slog.i(TAG, "Config changed: " + newConfig);
11558
11559                AttributeCache ac = AttributeCache.instance();
11560                if (ac != null) {
11561                    ac.updateConfiguration(mConfiguration);
11562                }
11563
11564                if (Settings.System.hasInterestingConfigurationChanges(changes)) {
11565                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11566                    msg.obj = new Configuration(mConfiguration);
11567                    mHandler.sendMessage(msg);
11568                }
11569
11570                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11571                    ProcessRecord app = mLruProcesses.get(i);
11572                    try {
11573                        if (app.thread != null) {
11574                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
11575                                    + app.processName + " new config " + mConfiguration);
11576                            app.thread.scheduleConfigurationChanged(mConfiguration);
11577                        }
11578                    } catch (Exception e) {
11579                    }
11580                }
11581                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
11582                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11583                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
11584                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11585                        null, false, false, MY_PID, Process.SYSTEM_UID);
11586                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
11587                    broadcastIntentLocked(null, null,
11588                            new Intent(Intent.ACTION_LOCALE_CHANGED),
11589                            null, null, 0, null, null,
11590                            null, false, false, MY_PID, Process.SYSTEM_UID);
11591                }
11592            }
11593        }
11594
11595        if (changes != 0 && starting == null) {
11596            // If the configuration changed, and the caller is not already
11597            // in the process of starting an activity, then find the top
11598            // activity to check if its configuration needs to change.
11599            starting = mMainStack.topRunningActivityLocked(null);
11600        }
11601
11602        if (starting != null) {
11603            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
11604            if (kept) {
11605                // If this didn't result in the starting activity being
11606                // destroyed, then we need to make sure at this point that all
11607                // other activities are made visible.
11608                if (DEBUG_SWITCH) Slog.i(TAG, "Config didn't destroy " + starting
11609                        + ", ensuring others are correct.");
11610                mMainStack.ensureActivitiesVisibleLocked(starting, changes);
11611            }
11612        }
11613
11614        if (values != null && mWindowManager != null) {
11615            mWindowManager.setNewConfiguration(mConfiguration);
11616        }
11617
11618        return kept;
11619    }
11620
11621    /**
11622     * Save the locale.  You must be inside a synchronized (this) block.
11623     */
11624    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
11625        if(isDiff) {
11626            SystemProperties.set("user.language", l.getLanguage());
11627            SystemProperties.set("user.region", l.getCountry());
11628        }
11629
11630        if(isPersist) {
11631            SystemProperties.set("persist.sys.language", l.getLanguage());
11632            SystemProperties.set("persist.sys.country", l.getCountry());
11633            SystemProperties.set("persist.sys.localevar", l.getVariant());
11634        }
11635    }
11636
11637    // =========================================================
11638    // LIFETIME MANAGEMENT
11639    // =========================================================
11640
11641    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
11642            ProcessRecord TOP_APP, boolean recursed) {
11643        if (mAdjSeq == app.adjSeq) {
11644            // This adjustment has already been computed.  If we are calling
11645            // from the top, we may have already computed our adjustment with
11646            // an earlier hidden adjustment that isn't really for us... if
11647            // so, use the new hidden adjustment.
11648            if (!recursed && app.hidden) {
11649                app.curAdj = hiddenAdj;
11650            }
11651            return app.curAdj;
11652        }
11653
11654        if (app.thread == null) {
11655            app.adjSeq = mAdjSeq;
11656            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
11657            return (app.curAdj=EMPTY_APP_ADJ);
11658        }
11659
11660        if (app.maxAdj <= FOREGROUND_APP_ADJ) {
11661            // The max adjustment doesn't allow this app to be anything
11662            // below foreground, so it is not worth doing work for it.
11663            app.adjType = "fixed";
11664            app.adjSeq = mAdjSeq;
11665            app.curRawAdj = app.maxAdj;
11666            app.keeping = true;
11667            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
11668            return (app.curAdj=app.maxAdj);
11669       }
11670
11671        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
11672        app.adjSource = null;
11673        app.adjTarget = null;
11674        app.keeping = false;
11675        app.empty = false;
11676        app.hidden = false;
11677
11678        // Determine the importance of the process, starting with most
11679        // important to least, and assign an appropriate OOM adjustment.
11680        int adj;
11681        int schedGroup;
11682        int N;
11683        if (app == TOP_APP) {
11684            // The last app on the list is the foreground app.
11685            adj = FOREGROUND_APP_ADJ;
11686            schedGroup = Process.THREAD_GROUP_DEFAULT;
11687            app.adjType = "top-activity";
11688        } else if (app.instrumentationClass != null) {
11689            // Don't want to kill running instrumentation.
11690            adj = FOREGROUND_APP_ADJ;
11691            schedGroup = Process.THREAD_GROUP_DEFAULT;
11692            app.adjType = "instrumentation";
11693        } else if (app.curReceiver != null ||
11694                (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
11695            // An app that is currently receiving a broadcast also
11696            // counts as being in the foreground.
11697            adj = FOREGROUND_APP_ADJ;
11698            schedGroup = Process.THREAD_GROUP_DEFAULT;
11699            app.adjType = "broadcast";
11700        } else if (app.executingServices.size() > 0) {
11701            // An app that is currently executing a service callback also
11702            // counts as being in the foreground.
11703            adj = FOREGROUND_APP_ADJ;
11704            schedGroup = Process.THREAD_GROUP_DEFAULT;
11705            app.adjType = "exec-service";
11706        } else if (app.foregroundServices) {
11707            // The user is aware of this app, so make it visible.
11708            adj = PERCEPTIBLE_APP_ADJ;
11709            schedGroup = Process.THREAD_GROUP_DEFAULT;
11710            app.adjType = "foreground-service";
11711        } else if (app.forcingToForeground != null) {
11712            // The user is aware of this app, so make it visible.
11713            adj = PERCEPTIBLE_APP_ADJ;
11714            schedGroup = Process.THREAD_GROUP_DEFAULT;
11715            app.adjType = "force-foreground";
11716            app.adjSource = app.forcingToForeground;
11717        } else if (app == mHeavyWeightProcess) {
11718            // We don't want to kill the current heavy-weight process.
11719            adj = HEAVY_WEIGHT_APP_ADJ;
11720            schedGroup = Process.THREAD_GROUP_DEFAULT;
11721            app.adjType = "heavy";
11722        } else if (app == mHomeProcess) {
11723            // This process is hosting what we currently consider to be the
11724            // home app, so we don't want to let it go into the background.
11725            adj = HOME_APP_ADJ;
11726            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
11727            app.adjType = "home";
11728        } else if ((N=app.activities.size()) != 0) {
11729            // This app is in the background with paused activities.
11730            app.hidden = true;
11731            adj = hiddenAdj;
11732            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
11733            app.adjType = "bg-activities";
11734            N = app.activities.size();
11735            for (int j=0; j<N; j++) {
11736                if (app.activities.get(j).visible) {
11737                    // This app has a visible activity!
11738                    app.hidden = false;
11739                    adj = VISIBLE_APP_ADJ;
11740                    schedGroup = Process.THREAD_GROUP_DEFAULT;
11741                    app.adjType = "visible";
11742                    break;
11743                }
11744            }
11745        } else {
11746            // A very not-needed process.  If this is lower in the lru list,
11747            // we will push it in to the empty bucket.
11748            app.hidden = true;
11749            app.empty = true;
11750            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
11751            adj = hiddenAdj;
11752            app.adjType = "bg-empty";
11753        }
11754
11755        //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
11756
11757        // By default, we use the computed adjustment.  It may be changed if
11758        // there are applications dependent on our services or providers, but
11759        // this gives us a baseline and makes sure we don't get into an
11760        // infinite recursion.
11761        app.adjSeq = mAdjSeq;
11762        app.curRawAdj = adj;
11763
11764        if (mBackupTarget != null && app == mBackupTarget.app) {
11765            // If possible we want to avoid killing apps while they're being backed up
11766            if (adj > BACKUP_APP_ADJ) {
11767                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
11768                adj = BACKUP_APP_ADJ;
11769                app.adjType = "backup";
11770                app.hidden = false;
11771            }
11772        }
11773
11774        if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
11775                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
11776            final long now = SystemClock.uptimeMillis();
11777            // This process is more important if the top activity is
11778            // bound to the service.
11779            Iterator<ServiceRecord> jt = app.services.iterator();
11780            while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
11781                ServiceRecord s = jt.next();
11782                if (s.startRequested) {
11783                    if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
11784                        // This service has seen some activity within
11785                        // recent memory, so we will keep its process ahead
11786                        // of the background processes.
11787                        if (adj > SECONDARY_SERVER_ADJ) {
11788                            adj = SECONDARY_SERVER_ADJ;
11789                            app.adjType = "started-services";
11790                            app.hidden = false;
11791                        }
11792                    }
11793                    // If we have let the service slide into the background
11794                    // state, still have some text describing what it is doing
11795                    // even though the service no longer has an impact.
11796                    if (adj > SECONDARY_SERVER_ADJ) {
11797                        app.adjType = "started-bg-services";
11798                    }
11799                    // Don't kill this process because it is doing work; it
11800                    // has said it is doing work.
11801                    app.keeping = true;
11802                }
11803                if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
11804                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
11805                    Iterator<ArrayList<ConnectionRecord>> kt
11806                            = s.connections.values().iterator();
11807                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
11808                        ArrayList<ConnectionRecord> clist = kt.next();
11809                        for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
11810                            // XXX should compute this based on the max of
11811                            // all connected clients.
11812                            ConnectionRecord cr = clist.get(i);
11813                            if (cr.binding.client == app) {
11814                                // Binding to ourself is not interesting.
11815                                continue;
11816                            }
11817                            if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
11818                                ProcessRecord client = cr.binding.client;
11819                                int myHiddenAdj = hiddenAdj;
11820                                if (myHiddenAdj > client.hiddenAdj) {
11821                                    if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
11822                                        myHiddenAdj = client.hiddenAdj;
11823                                    } else {
11824                                        myHiddenAdj = VISIBLE_APP_ADJ;
11825                                    }
11826                                }
11827                                int clientAdj = computeOomAdjLocked(
11828                                    client, myHiddenAdj, TOP_APP, true);
11829                                if (adj > clientAdj) {
11830                                    adj = clientAdj >= VISIBLE_APP_ADJ
11831                                            ? clientAdj : VISIBLE_APP_ADJ;
11832                                    if (!client.hidden) {
11833                                        app.hidden = false;
11834                                    }
11835                                    if (client.keeping) {
11836                                        app.keeping = true;
11837                                    }
11838                                    app.adjType = "service";
11839                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
11840                                            .REASON_SERVICE_IN_USE;
11841                                    app.adjSource = cr.binding.client;
11842                                    app.adjTarget = s.name;
11843                                }
11844                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
11845                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
11846                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
11847                                    }
11848                                }
11849                            }
11850                            ActivityRecord a = cr.activity;
11851                            //if (a != null) {
11852                            //    Slog.i(TAG, "Connection to " + a ": state=" + a.state);
11853                            //}
11854                            if (a != null && adj > FOREGROUND_APP_ADJ &&
11855                                    (a.state == ActivityState.RESUMED
11856                                     || a.state == ActivityState.PAUSING)) {
11857                                adj = FOREGROUND_APP_ADJ;
11858                                schedGroup = Process.THREAD_GROUP_DEFAULT;
11859                                app.hidden = false;
11860                                app.adjType = "service";
11861                                app.adjTypeCode = ActivityManager.RunningAppProcessInfo
11862                                        .REASON_SERVICE_IN_USE;
11863                                app.adjSource = a;
11864                                app.adjTarget = s.name;
11865                            }
11866                        }
11867                    }
11868                }
11869            }
11870
11871            // Finally, if this process has active services running in it, we
11872            // would like to avoid killing it unless it would prevent the current
11873            // application from running.  By default we put the process in
11874            // with the rest of the background processes; as we scan through
11875            // its services we may bump it up from there.
11876            if (adj > hiddenAdj) {
11877                adj = hiddenAdj;
11878                app.hidden = false;
11879                app.adjType = "bg-services";
11880            }
11881        }
11882
11883        if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
11884                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
11885            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
11886            while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
11887                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
11888                ContentProviderRecord cpr = jt.next();
11889                if (cpr.clients.size() != 0) {
11890                    Iterator<ProcessRecord> kt = cpr.clients.iterator();
11891                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
11892                        ProcessRecord client = kt.next();
11893                        if (client == app) {
11894                            // Being our own client is not interesting.
11895                            continue;
11896                        }
11897                        int myHiddenAdj = hiddenAdj;
11898                        if (myHiddenAdj > client.hiddenAdj) {
11899                            if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
11900                                myHiddenAdj = client.hiddenAdj;
11901                            } else {
11902                                myHiddenAdj = FOREGROUND_APP_ADJ;
11903                            }
11904                        }
11905                        int clientAdj = computeOomAdjLocked(
11906                            client, myHiddenAdj, TOP_APP, true);
11907                        if (adj > clientAdj) {
11908                            adj = clientAdj > FOREGROUND_APP_ADJ
11909                                    ? clientAdj : FOREGROUND_APP_ADJ;
11910                            if (!client.hidden) {
11911                                app.hidden = false;
11912                            }
11913                            if (client.keeping) {
11914                                app.keeping = true;
11915                            }
11916                            app.adjType = "provider";
11917                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
11918                                    .REASON_PROVIDER_IN_USE;
11919                            app.adjSource = client;
11920                            app.adjTarget = cpr.name;
11921                        }
11922                        if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
11923                            schedGroup = Process.THREAD_GROUP_DEFAULT;
11924                        }
11925                    }
11926                }
11927                // If the provider has external (non-framework) process
11928                // dependencies, ensure that its adjustment is at least
11929                // FOREGROUND_APP_ADJ.
11930                if (cpr.externals != 0) {
11931                    if (adj > FOREGROUND_APP_ADJ) {
11932                        adj = FOREGROUND_APP_ADJ;
11933                        schedGroup = Process.THREAD_GROUP_DEFAULT;
11934                        app.hidden = false;
11935                        app.keeping = true;
11936                        app.adjType = "provider";
11937                        app.adjTarget = cpr.name;
11938                    }
11939                }
11940            }
11941        }
11942
11943        app.curRawAdj = adj;
11944
11945        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
11946        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
11947        if (adj > app.maxAdj) {
11948            adj = app.maxAdj;
11949            if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
11950                schedGroup = Process.THREAD_GROUP_DEFAULT;
11951            }
11952        }
11953        if (adj < HIDDEN_APP_MIN_ADJ) {
11954            app.keeping = true;
11955        }
11956
11957        app.curAdj = adj;
11958        app.curSchedGroup = schedGroup;
11959
11960        return adj;
11961    }
11962
11963    /**
11964     * Ask a given process to GC right now.
11965     */
11966    final void performAppGcLocked(ProcessRecord app) {
11967        try {
11968            app.lastRequestedGc = SystemClock.uptimeMillis();
11969            if (app.thread != null) {
11970                if (app.reportLowMemory) {
11971                    app.reportLowMemory = false;
11972                    app.thread.scheduleLowMemory();
11973                } else {
11974                    app.thread.processInBackground();
11975                }
11976            }
11977        } catch (Exception e) {
11978            // whatever.
11979        }
11980    }
11981
11982    /**
11983     * Returns true if things are idle enough to perform GCs.
11984     */
11985    private final boolean canGcNowLocked() {
11986        return mParallelBroadcasts.size() == 0
11987                && mOrderedBroadcasts.size() == 0
11988                && (mSleeping || (mMainStack.mResumedActivity != null &&
11989                        mMainStack.mResumedActivity.idle));
11990    }
11991
11992    /**
11993     * Perform GCs on all processes that are waiting for it, but only
11994     * if things are idle.
11995     */
11996    final void performAppGcsLocked() {
11997        final int N = mProcessesToGc.size();
11998        if (N <= 0) {
11999            return;
12000        }
12001        if (canGcNowLocked()) {
12002            while (mProcessesToGc.size() > 0) {
12003                ProcessRecord proc = mProcessesToGc.remove(0);
12004                if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
12005                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12006                            <= SystemClock.uptimeMillis()) {
12007                        // To avoid spamming the system, we will GC processes one
12008                        // at a time, waiting a few seconds between each.
12009                        performAppGcLocked(proc);
12010                        scheduleAppGcsLocked();
12011                        return;
12012                    } else {
12013                        // It hasn't been long enough since we last GCed this
12014                        // process...  put it in the list to wait for its time.
12015                        addProcessToGcListLocked(proc);
12016                        break;
12017                    }
12018                }
12019            }
12020
12021            scheduleAppGcsLocked();
12022        }
12023    }
12024
12025    /**
12026     * If all looks good, perform GCs on all processes waiting for them.
12027     */
12028    final void performAppGcsIfAppropriateLocked() {
12029        if (canGcNowLocked()) {
12030            performAppGcsLocked();
12031            return;
12032        }
12033        // Still not idle, wait some more.
12034        scheduleAppGcsLocked();
12035    }
12036
12037    /**
12038     * Schedule the execution of all pending app GCs.
12039     */
12040    final void scheduleAppGcsLocked() {
12041        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
12042
12043        if (mProcessesToGc.size() > 0) {
12044            // Schedule a GC for the time to the next process.
12045            ProcessRecord proc = mProcessesToGc.get(0);
12046            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12047
12048            long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
12049            long now = SystemClock.uptimeMillis();
12050            if (when < (now+GC_TIMEOUT)) {
12051                when = now + GC_TIMEOUT;
12052            }
12053            mHandler.sendMessageAtTime(msg, when);
12054        }
12055    }
12056
12057    /**
12058     * Add a process to the array of processes waiting to be GCed.  Keeps the
12059     * list in sorted order by the last GC time.  The process can't already be
12060     * on the list.
12061     */
12062    final void addProcessToGcListLocked(ProcessRecord proc) {
12063        boolean added = false;
12064        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12065            if (mProcessesToGc.get(i).lastRequestedGc <
12066                    proc.lastRequestedGc) {
12067                added = true;
12068                mProcessesToGc.add(i+1, proc);
12069                break;
12070            }
12071        }
12072        if (!added) {
12073            mProcessesToGc.add(0, proc);
12074        }
12075    }
12076
12077    /**
12078     * Set up to ask a process to GC itself.  This will either do it
12079     * immediately, or put it on the list of processes to gc the next
12080     * time things are idle.
12081     */
12082    final void scheduleAppGcLocked(ProcessRecord app) {
12083        long now = SystemClock.uptimeMillis();
12084        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
12085            return;
12086        }
12087        if (!mProcessesToGc.contains(app)) {
12088            addProcessToGcListLocked(app);
12089            scheduleAppGcsLocked();
12090        }
12091    }
12092
12093    final void checkExcessivePowerUsageLocked(boolean doKills) {
12094        updateCpuStatsNow();
12095
12096        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12097        boolean doWakeKills = doKills;
12098        boolean doCpuKills = doKills;
12099        if (mLastPowerCheckRealtime == 0) {
12100            doWakeKills = false;
12101        }
12102        if (mLastPowerCheckUptime == 0) {
12103            doCpuKills = false;
12104        }
12105        if (stats.isScreenOn()) {
12106            doWakeKills = false;
12107        }
12108        final long curRealtime = SystemClock.elapsedRealtime();
12109        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12110        final long curUptime = SystemClock.uptimeMillis();
12111        final long uptimeSince = curUptime - mLastPowerCheckUptime;
12112        mLastPowerCheckRealtime = curRealtime;
12113        mLastPowerCheckUptime = curUptime;
12114        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12115            doWakeKills = false;
12116        }
12117        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12118            doCpuKills = false;
12119        }
12120        int i = mLruProcesses.size();
12121        while (i > 0) {
12122            i--;
12123            ProcessRecord app = mLruProcesses.get(i);
12124            if (!app.keeping) {
12125                long wtime;
12126                synchronized (stats) {
12127                    wtime = stats.getProcessWakeTime(app.info.uid,
12128                            app.pid, curRealtime);
12129                }
12130                long wtimeUsed = wtime - app.lastWakeTime;
12131                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12132                if (DEBUG_POWER) {
12133                    StringBuilder sb = new StringBuilder(128);
12134                    sb.append("Wake for ");
12135                    app.toShortString(sb);
12136                    sb.append(": over ");
12137                    TimeUtils.formatDuration(realtimeSince, sb);
12138                    sb.append(" used ");
12139                    TimeUtils.formatDuration(wtimeUsed, sb);
12140                    sb.append(" (");
12141                    sb.append((wtimeUsed*100)/realtimeSince);
12142                    sb.append("%)");
12143                    Slog.i(TAG, sb.toString());
12144                    sb.setLength(0);
12145                    sb.append("CPU for ");
12146                    app.toShortString(sb);
12147                    sb.append(": over ");
12148                    TimeUtils.formatDuration(uptimeSince, sb);
12149                    sb.append(" used ");
12150                    TimeUtils.formatDuration(cputimeUsed, sb);
12151                    sb.append(" (");
12152                    sb.append((cputimeUsed*100)/uptimeSince);
12153                    sb.append("%)");
12154                    Slog.i(TAG, sb.toString());
12155                }
12156                // If a process has held a wake lock for more
12157                // than 50% of the time during this period,
12158                // that sounds pad.  Kill!
12159                if (doWakeKills && realtimeSince > 0
12160                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
12161                    synchronized (stats) {
12162                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12163                                realtimeSince, wtimeUsed);
12164                    }
12165                    Slog.w(TAG, "Excessive wake lock in " + app.processName
12166                            + " (pid " + app.pid + "): held " + wtimeUsed
12167                            + " during " + realtimeSince);
12168                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12169                            app.processName, app.setAdj, "excessive wake lock");
12170                    Process.killProcessQuiet(app.pid);
12171                } else if (doCpuKills && uptimeSince > 0
12172                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
12173                    synchronized (stats) {
12174                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12175                                uptimeSince, cputimeUsed);
12176                    }
12177                    Slog.w(TAG, "Excessive CPU in " + app.processName
12178                            + " (pid " + app.pid + "): used " + cputimeUsed
12179                            + " during " + uptimeSince);
12180                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12181                            app.processName, app.setAdj, "excessive cpu");
12182                    Process.killProcessQuiet(app.pid);
12183                } else {
12184                    app.lastWakeTime = wtime;
12185                    app.lastCpuTime = app.curCpuTime;
12186                }
12187            }
12188        }
12189    }
12190
12191    private final boolean updateOomAdjLocked(
12192        ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
12193        app.hiddenAdj = hiddenAdj;
12194
12195        if (app.thread == null) {
12196            return true;
12197        }
12198
12199        final boolean wasKeeping = app.keeping;
12200
12201        int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
12202
12203        if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
12204            if (app.curRawAdj != app.setRawAdj) {
12205                if (app.curRawAdj > FOREGROUND_APP_ADJ
12206                        && app.setRawAdj <= FOREGROUND_APP_ADJ) {
12207                    // If this app is transitioning from foreground to
12208                    // non-foreground, have it do a gc.
12209                    scheduleAppGcLocked(app);
12210                } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
12211                        && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
12212                    // Likewise do a gc when an app is moving in to the
12213                    // background (such as a service stopping).
12214                    scheduleAppGcLocked(app);
12215                }
12216
12217                if (wasKeeping && !app.keeping) {
12218                    // This app is no longer something we want to keep.  Note
12219                    // its current wake lock time to later know to kill it if
12220                    // it is not behaving well.
12221                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12222                    synchronized (stats) {
12223                        app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12224                                app.pid, SystemClock.elapsedRealtime());
12225                    }
12226                    app.lastCpuTime = app.curCpuTime;
12227                }
12228
12229                app.setRawAdj = app.curRawAdj;
12230            }
12231            if (adj != app.setAdj) {
12232                if (Process.setOomAdj(app.pid, adj)) {
12233                    if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
12234                        TAG, "Set app " + app.processName +
12235                        " oom adj to " + adj);
12236                    app.setAdj = adj;
12237                } else {
12238                    return false;
12239                }
12240            }
12241            if (app.setSchedGroup != app.curSchedGroup) {
12242                app.setSchedGroup = app.curSchedGroup;
12243                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
12244                        "Setting process group of " + app.processName
12245                        + " to " + app.curSchedGroup);
12246                if (true) {
12247                    long oldId = Binder.clearCallingIdentity();
12248                    try {
12249                        Process.setProcessGroup(app.pid, app.curSchedGroup);
12250                    } catch (Exception e) {
12251                        Slog.w(TAG, "Failed setting process group of " + app.pid
12252                                + " to " + app.curSchedGroup);
12253                        e.printStackTrace();
12254                    } finally {
12255                        Binder.restoreCallingIdentity(oldId);
12256                    }
12257                }
12258                if (false) {
12259                    if (app.thread != null) {
12260                        try {
12261                            app.thread.setSchedulingGroup(app.curSchedGroup);
12262                        } catch (RemoteException e) {
12263                        }
12264                    }
12265                }
12266            }
12267        }
12268
12269        return true;
12270    }
12271
12272    private final ActivityRecord resumedAppLocked() {
12273        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
12274        if (resumedActivity == null || resumedActivity.app == null) {
12275            resumedActivity = mMainStack.mPausingActivity;
12276            if (resumedActivity == null || resumedActivity.app == null) {
12277                resumedActivity = mMainStack.topRunningActivityLocked(null);
12278            }
12279        }
12280        return resumedActivity;
12281    }
12282
12283    private final boolean updateOomAdjLocked(ProcessRecord app) {
12284        final ActivityRecord TOP_ACT = resumedAppLocked();
12285        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12286        int curAdj = app.curAdj;
12287        final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
12288            && app.curAdj <= HIDDEN_APP_MAX_ADJ;
12289
12290        mAdjSeq++;
12291
12292        final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
12293        if (res) {
12294            final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
12295                && app.curAdj <= HIDDEN_APP_MAX_ADJ;
12296            if (nowHidden != wasHidden) {
12297                // Changed to/from hidden state, so apps after it in the LRU
12298                // list may also be changed.
12299                updateOomAdjLocked();
12300            }
12301        }
12302        return res;
12303    }
12304
12305    final boolean updateOomAdjLocked() {
12306        boolean didOomAdj = true;
12307        final ActivityRecord TOP_ACT = resumedAppLocked();
12308        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12309
12310        if (false) {
12311            RuntimeException e = new RuntimeException();
12312            e.fillInStackTrace();
12313            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
12314        }
12315
12316        mAdjSeq++;
12317
12318        // Let's determine how many processes we have running vs.
12319        // how many slots we have for background processes; we may want
12320        // to put multiple processes in a slot of there are enough of
12321        // them.
12322        int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
12323        int factor = (mLruProcesses.size()-4)/numSlots;
12324        if (factor < 1) factor = 1;
12325        int step = 0;
12326        int numHidden = 0;
12327
12328        // First try updating the OOM adjustment for each of the
12329        // application processes based on their current state.
12330        int i = mLruProcesses.size();
12331        int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
12332        while (i > 0) {
12333            i--;
12334            ProcessRecord app = mLruProcesses.get(i);
12335            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
12336            if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
12337                if (curHiddenAdj < EMPTY_APP_ADJ
12338                    && app.curAdj == curHiddenAdj) {
12339                    step++;
12340                    if (step >= factor) {
12341                        step = 0;
12342                        curHiddenAdj++;
12343                    }
12344                }
12345                if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
12346                    if (!app.killedBackground) {
12347                        numHidden++;
12348                        if (numHidden > MAX_HIDDEN_APPS) {
12349                            Slog.i(TAG, "No longer want " + app.processName
12350                                    + " (pid " + app.pid + "): hidden #" + numHidden);
12351                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12352                                    app.processName, app.setAdj, "too many background");
12353                            app.killedBackground = true;
12354                            Process.killProcessQuiet(app.pid);
12355                        }
12356                    }
12357                }
12358            } else {
12359                didOomAdj = false;
12360            }
12361        }
12362
12363        // If we return false, we will fall back on killing processes to
12364        // have a fixed limit.  Do this if a limit has been requested; else
12365        // only return false if one of the adjustments failed.
12366        return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
12367    }
12368
12369    final void trimApplications() {
12370        synchronized (this) {
12371            int i;
12372
12373            // First remove any unused application processes whose package
12374            // has been removed.
12375            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
12376                final ProcessRecord app = mRemovedProcesses.get(i);
12377                if (app.activities.size() == 0
12378                        && app.curReceiver == null && app.services.size() == 0) {
12379                    Slog.i(
12380                        TAG, "Exiting empty application process "
12381                        + app.processName + " ("
12382                        + (app.thread != null ? app.thread.asBinder() : null)
12383                        + ")\n");
12384                    if (app.pid > 0 && app.pid != MY_PID) {
12385                        Process.killProcess(app.pid);
12386                    } else {
12387                        try {
12388                            app.thread.scheduleExit();
12389                        } catch (Exception e) {
12390                            // Ignore exceptions.
12391                        }
12392                    }
12393                    cleanUpApplicationRecordLocked(app, false, -1);
12394                    mRemovedProcesses.remove(i);
12395
12396                    if (app.persistent) {
12397                        if (app.persistent) {
12398                            addAppLocked(app.info);
12399                        }
12400                    }
12401                }
12402            }
12403
12404            // Now try updating the OOM adjustment for each of the
12405            // application processes based on their current state.
12406            // If the setOomAdj() API is not supported, then go with our
12407            // back-up plan...
12408            if (!updateOomAdjLocked()) {
12409
12410                // Count how many processes are running services.
12411                int numServiceProcs = 0;
12412                for (i=mLruProcesses.size()-1; i>=0; i--) {
12413                    final ProcessRecord app = mLruProcesses.get(i);
12414
12415                    if (app.persistent || app.services.size() != 0
12416                            || app.curReceiver != null) {
12417                        // Don't count processes holding services against our
12418                        // maximum process count.
12419                        if (localLOGV) Slog.v(
12420                            TAG, "Not trimming app " + app + " with services: "
12421                            + app.services);
12422                        numServiceProcs++;
12423                    }
12424                }
12425
12426                int curMaxProcs = mProcessLimit;
12427                if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
12428                if (mAlwaysFinishActivities) {
12429                    curMaxProcs = 1;
12430                }
12431                curMaxProcs += numServiceProcs;
12432
12433                // Quit as many processes as we can to get down to the desired
12434                // process count.  First remove any processes that no longer
12435                // have activites running in them.
12436                for (   i=0;
12437                        i<mLruProcesses.size()
12438                            && mLruProcesses.size() > curMaxProcs;
12439                        i++) {
12440                    final ProcessRecord app = mLruProcesses.get(i);
12441                    // Quit an application only if it is not currently
12442                    // running any activities.
12443                    if (!app.persistent && app.activities.size() == 0
12444                            && app.curReceiver == null && app.services.size() == 0) {
12445                        Slog.i(
12446                            TAG, "Exiting empty application process "
12447                            + app.processName + " ("
12448                            + (app.thread != null ? app.thread.asBinder() : null)
12449                            + ")\n");
12450                        if (app.pid > 0 && app.pid != MY_PID) {
12451                            Process.killProcess(app.pid);
12452                        } else {
12453                            try {
12454                                app.thread.scheduleExit();
12455                            } catch (Exception e) {
12456                                // Ignore exceptions.
12457                            }
12458                        }
12459                        // todo: For now we assume the application is not buggy
12460                        // or evil, and will quit as a result of our request.
12461                        // Eventually we need to drive this off of the death
12462                        // notification, and kill the process if it takes too long.
12463                        cleanUpApplicationRecordLocked(app, false, i);
12464                        i--;
12465                    }
12466                }
12467
12468                // If we still have too many processes, now from the least
12469                // recently used process we start finishing activities.
12470                if (Config.LOGV) Slog.v(
12471                    TAG, "*** NOW HAVE " + mLruProcesses.size() +
12472                    " of " + curMaxProcs + " processes");
12473                for (   i=0;
12474                        i<mLruProcesses.size()
12475                            && mLruProcesses.size() > curMaxProcs;
12476                        i++) {
12477                    final ProcessRecord app = mLruProcesses.get(i);
12478                    // Quit the application only if we have a state saved for
12479                    // all of its activities.
12480                    boolean canQuit = !app.persistent && app.curReceiver == null
12481                        && app.services.size() == 0;
12482                    int NUMA = app.activities.size();
12483                    int j;
12484                    if (Config.LOGV) Slog.v(
12485                        TAG, "Looking to quit " + app.processName);
12486                    for (j=0; j<NUMA && canQuit; j++) {
12487                        ActivityRecord r = app.activities.get(j);
12488                        if (Config.LOGV) Slog.v(
12489                            TAG, "  " + r.intent.getComponent().flattenToShortString()
12490                            + ": frozen=" + r.haveState + ", visible=" + r.visible);
12491                        canQuit = (r.haveState || !r.stateNotNeeded)
12492                                && !r.visible && r.stopped;
12493                    }
12494                    if (canQuit) {
12495                        // Finish all of the activities, and then the app itself.
12496                        for (j=0; j<NUMA; j++) {
12497                            ActivityRecord r = app.activities.get(j);
12498                            if (!r.finishing) {
12499                                r.stack.destroyActivityLocked(r, false);
12500                            }
12501                            r.resultTo = null;
12502                        }
12503                        Slog.i(TAG, "Exiting application process "
12504                              + app.processName + " ("
12505                              + (app.thread != null ? app.thread.asBinder() : null)
12506                              + ")\n");
12507                        if (app.pid > 0 && app.pid != MY_PID) {
12508                            Process.killProcess(app.pid);
12509                        } else {
12510                            try {
12511                                app.thread.scheduleExit();
12512                            } catch (Exception e) {
12513                                // Ignore exceptions.
12514                            }
12515                        }
12516                        // todo: For now we assume the application is not buggy
12517                        // or evil, and will quit as a result of our request.
12518                        // Eventually we need to drive this off of the death
12519                        // notification, and kill the process if it takes too long.
12520                        cleanUpApplicationRecordLocked(app, false, i);
12521                        i--;
12522                        //dump();
12523                    }
12524                }
12525
12526            }
12527
12528            int curMaxActivities = MAX_ACTIVITIES;
12529            if (mAlwaysFinishActivities) {
12530                curMaxActivities = 1;
12531            }
12532
12533            // Finally, if there are too many activities now running, try to
12534            // finish as many as we can to get back down to the limit.
12535            for (   i=0;
12536                    i<mMainStack.mLRUActivities.size()
12537                        && mMainStack.mLRUActivities.size() > curMaxActivities;
12538                    i++) {
12539                final ActivityRecord r
12540                    = (ActivityRecord)mMainStack.mLRUActivities.get(i);
12541
12542                // We can finish this one if we have its icicle saved and
12543                // it is not persistent.
12544                if ((r.haveState || !r.stateNotNeeded) && !r.visible
12545                        && r.stopped && !r.finishing) {
12546                    final int origSize = mMainStack.mLRUActivities.size();
12547                    r.stack.destroyActivityLocked(r, true);
12548
12549                    // This will remove it from the LRU list, so keep
12550                    // our index at the same value.  Note that this check to
12551                    // see if the size changes is just paranoia -- if
12552                    // something unexpected happens, we don't want to end up
12553                    // in an infinite loop.
12554                    if (origSize > mMainStack.mLRUActivities.size()) {
12555                        i--;
12556                    }
12557                }
12558            }
12559        }
12560    }
12561
12562    /** This method sends the specified signal to each of the persistent apps */
12563    public void signalPersistentProcesses(int sig) throws RemoteException {
12564        if (sig != Process.SIGNAL_USR1) {
12565            throw new SecurityException("Only SIGNAL_USR1 is allowed");
12566        }
12567
12568        synchronized (this) {
12569            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
12570                    != PackageManager.PERMISSION_GRANTED) {
12571                throw new SecurityException("Requires permission "
12572                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
12573            }
12574
12575            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12576                ProcessRecord r = mLruProcesses.get(i);
12577                if (r.thread != null && r.persistent) {
12578                    Process.sendSignal(r.pid, sig);
12579                }
12580            }
12581        }
12582    }
12583
12584    public boolean profileControl(String process, boolean start,
12585            String path, ParcelFileDescriptor fd) throws RemoteException {
12586
12587        try {
12588            synchronized (this) {
12589                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
12590                // its own permission.
12591                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12592                        != PackageManager.PERMISSION_GRANTED) {
12593                    throw new SecurityException("Requires permission "
12594                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12595                }
12596
12597                if (start && fd == null) {
12598                    throw new IllegalArgumentException("null fd");
12599                }
12600
12601                ProcessRecord proc = null;
12602                try {
12603                    int pid = Integer.parseInt(process);
12604                    synchronized (mPidsSelfLocked) {
12605                        proc = mPidsSelfLocked.get(pid);
12606                    }
12607                } catch (NumberFormatException e) {
12608                }
12609
12610                if (proc == null) {
12611                    HashMap<String, SparseArray<ProcessRecord>> all
12612                            = mProcessNames.getMap();
12613                    SparseArray<ProcessRecord> procs = all.get(process);
12614                    if (procs != null && procs.size() > 0) {
12615                        proc = procs.valueAt(0);
12616                    }
12617                }
12618
12619                if (proc == null || proc.thread == null) {
12620                    throw new IllegalArgumentException("Unknown process: " + process);
12621                }
12622
12623                boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
12624                if (isSecure) {
12625                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12626                        throw new SecurityException("Process not debuggable: " + proc);
12627                    }
12628                }
12629
12630                proc.thread.profilerControl(start, path, fd);
12631                fd = null;
12632                return true;
12633            }
12634        } catch (RemoteException e) {
12635            throw new IllegalStateException("Process disappeared");
12636        } finally {
12637            if (fd != null) {
12638                try {
12639                    fd.close();
12640                } catch (IOException e) {
12641                }
12642            }
12643        }
12644    }
12645
12646    public boolean dumpHeap(String process, boolean managed,
12647            String path, ParcelFileDescriptor fd) throws RemoteException {
12648
12649        try {
12650            synchronized (this) {
12651                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
12652                // its own permission (same as profileControl).
12653                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12654                        != PackageManager.PERMISSION_GRANTED) {
12655                    throw new SecurityException("Requires permission "
12656                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12657                }
12658
12659                if (fd == null) {
12660                    throw new IllegalArgumentException("null fd");
12661                }
12662
12663                ProcessRecord proc = null;
12664                try {
12665                    int pid = Integer.parseInt(process);
12666                    synchronized (mPidsSelfLocked) {
12667                        proc = mPidsSelfLocked.get(pid);
12668                    }
12669                } catch (NumberFormatException e) {
12670                }
12671
12672                if (proc == null) {
12673                    HashMap<String, SparseArray<ProcessRecord>> all
12674                            = mProcessNames.getMap();
12675                    SparseArray<ProcessRecord> procs = all.get(process);
12676                    if (procs != null && procs.size() > 0) {
12677                        proc = procs.valueAt(0);
12678                    }
12679                }
12680
12681                if (proc == null || proc.thread == null) {
12682                    throw new IllegalArgumentException("Unknown process: " + process);
12683                }
12684
12685                boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
12686                if (isSecure) {
12687                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12688                        throw new SecurityException("Process not debuggable: " + proc);
12689                    }
12690                }
12691
12692                proc.thread.dumpHeap(managed, path, fd);
12693                fd = null;
12694                return true;
12695            }
12696        } catch (RemoteException e) {
12697            throw new IllegalStateException("Process disappeared");
12698        } finally {
12699            if (fd != null) {
12700                try {
12701                    fd.close();
12702                } catch (IOException e) {
12703                }
12704            }
12705        }
12706    }
12707
12708    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
12709    public void monitor() {
12710        synchronized (this) { }
12711    }
12712}
12713