ActivityManagerService.java revision 75a99709accef8cf221fd436d646727e7c8dd1f1
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.am.ActivityStack.ActivityState;
28import com.android.server.net.NetworkPolicyManagerService;
29import com.android.server.wm.WindowManagerService;
30
31import dalvik.system.Zygote;
32
33import android.app.Activity;
34import android.app.ActivityManager;
35import android.app.ActivityManagerNative;
36import android.app.ActivityThread;
37import android.app.AlertDialog;
38import android.app.AppGlobals;
39import android.app.ApplicationErrorReport;
40import android.app.Dialog;
41import android.app.IActivityController;
42import android.app.IActivityWatcher;
43import android.app.IApplicationThread;
44import android.app.IInstrumentationWatcher;
45import android.app.INotificationManager;
46import android.app.IProcessObserver;
47import android.app.IServiceConnection;
48import android.app.IThumbnailReceiver;
49import android.app.IThumbnailRetriever;
50import android.app.Instrumentation;
51import android.app.Notification;
52import android.app.NotificationManager;
53import android.app.PendingIntent;
54import android.app.Service;
55import android.app.backup.IBackupManager;
56import android.content.ActivityNotFoundException;
57import android.content.BroadcastReceiver;
58import android.content.ComponentName;
59import android.content.ContentResolver;
60import android.content.Context;
61import android.content.DialogInterface;
62import android.content.Intent;
63import android.content.IntentFilter;
64import android.content.IIntentReceiver;
65import android.content.IIntentSender;
66import android.content.IntentSender;
67import android.content.pm.ActivityInfo;
68import android.content.pm.ApplicationInfo;
69import android.content.pm.ConfigurationInfo;
70import android.content.pm.IPackageDataObserver;
71import android.content.pm.IPackageManager;
72import android.content.pm.InstrumentationInfo;
73import android.content.pm.PackageInfo;
74import android.content.pm.PackageManager;
75import android.content.pm.PathPermission;
76import android.content.pm.ProviderInfo;
77import android.content.pm.ResolveInfo;
78import android.content.pm.ServiceInfo;
79import android.content.pm.PackageManager.NameNotFoundException;
80import android.content.res.CompatibilityInfo;
81import android.content.res.Configuration;
82import android.graphics.Bitmap;
83import android.net.Proxy;
84import android.net.ProxyProperties;
85import android.net.Uri;
86import android.os.Binder;
87import android.os.Build;
88import android.os.Bundle;
89import android.os.Debug;
90import android.os.DropBoxManager;
91import android.os.Environment;
92import android.os.FileObserver;
93import android.os.FileUtils;
94import android.os.Handler;
95import android.os.IBinder;
96import android.os.IInterface;
97import android.os.IPermissionController;
98import android.os.Looper;
99import android.os.Message;
100import android.os.Parcel;
101import android.os.ParcelFileDescriptor;
102import android.os.Process;
103import android.os.RemoteCallbackList;
104import android.os.RemoteException;
105import android.os.ServiceManager;
106import android.os.StrictMode;
107import android.os.SystemClock;
108import android.os.SystemProperties;
109import android.provider.Settings;
110import android.util.EventLog;
111import android.util.Slog;
112import android.util.Log;
113import android.util.PrintWriterPrinter;
114import android.util.SparseArray;
115import android.util.TimeUtils;
116import android.view.Gravity;
117import android.view.LayoutInflater;
118import android.view.View;
119import android.view.WindowManager;
120import android.view.WindowManagerPolicy;
121
122import java.io.BufferedInputStream;
123import java.io.BufferedOutputStream;
124import java.io.DataInputStream;
125import java.io.DataOutputStream;
126import java.io.File;
127import java.io.FileDescriptor;
128import java.io.FileInputStream;
129import java.io.FileNotFoundException;
130import java.io.FileOutputStream;
131import java.io.IOException;
132import java.io.InputStreamReader;
133import java.io.PrintWriter;
134import java.lang.IllegalStateException;
135import java.lang.ref.WeakReference;
136import java.util.ArrayList;
137import java.util.Collections;
138import java.util.Comparator;
139import java.util.HashMap;
140import java.util.HashSet;
141import java.util.Iterator;
142import java.util.List;
143import java.util.Locale;
144import java.util.Map;
145import java.util.Set;
146import java.util.concurrent.atomic.AtomicBoolean;
147import java.util.concurrent.atomic.AtomicLong;
148
149public final class ActivityManagerService extends ActivityManagerNative
150        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
151    static final String TAG = "ActivityManager";
152    static final boolean DEBUG = false;
153    static final boolean localLOGV = DEBUG;
154    static final boolean DEBUG_SWITCH = localLOGV || false;
155    static final boolean DEBUG_TASKS = localLOGV || false;
156    static final boolean DEBUG_PAUSE = localLOGV || false;
157    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
158    static final boolean DEBUG_TRANSITION = localLOGV || false;
159    static final boolean DEBUG_BROADCAST = localLOGV || false;
160    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
161    static final boolean DEBUG_SERVICE = localLOGV || false;
162    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
163    static final boolean DEBUG_VISBILITY = localLOGV || false;
164    static final boolean DEBUG_PROCESSES = localLOGV || false;
165    static final boolean DEBUG_PROVIDER = localLOGV || false;
166    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
167    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
168    static final boolean DEBUG_RESULTS = localLOGV || false;
169    static final boolean DEBUG_BACKUP = localLOGV || true;
170    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
171    static final boolean DEBUG_POWER = localLOGV || false;
172    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
173    static final boolean VALIDATE_TOKENS = false;
174    static final boolean SHOW_ACTIVITY_START_TIME = true;
175
176    // Control over CPU and battery monitoring.
177    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
178    static final boolean MONITOR_CPU_USAGE = true;
179    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
180    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
181    static final boolean MONITOR_THREAD_CPU_USAGE = false;
182
183    // The flags that are set for all calls we make to the package manager.
184    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
185
186    private static final String SYSTEM_SECURE = "ro.secure";
187    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
188
189    // This is the maximum number of application processes we would like
190    // to have running.  Due to the asynchronous nature of things, we can
191    // temporarily go beyond this limit.
192    static final int MAX_PROCESSES = 2;
193
194    // Set to false to leave processes running indefinitely, relying on
195    // the kernel killing them as resources are required.
196    static final boolean ENFORCE_PROCESS_LIMIT = false;
197
198    // This is the maximum number of activities that we would like to have
199    // running at a given time.
200    static final int MAX_ACTIVITIES = 20;
201
202    // Maximum number of recent tasks that we can remember.
203    static final int MAX_RECENT_TASKS = 20;
204
205    // Amount of time after a call to stopAppSwitches() during which we will
206    // prevent further untrusted switches from happening.
207    static final long APP_SWITCH_DELAY_TIME = 5*1000;
208
209    // How long we wait for a launched process to attach to the activity manager
210    // before we decide it's never going to come up for real.
211    static final int PROC_START_TIMEOUT = 10*1000;
212
213    // How long to wait after going idle before forcing apps to GC.
214    static final int GC_TIMEOUT = 5*1000;
215
216    // The minimum amount of time between successive GC requests for a process.
217    static final int GC_MIN_INTERVAL = 60*1000;
218
219    // The rate at which we check for apps using excessive power -- 15 mins.
220    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
221
222    // The minimum sample duration we will allow before deciding we have
223    // enough data on wake locks to start killing things.
224    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
225
226    // The minimum sample duration we will allow before deciding we have
227    // enough data on CPU usage to start killing things.
228    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
229
230    // How long we allow a receiver to run before giving up on it.
231    static final int BROADCAST_TIMEOUT = 10*1000;
232
233    // How long we wait for a service to finish executing.
234    static final int SERVICE_TIMEOUT = 20*1000;
235
236    // How long a service needs to be running until restarting its process
237    // is no longer considered to be a relaunch of the service.
238    static final int SERVICE_RESTART_DURATION = 5*1000;
239
240    // How long a service needs to be running until it will start back at
241    // SERVICE_RESTART_DURATION after being killed.
242    static final int SERVICE_RESET_RUN_DURATION = 60*1000;
243
244    // Multiplying factor to increase restart duration time by, for each time
245    // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
246    static final int SERVICE_RESTART_DURATION_FACTOR = 4;
247
248    // The minimum amount of time between restarting services that we allow.
249    // That is, when multiple services are restarting, we won't allow each
250    // to restart less than this amount of time from the last one.
251    static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
252
253    // Maximum amount of time for there to be no activity on a service before
254    // we consider it non-essential and allow its process to go on the
255    // LRU background list.
256    static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
257
258    // How long we wait until we timeout on key dispatching.
259    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
260
261    // The minimum time we allow between crashes, for us to consider this
262    // application to be bad and stop and its services and reject broadcasts.
263    static final int MIN_CRASH_INTERVAL = 60*1000;
264
265    // How long we wait until we timeout on key dispatching during instrumentation.
266    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
267
268    // OOM adjustments for processes in various states:
269
270    // This is a process without anything currently running in it.  Definitely
271    // the first to go! Value set in system/rootdir/init.rc on startup.
272    // This value is initalized in the constructor, careful when refering to
273    // this static variable externally.
274    static final int EMPTY_APP_ADJ;
275
276    // This is a process only hosting activities that are not visible,
277    // so it can be killed without any disruption. Value set in
278    // system/rootdir/init.rc on startup.
279    static final int HIDDEN_APP_MAX_ADJ;
280    static int HIDDEN_APP_MIN_ADJ;
281
282    // This is a process holding the home application -- we want to try
283    // avoiding killing it, even if it would normally be in the background,
284    // because the user interacts with it so much.
285    static final int HOME_APP_ADJ;
286
287    // This is a process currently hosting a backup operation.  Killing it
288    // is not entirely fatal but is generally a bad idea.
289    static final int BACKUP_APP_ADJ;
290
291    // This is a process holding a secondary server -- killing it will not
292    // have much of an impact as far as the user is concerned. Value set in
293    // system/rootdir/init.rc on startup.
294    static final int SECONDARY_SERVER_ADJ;
295
296    // This is a process with a heavy-weight application.  It is in the
297    // background, but we want to try to avoid killing it.  Value set in
298    // system/rootdir/init.rc on startup.
299    static final int HEAVY_WEIGHT_APP_ADJ;
300
301    // This is a process only hosting components that are perceptible to the
302    // user, and we really want to avoid killing them, but they are not
303    // immediately visible. An example is background music playback.  Value set in
304    // system/rootdir/init.rc on startup.
305    static final int PERCEPTIBLE_APP_ADJ;
306
307    // This is a process only hosting activities that are visible to the
308    // user, so we'd prefer they don't disappear. Value set in
309    // system/rootdir/init.rc on startup.
310    static final int VISIBLE_APP_ADJ;
311
312    // This is the process running the current foreground app.  We'd really
313    // rather not kill it! Value set in system/rootdir/init.rc on startup.
314    static final int FOREGROUND_APP_ADJ;
315
316    // This is a process running a core server, such as telephony.  Definitely
317    // don't want to kill it, but doing so is not completely fatal.
318    static final int CORE_SERVER_ADJ = -12;
319
320    // The system process runs at the default adjustment.
321    static final int SYSTEM_ADJ = -16;
322
323    // Memory pages are 4K.
324    static final int PAGE_SIZE = 4*1024;
325
326    // Corresponding memory levels for above adjustments.
327    static final int EMPTY_APP_MEM;
328    static final int HIDDEN_APP_MEM;
329    static final int HOME_APP_MEM;
330    static final int BACKUP_APP_MEM;
331    static final int SECONDARY_SERVER_MEM;
332    static final int HEAVY_WEIGHT_APP_MEM;
333    static final int PERCEPTIBLE_APP_MEM;
334    static final int VISIBLE_APP_MEM;
335    static final int FOREGROUND_APP_MEM;
336
337    // The minimum number of hidden apps we want to be able to keep around,
338    // without empty apps being able to push them out of memory.
339    static final int MIN_HIDDEN_APPS = 2;
340
341    // The maximum number of hidden processes we will keep around before
342    // killing them; this is just a control to not let us go too crazy with
343    // keeping around processes on devices with large amounts of RAM.
344    static final int MAX_HIDDEN_APPS = 15;
345
346    // We put empty content processes after any hidden processes that have
347    // been idle for less than 15 seconds.
348    static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
349
350    // We put empty content processes after any hidden processes that have
351    // been idle for less than 120 seconds.
352    static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
353
354    static int getIntProp(String name, boolean allowZero) {
355        String str = SystemProperties.get(name);
356        if (str == null) {
357            throw new IllegalArgumentException("Property not defined: " + name);
358        }
359        int val = Integer.valueOf(str);
360        if (val == 0 && !allowZero) {
361            throw new IllegalArgumentException("Property must not be zero: " + name);
362        }
363        return val;
364    }
365
366    static {
367        // These values are set in system/rootdir/init.rc on startup.
368        FOREGROUND_APP_ADJ = getIntProp("ro.FOREGROUND_APP_ADJ", true);
369        VISIBLE_APP_ADJ = getIntProp("ro.VISIBLE_APP_ADJ", true);
370        PERCEPTIBLE_APP_ADJ = getIntProp("ro.PERCEPTIBLE_APP_ADJ", true);
371        HEAVY_WEIGHT_APP_ADJ = getIntProp("ro.HEAVY_WEIGHT_APP_ADJ", true);
372        SECONDARY_SERVER_ADJ = getIntProp("ro.SECONDARY_SERVER_ADJ", true);
373        BACKUP_APP_ADJ = getIntProp("ro.BACKUP_APP_ADJ", true);
374        HOME_APP_ADJ = getIntProp("ro.HOME_APP_ADJ", true);
375        HIDDEN_APP_MIN_ADJ = getIntProp("ro.HIDDEN_APP_MIN_ADJ", true);
376        EMPTY_APP_ADJ = getIntProp("ro.EMPTY_APP_ADJ", true);
377        // These days we use the last empty slot for hidden apps as well.
378        HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ;
379        FOREGROUND_APP_MEM = getIntProp("ro.FOREGROUND_APP_MEM", false)*PAGE_SIZE;
380        VISIBLE_APP_MEM = getIntProp("ro.VISIBLE_APP_MEM", false)*PAGE_SIZE;
381        PERCEPTIBLE_APP_MEM = getIntProp("ro.PERCEPTIBLE_APP_MEM", false)*PAGE_SIZE;
382        HEAVY_WEIGHT_APP_MEM = getIntProp("ro.HEAVY_WEIGHT_APP_MEM", false)*PAGE_SIZE;
383        SECONDARY_SERVER_MEM = getIntProp("ro.SECONDARY_SERVER_MEM", false)*PAGE_SIZE;
384        BACKUP_APP_MEM = getIntProp("ro.BACKUP_APP_MEM", false)*PAGE_SIZE;
385        HOME_APP_MEM = getIntProp("ro.HOME_APP_MEM", false)*PAGE_SIZE;
386        HIDDEN_APP_MEM = getIntProp("ro.HIDDEN_APP_MEM", false)*PAGE_SIZE;
387        EMPTY_APP_MEM = getIntProp("ro.EMPTY_APP_MEM", false)*PAGE_SIZE;
388    }
389
390    static final int MY_PID = Process.myPid();
391
392    static final String[] EMPTY_STRING_ARRAY = new String[0];
393
394    public ActivityStack mMainStack;
395
396    /**
397     * Description of a request to start a new activity, which has been held
398     * due to app switches being disabled.
399     */
400    static class PendingActivityLaunch {
401        ActivityRecord r;
402        ActivityRecord sourceRecord;
403        Uri[] grantedUriPermissions;
404        int grantedMode;
405        boolean onlyIfNeeded;
406    }
407
408    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
409            = new ArrayList<PendingActivityLaunch>();
410
411    /**
412     * List of all active broadcasts that are to be executed immediately
413     * (without waiting for another broadcast to finish).  Currently this only
414     * contains broadcasts to registered receivers, to avoid spinning up
415     * a bunch of processes to execute IntentReceiver components.
416     */
417    final ArrayList<BroadcastRecord> mParallelBroadcasts
418            = new ArrayList<BroadcastRecord>();
419
420    /**
421     * List of all active broadcasts that are to be executed one at a time.
422     * The object at the top of the list is the currently activity broadcasts;
423     * those after it are waiting for the top to finish..
424     */
425    final ArrayList<BroadcastRecord> mOrderedBroadcasts
426            = new ArrayList<BroadcastRecord>();
427
428    /**
429     * Historical data of past broadcasts, for debugging.
430     */
431    static final int MAX_BROADCAST_HISTORY = 100;
432    final BroadcastRecord[] mBroadcastHistory
433            = new BroadcastRecord[MAX_BROADCAST_HISTORY];
434
435    /**
436     * Set when we current have a BROADCAST_INTENT_MSG in flight.
437     */
438    boolean mBroadcastsScheduled = false;
439
440    /**
441     * Activity we have told the window manager to have key focus.
442     */
443    ActivityRecord mFocusedActivity = null;
444    /**
445     * List of intents that were used to start the most recent tasks.
446     */
447    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
448
449    /**
450     * All of the applications we currently have running organized by name.
451     * The keys are strings of the application package name (as
452     * returned by the package manager), and the keys are ApplicationRecord
453     * objects.
454     */
455    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
456
457    /**
458     * The currently running heavy-weight process, if any.
459     */
460    ProcessRecord mHeavyWeightProcess = null;
461
462    /**
463     * The last time that various processes have crashed.
464     */
465    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
466
467    /**
468     * Set of applications that we consider to be bad, and will reject
469     * incoming broadcasts from (which the user has no control over).
470     * Processes are added to this set when they have crashed twice within
471     * a minimum amount of time; they are removed from it when they are
472     * later restarted (hopefully due to some user action).  The value is the
473     * time it was added to the list.
474     */
475    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
476
477    /**
478     * All of the processes we currently have running organized by pid.
479     * The keys are the pid running the application.
480     *
481     * <p>NOTE: This object is protected by its own lock, NOT the global
482     * activity manager lock!
483     */
484    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
485
486    /**
487     * All of the processes that have been forced to be foreground.  The key
488     * is the pid of the caller who requested it (we hold a death
489     * link on it).
490     */
491    abstract class ForegroundToken implements IBinder.DeathRecipient {
492        int pid;
493        IBinder token;
494    }
495    final SparseArray<ForegroundToken> mForegroundProcesses
496            = new SparseArray<ForegroundToken>();
497
498    /**
499     * List of records for processes that someone had tried to start before the
500     * system was ready.  We don't start them at that point, but ensure they
501     * are started by the time booting is complete.
502     */
503    final ArrayList<ProcessRecord> mProcessesOnHold
504            = new ArrayList<ProcessRecord>();
505
506    /**
507     * List of records for processes that we have started and are waiting
508     * for them to call back.  This is really only needed when running in
509     * single processes mode, in which case we do not have a unique pid for
510     * each process.
511     */
512    final ArrayList<ProcessRecord> mStartingProcesses
513            = new ArrayList<ProcessRecord>();
514
515    /**
516     * List of persistent applications that are in the process
517     * of being started.
518     */
519    final ArrayList<ProcessRecord> mPersistentStartingProcesses
520            = new ArrayList<ProcessRecord>();
521
522    /**
523     * Processes that are being forcibly torn down.
524     */
525    final ArrayList<ProcessRecord> mRemovedProcesses
526            = new ArrayList<ProcessRecord>();
527
528    /**
529     * List of running applications, sorted by recent usage.
530     * The first entry in the list is the least recently used.
531     * It contains ApplicationRecord objects.  This list does NOT include
532     * any persistent application records (since we never want to exit them).
533     */
534    final ArrayList<ProcessRecord> mLruProcesses
535            = new ArrayList<ProcessRecord>();
536
537    /**
538     * List of processes that should gc as soon as things are idle.
539     */
540    final ArrayList<ProcessRecord> mProcessesToGc
541            = new ArrayList<ProcessRecord>();
542
543    /**
544     * This is the process holding what we currently consider to be
545     * the "home" activity.
546     */
547    ProcessRecord mHomeProcess;
548
549    /**
550     * Packages that the user has asked to have run in screen size
551     * compatibility mode instead of filling the screen.
552     */
553    final CompatModePackages mCompatModePackages;
554
555    /**
556     * Set of PendingResultRecord objects that are currently active.
557     */
558    final HashSet mPendingResultRecords = new HashSet();
559
560    /**
561     * Set of IntentSenderRecord objects that are currently active.
562     */
563    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
564            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
565
566    /**
567     * Fingerprints (hashCode()) of stack traces that we've
568     * already logged DropBox entries for.  Guarded by itself.  If
569     * something (rogue user app) forces this over
570     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
571     */
572    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
573    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
574
575    /**
576     * Strict Mode background batched logging state.
577     *
578     * The string buffer is guarded by itself, and its lock is also
579     * used to determine if another batched write is already
580     * in-flight.
581     */
582    private final StringBuilder mStrictModeBuffer = new StringBuilder();
583
584    /**
585     * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
586     */
587    private boolean mPendingBroadcastTimeoutMessage;
588
589    /**
590     * Intent broadcast that we have tried to start, but are
591     * waiting for its application's process to be created.  We only
592     * need one (instead of a list) because we always process broadcasts
593     * one at a time, so no others can be started while waiting for this
594     * one.
595     */
596    BroadcastRecord mPendingBroadcast = null;
597
598    /**
599     * The receiver index that is pending, to restart the broadcast if needed.
600     */
601    int mPendingBroadcastRecvIndex;
602
603    /**
604     * Keeps track of all IIntentReceivers that have been registered for
605     * broadcasts.  Hash keys are the receiver IBinder, hash value is
606     * a ReceiverList.
607     */
608    final HashMap mRegisteredReceivers = new HashMap();
609
610    /**
611     * Resolver for broadcast intents to registered receivers.
612     * Holds BroadcastFilter (subclass of IntentFilter).
613     */
614    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
615            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
616        @Override
617        protected boolean allowFilterResult(
618                BroadcastFilter filter, List<BroadcastFilter> dest) {
619            IBinder target = filter.receiverList.receiver.asBinder();
620            for (int i=dest.size()-1; i>=0; i--) {
621                if (dest.get(i).receiverList.receiver.asBinder() == target) {
622                    return false;
623                }
624            }
625            return true;
626        }
627    };
628
629    /**
630     * State of all active sticky broadcasts.  Keys are the action of the
631     * sticky Intent, values are an ArrayList of all broadcasted intents with
632     * that action (which should usually be one).
633     */
634    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
635            new HashMap<String, ArrayList<Intent>>();
636
637    /**
638     * All currently running services.
639     */
640    final HashMap<ComponentName, ServiceRecord> mServices =
641        new HashMap<ComponentName, ServiceRecord>();
642
643    /**
644     * All currently running services indexed by the Intent used to start them.
645     */
646    final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
647        new HashMap<Intent.FilterComparison, ServiceRecord>();
648
649    /**
650     * All currently bound service connections.  Keys are the IBinder of
651     * the client's IServiceConnection.
652     */
653    final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
654            = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
655
656    /**
657     * List of services that we have been asked to start,
658     * but haven't yet been able to.  It is used to hold start requests
659     * while waiting for their corresponding application thread to get
660     * going.
661     */
662    final ArrayList<ServiceRecord> mPendingServices
663            = new ArrayList<ServiceRecord>();
664
665    /**
666     * List of services that are scheduled to restart following a crash.
667     */
668    final ArrayList<ServiceRecord> mRestartingServices
669            = new ArrayList<ServiceRecord>();
670
671    /**
672     * List of services that are in the process of being stopped.
673     */
674    final ArrayList<ServiceRecord> mStoppingServices
675            = new ArrayList<ServiceRecord>();
676
677    /**
678     * Backup/restore process management
679     */
680    String mBackupAppName = null;
681    BackupRecord mBackupTarget = null;
682
683    /**
684     * List of PendingThumbnailsRecord objects of clients who are still
685     * waiting to receive all of the thumbnails for a task.
686     */
687    final ArrayList mPendingThumbnails = new ArrayList();
688
689    /**
690     * List of HistoryRecord objects that have been finished and must
691     * still report back to a pending thumbnail receiver.
692     */
693    final ArrayList mCancelledThumbnails = new ArrayList();
694
695    /**
696     * All of the currently running global content providers.  Keys are a
697     * string containing the provider name and values are a
698     * ContentProviderRecord object containing the data about it.  Note
699     * that a single provider may be published under multiple names, so
700     * there may be multiple entries here for a single one in mProvidersByClass.
701     */
702    final HashMap<String, ContentProviderRecord> mProvidersByName
703            = new HashMap<String, ContentProviderRecord>();
704
705    /**
706     * All of the currently running global content providers.  Keys are a
707     * string containing the provider's implementation class and values are a
708     * ContentProviderRecord object containing the data about it.
709     */
710    final HashMap<String, ContentProviderRecord> mProvidersByClass
711            = new HashMap<String, ContentProviderRecord>();
712
713    /**
714     * List of content providers who have clients waiting for them.  The
715     * application is currently being launched and the provider will be
716     * removed from this list once it is published.
717     */
718    final ArrayList<ContentProviderRecord> mLaunchingProviders
719            = new ArrayList<ContentProviderRecord>();
720
721    /**
722     * Global set of specific Uri permissions that have been granted.
723     */
724    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
725            = new SparseArray<HashMap<Uri, UriPermission>>();
726
727    CoreSettingsObserver mCoreSettingsObserver;
728
729    /**
730     * Thread-local storage used to carry caller permissions over through
731     * indirect content-provider access.
732     * @see #ActivityManagerService.openContentUri()
733     */
734    private class Identity {
735        public int pid;
736        public int uid;
737
738        Identity(int _pid, int _uid) {
739            pid = _pid;
740            uid = _uid;
741        }
742    }
743    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
744
745    /**
746     * All information we have collected about the runtime performance of
747     * any user id that can impact battery performance.
748     */
749    final BatteryStatsService mBatteryStatsService;
750
751    /**
752     * information about component usage
753     */
754    final UsageStatsService mUsageStatsService;
755
756    /**
757     * Current configuration information.  HistoryRecord objects are given
758     * a reference to this object to indicate which configuration they are
759     * currently running in, so this object must be kept immutable.
760     */
761    Configuration mConfiguration = new Configuration();
762
763    /**
764     * Current sequencing integer of the configuration, for skipping old
765     * configurations.
766     */
767    int mConfigurationSeq = 0;
768
769    /**
770     * Hardware-reported OpenGLES version.
771     */
772    final int GL_ES_VERSION;
773
774    /**
775     * List of initialization arguments to pass to all processes when binding applications to them.
776     * For example, references to the commonly used services.
777     */
778    HashMap<String, IBinder> mAppBindArgs;
779
780    /**
781     * Temporary to avoid allocations.  Protected by main lock.
782     */
783    final StringBuilder mStringBuilder = new StringBuilder(256);
784
785    /**
786     * Used to control how we initialize the service.
787     */
788    boolean mStartRunning = false;
789    ComponentName mTopComponent;
790    String mTopAction;
791    String mTopData;
792    boolean mProcessesReady = false;
793    boolean mSystemReady = false;
794    boolean mBooting = false;
795    boolean mWaitingUpdate = false;
796    boolean mDidUpdate = false;
797    boolean mOnBattery = false;
798    boolean mLaunchWarningShown = false;
799
800    Context mContext;
801
802    int mFactoryTest;
803
804    boolean mCheckedForSetup;
805
806    /**
807     * The time at which we will allow normal application switches again,
808     * after a call to {@link #stopAppSwitches()}.
809     */
810    long mAppSwitchesAllowedTime;
811
812    /**
813     * This is set to true after the first switch after mAppSwitchesAllowedTime
814     * is set; any switches after that will clear the time.
815     */
816    boolean mDidAppSwitch;
817
818    /**
819     * Last time (in realtime) at which we checked for power usage.
820     */
821    long mLastPowerCheckRealtime;
822
823    /**
824     * Last time (in uptime) at which we checked for power usage.
825     */
826    long mLastPowerCheckUptime;
827
828    /**
829     * Set while we are wanting to sleep, to prevent any
830     * activities from being started/resumed.
831     */
832    boolean mSleeping = false;
833
834    /**
835     * Set if we are shutting down the system, similar to sleeping.
836     */
837    boolean mShuttingDown = false;
838
839    /**
840     * Task identifier that activities are currently being started
841     * in.  Incremented each time a new task is created.
842     * todo: Replace this with a TokenSpace class that generates non-repeating
843     * integers that won't wrap.
844     */
845    int mCurTask = 1;
846
847    /**
848     * Current sequence id for oom_adj computation traversal.
849     */
850    int mAdjSeq = 0;
851
852    /**
853     * Current sequence id for process LRU updating.
854     */
855    int mLruSeq = 0;
856
857    /**
858     * System monitoring: number of processes that died since the last
859     * N procs were started.
860     */
861    int[] mProcDeaths = new int[20];
862
863    /**
864     * This is set if we had to do a delayed dexopt of an app before launching
865     * it, to increasing the ANR timeouts in that case.
866     */
867    boolean mDidDexOpt;
868
869    String mDebugApp = null;
870    boolean mWaitForDebugger = false;
871    boolean mDebugTransient = false;
872    String mOrigDebugApp = null;
873    boolean mOrigWaitForDebugger = false;
874    boolean mAlwaysFinishActivities = false;
875    IActivityController mController = null;
876
877    final RemoteCallbackList<IActivityWatcher> mWatchers
878            = new RemoteCallbackList<IActivityWatcher>();
879
880    final RemoteCallbackList<IProcessObserver> mProcessObservers
881            = new RemoteCallbackList<IProcessObserver>();
882
883    /**
884     * Callback of last caller to {@link #requestPss}.
885     */
886    Runnable mRequestPssCallback;
887
888    /**
889     * Remaining processes for which we are waiting results from the last
890     * call to {@link #requestPss}.
891     */
892    final ArrayList<ProcessRecord> mRequestPssList
893            = new ArrayList<ProcessRecord>();
894
895    /**
896     * Runtime statistics collection thread.  This object's lock is used to
897     * protect all related state.
898     */
899    final Thread mProcessStatsThread;
900
901    /**
902     * Used to collect process stats when showing not responding dialog.
903     * Protected by mProcessStatsThread.
904     */
905    final ProcessStats mProcessStats = new ProcessStats(
906            MONITOR_THREAD_CPU_USAGE);
907    final AtomicLong mLastCpuTime = new AtomicLong(0);
908    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
909
910    long mLastWriteTime = 0;
911
912    /**
913     * Set to true after the system has finished booting.
914     */
915    boolean mBooted = false;
916
917    int mProcessLimit = 0;
918
919    WindowManagerService mWindowManager;
920
921    static ActivityManagerService mSelf;
922    static ActivityThread mSystemThread;
923
924    private final class AppDeathRecipient implements IBinder.DeathRecipient {
925        final ProcessRecord mApp;
926        final int mPid;
927        final IApplicationThread mAppThread;
928
929        AppDeathRecipient(ProcessRecord app, int pid,
930                IApplicationThread thread) {
931            if (localLOGV) Slog.v(
932                TAG, "New death recipient " + this
933                + " for thread " + thread.asBinder());
934            mApp = app;
935            mPid = pid;
936            mAppThread = thread;
937        }
938
939        public void binderDied() {
940            if (localLOGV) Slog.v(
941                TAG, "Death received in " + this
942                + " for thread " + mAppThread.asBinder());
943            synchronized(ActivityManagerService.this) {
944                appDiedLocked(mApp, mPid, mAppThread);
945            }
946        }
947    }
948
949    static final int SHOW_ERROR_MSG = 1;
950    static final int SHOW_NOT_RESPONDING_MSG = 2;
951    static final int SHOW_FACTORY_ERROR_MSG = 3;
952    static final int UPDATE_CONFIGURATION_MSG = 4;
953    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
954    static final int WAIT_FOR_DEBUGGER_MSG = 6;
955    static final int BROADCAST_INTENT_MSG = 7;
956    static final int BROADCAST_TIMEOUT_MSG = 8;
957    static final int SERVICE_TIMEOUT_MSG = 12;
958    static final int UPDATE_TIME_ZONE = 13;
959    static final int SHOW_UID_ERROR_MSG = 14;
960    static final int IM_FEELING_LUCKY_MSG = 15;
961    static final int PROC_START_TIMEOUT_MSG = 20;
962    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
963    static final int KILL_APPLICATION_MSG = 22;
964    static final int FINALIZE_PENDING_INTENT_MSG = 23;
965    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
966    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
967    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
968    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
969    static final int CLEAR_DNS_CACHE = 28;
970    static final int UPDATE_HTTP_PROXY = 29;
971    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
972    static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
973    static final int DISPATCH_PROCESS_DIED = 32;
974
975    AlertDialog mUidAlert;
976    CompatModeDialog mCompatModeDialog;
977
978    final Handler mHandler = new Handler() {
979        //public Handler() {
980        //    if (localLOGV) Slog.v(TAG, "Handler started!");
981        //}
982
983        public void handleMessage(Message msg) {
984            switch (msg.what) {
985            case SHOW_ERROR_MSG: {
986                HashMap data = (HashMap) msg.obj;
987                synchronized (ActivityManagerService.this) {
988                    ProcessRecord proc = (ProcessRecord)data.get("app");
989                    if (proc != null && proc.crashDialog != null) {
990                        Slog.e(TAG, "App already has crash dialog: " + proc);
991                        return;
992                    }
993                    AppErrorResult res = (AppErrorResult) data.get("result");
994                    if (!mSleeping && !mShuttingDown) {
995                        Dialog d = new AppErrorDialog(mContext, res, proc);
996                        d.show();
997                        proc.crashDialog = d;
998                    } else {
999                        // The device is asleep, so just pretend that the user
1000                        // saw a crash dialog and hit "force quit".
1001                        res.set(0);
1002                    }
1003                }
1004
1005                ensureBootCompleted();
1006            } break;
1007            case SHOW_NOT_RESPONDING_MSG: {
1008                synchronized (ActivityManagerService.this) {
1009                    HashMap data = (HashMap) msg.obj;
1010                    ProcessRecord proc = (ProcessRecord)data.get("app");
1011                    if (proc != null && proc.anrDialog != null) {
1012                        Slog.e(TAG, "App already has anr dialog: " + proc);
1013                        return;
1014                    }
1015
1016                    Intent intent = new Intent("android.intent.action.ANR");
1017                    if (!mProcessesReady) {
1018                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1019                    }
1020                    broadcastIntentLocked(null, null, intent,
1021                            null, null, 0, null, null, null,
1022                            false, false, MY_PID, Process.SYSTEM_UID);
1023
1024                    Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1025                            mContext, proc, (ActivityRecord)data.get("activity"));
1026                    d.show();
1027                    proc.anrDialog = d;
1028                }
1029
1030                ensureBootCompleted();
1031            } break;
1032            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1033                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1034                synchronized (ActivityManagerService.this) {
1035                    ProcessRecord proc = (ProcessRecord) data.get("app");
1036                    if (proc == null) {
1037                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1038                        break;
1039                    }
1040                    if (proc.crashDialog != null) {
1041                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1042                        return;
1043                    }
1044                    AppErrorResult res = (AppErrorResult) data.get("result");
1045                    if (!mSleeping && !mShuttingDown) {
1046                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
1047                        d.show();
1048                        proc.crashDialog = d;
1049                    } else {
1050                        // The device is asleep, so just pretend that the user
1051                        // saw a crash dialog and hit "force quit".
1052                        res.set(0);
1053                    }
1054                }
1055                ensureBootCompleted();
1056            } break;
1057            case SHOW_FACTORY_ERROR_MSG: {
1058                Dialog d = new FactoryErrorDialog(
1059                    mContext, msg.getData().getCharSequence("msg"));
1060                d.show();
1061                ensureBootCompleted();
1062            } break;
1063            case UPDATE_CONFIGURATION_MSG: {
1064                final ContentResolver resolver = mContext.getContentResolver();
1065                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1066            } break;
1067            case GC_BACKGROUND_PROCESSES_MSG: {
1068                synchronized (ActivityManagerService.this) {
1069                    performAppGcsIfAppropriateLocked();
1070                }
1071            } break;
1072            case WAIT_FOR_DEBUGGER_MSG: {
1073                synchronized (ActivityManagerService.this) {
1074                    ProcessRecord app = (ProcessRecord)msg.obj;
1075                    if (msg.arg1 != 0) {
1076                        if (!app.waitedForDebugger) {
1077                            Dialog d = new AppWaitingForDebuggerDialog(
1078                                    ActivityManagerService.this,
1079                                    mContext, app);
1080                            app.waitDialog = d;
1081                            app.waitedForDebugger = true;
1082                            d.show();
1083                        }
1084                    } else {
1085                        if (app.waitDialog != null) {
1086                            app.waitDialog.dismiss();
1087                            app.waitDialog = null;
1088                        }
1089                    }
1090                }
1091            } break;
1092            case BROADCAST_INTENT_MSG: {
1093                if (DEBUG_BROADCAST) Slog.v(
1094                        TAG, "Received BROADCAST_INTENT_MSG");
1095                processNextBroadcast(true);
1096            } break;
1097            case BROADCAST_TIMEOUT_MSG: {
1098                synchronized (ActivityManagerService.this) {
1099                    broadcastTimeoutLocked(true);
1100                }
1101            } break;
1102            case SERVICE_TIMEOUT_MSG: {
1103                if (mDidDexOpt) {
1104                    mDidDexOpt = false;
1105                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1106                    nmsg.obj = msg.obj;
1107                    mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1108                    return;
1109                }
1110                serviceTimeout((ProcessRecord)msg.obj);
1111            } break;
1112            case UPDATE_TIME_ZONE: {
1113                synchronized (ActivityManagerService.this) {
1114                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1115                        ProcessRecord r = mLruProcesses.get(i);
1116                        if (r.thread != null) {
1117                            try {
1118                                r.thread.updateTimeZone();
1119                            } catch (RemoteException ex) {
1120                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1121                            }
1122                        }
1123                    }
1124                }
1125            } break;
1126            case CLEAR_DNS_CACHE: {
1127                synchronized (ActivityManagerService.this) {
1128                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1129                        ProcessRecord r = mLruProcesses.get(i);
1130                        if (r.thread != null) {
1131                            try {
1132                                r.thread.clearDnsCache();
1133                            } catch (RemoteException ex) {
1134                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1135                            }
1136                        }
1137                    }
1138                }
1139            } break;
1140            case UPDATE_HTTP_PROXY: {
1141                ProxyProperties proxy = (ProxyProperties)msg.obj;
1142                String host = "";
1143                String port = "";
1144                String exclList = "";
1145                if (proxy != null) {
1146                    host = proxy.getHost();
1147                    port = Integer.toString(proxy.getPort());
1148                    exclList = proxy.getExclusionList();
1149                }
1150                synchronized (ActivityManagerService.this) {
1151                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1152                        ProcessRecord r = mLruProcesses.get(i);
1153                        if (r.thread != null) {
1154                            try {
1155                                r.thread.setHttpProxy(host, port, exclList);
1156                            } catch (RemoteException ex) {
1157                                Slog.w(TAG, "Failed to update http proxy for: " +
1158                                        r.info.processName);
1159                            }
1160                        }
1161                    }
1162                }
1163            } break;
1164            case SHOW_UID_ERROR_MSG: {
1165                // XXX This is a temporary dialog, no need to localize.
1166                AlertDialog d = new BaseErrorDialog(mContext);
1167                d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1168                d.setCancelable(false);
1169                d.setTitle("System UIDs Inconsistent");
1170                d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
1171                d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1172                        mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1173                mUidAlert = d;
1174                d.show();
1175            } break;
1176            case IM_FEELING_LUCKY_MSG: {
1177                if (mUidAlert != null) {
1178                    mUidAlert.dismiss();
1179                    mUidAlert = null;
1180                }
1181            } break;
1182            case PROC_START_TIMEOUT_MSG: {
1183                if (mDidDexOpt) {
1184                    mDidDexOpt = false;
1185                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1186                    nmsg.obj = msg.obj;
1187                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1188                    return;
1189                }
1190                ProcessRecord app = (ProcessRecord)msg.obj;
1191                synchronized (ActivityManagerService.this) {
1192                    processStartTimedOutLocked(app);
1193                }
1194            } break;
1195            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1196                synchronized (ActivityManagerService.this) {
1197                    doPendingActivityLaunchesLocked(true);
1198                }
1199            } break;
1200            case KILL_APPLICATION_MSG: {
1201                synchronized (ActivityManagerService.this) {
1202                    int uid = msg.arg1;
1203                    boolean restart = (msg.arg2 == 1);
1204                    String pkg = (String) msg.obj;
1205                    forceStopPackageLocked(pkg, uid, restart, false, true);
1206                }
1207            } break;
1208            case FINALIZE_PENDING_INTENT_MSG: {
1209                ((PendingIntentRecord)msg.obj).completeFinalize();
1210            } break;
1211            case POST_HEAVY_NOTIFICATION_MSG: {
1212                INotificationManager inm = NotificationManager.getService();
1213                if (inm == null) {
1214                    return;
1215                }
1216
1217                ActivityRecord root = (ActivityRecord)msg.obj;
1218                ProcessRecord process = root.app;
1219                if (process == null) {
1220                    return;
1221                }
1222
1223                try {
1224                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1225                    String text = mContext.getString(R.string.heavy_weight_notification,
1226                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1227                    Notification notification = new Notification();
1228                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1229                    notification.when = 0;
1230                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1231                    notification.tickerText = text;
1232                    notification.defaults = 0; // please be quiet
1233                    notification.sound = null;
1234                    notification.vibrate = null;
1235                    notification.setLatestEventInfo(context, text,
1236                            mContext.getText(R.string.heavy_weight_notification_detail),
1237                            PendingIntent.getActivity(mContext, 0, root.intent,
1238                                    PendingIntent.FLAG_CANCEL_CURRENT));
1239
1240                    try {
1241                        int[] outId = new int[1];
1242                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
1243                                notification, outId);
1244                    } catch (RuntimeException e) {
1245                        Slog.w(ActivityManagerService.TAG,
1246                                "Error showing notification for heavy-weight app", e);
1247                    } catch (RemoteException e) {
1248                    }
1249                } catch (NameNotFoundException e) {
1250                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1251                }
1252            } break;
1253            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1254                INotificationManager inm = NotificationManager.getService();
1255                if (inm == null) {
1256                    return;
1257                }
1258                try {
1259                    inm.cancelNotification("android",
1260                            R.string.heavy_weight_notification);
1261                } catch (RuntimeException e) {
1262                    Slog.w(ActivityManagerService.TAG,
1263                            "Error canceling notification for service", e);
1264                } catch (RemoteException e) {
1265                }
1266            } break;
1267            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1268                synchronized (ActivityManagerService.this) {
1269                    checkExcessivePowerUsageLocked(true);
1270                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1271                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1272                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1273                }
1274            } break;
1275            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1276                synchronized (ActivityManagerService.this) {
1277                    ActivityRecord ar = (ActivityRecord)msg.obj;
1278                    if (mCompatModeDialog != null) {
1279                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1280                                ar.info.applicationInfo.packageName)) {
1281                            return;
1282                        }
1283                        mCompatModeDialog.dismiss();
1284                        mCompatModeDialog = null;
1285                    }
1286                    if (ar != null) {
1287                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1288                                ar.packageName)) {
1289                            int mode = mCompatModePackages.computeCompatModeLocked(
1290                                    ar.info.applicationInfo);
1291                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1292                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1293                                mCompatModeDialog = new CompatModeDialog(
1294                                        ActivityManagerService.this, mContext,
1295                                        ar.info.applicationInfo);
1296                                mCompatModeDialog.show();
1297                            }
1298                        }
1299                    }
1300                }
1301                break;
1302            }
1303            case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
1304                final ProcessRecord app = (ProcessRecord) msg.obj;
1305                final boolean foregroundActivities = msg.arg1 != 0;
1306                dispatchForegroundActivitiesChanged(
1307                        app.pid, app.info.uid, foregroundActivities);
1308                break;
1309            }
1310            case DISPATCH_PROCESS_DIED: {
1311                final ProcessRecord app = (ProcessRecord) msg.obj;
1312                dispatchProcessDied(app.pid, app.info.uid);
1313                break;
1314            }
1315            }
1316        }
1317    };
1318
1319    public static void setSystemProcess() {
1320        try {
1321            ActivityManagerService m = mSelf;
1322
1323            ServiceManager.addService("activity", m);
1324            ServiceManager.addService("meminfo", new MemBinder(m));
1325            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1326            if (MONITOR_CPU_USAGE) {
1327                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1328            }
1329            ServiceManager.addService("permission", new PermissionController(m));
1330
1331            ApplicationInfo info =
1332                mSelf.mContext.getPackageManager().getApplicationInfo(
1333                        "android", STOCK_PM_FLAGS);
1334            mSystemThread.installSystemApplicationInfo(info);
1335
1336            synchronized (mSelf) {
1337                ProcessRecord app = mSelf.newProcessRecordLocked(
1338                        mSystemThread.getApplicationThread(), info,
1339                        info.processName);
1340                app.persistent = true;
1341                app.pid = MY_PID;
1342                app.maxAdj = SYSTEM_ADJ;
1343                mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1344                synchronized (mSelf.mPidsSelfLocked) {
1345                    mSelf.mPidsSelfLocked.put(app.pid, app);
1346                }
1347                mSelf.updateLruProcessLocked(app, true, true);
1348            }
1349        } catch (PackageManager.NameNotFoundException e) {
1350            throw new RuntimeException(
1351                    "Unable to find android system package", e);
1352        }
1353    }
1354
1355    public void setWindowManager(WindowManagerService wm) {
1356        mWindowManager = wm;
1357    }
1358
1359    public static final Context main(int factoryTest) {
1360        AThread thr = new AThread();
1361        thr.start();
1362
1363        synchronized (thr) {
1364            while (thr.mService == null) {
1365                try {
1366                    thr.wait();
1367                } catch (InterruptedException e) {
1368                }
1369            }
1370        }
1371
1372        ActivityManagerService m = thr.mService;
1373        mSelf = m;
1374        ActivityThread at = ActivityThread.systemMain();
1375        mSystemThread = at;
1376        Context context = at.getSystemContext();
1377        context.setTheme(android.R.style.Theme_Holo);
1378        m.mContext = context;
1379        m.mFactoryTest = factoryTest;
1380        m.mMainStack = new ActivityStack(m, context, true);
1381
1382        m.mBatteryStatsService.publish(context);
1383        m.mUsageStatsService.publish(context);
1384
1385        synchronized (thr) {
1386            thr.mReady = true;
1387            thr.notifyAll();
1388        }
1389
1390        m.startRunning(null, null, null, null);
1391
1392        return context;
1393    }
1394
1395    public static ActivityManagerService self() {
1396        return mSelf;
1397    }
1398
1399    static class AThread extends Thread {
1400        ActivityManagerService mService;
1401        boolean mReady = false;
1402
1403        public AThread() {
1404            super("ActivityManager");
1405        }
1406
1407        public void run() {
1408            Looper.prepare();
1409
1410            android.os.Process.setThreadPriority(
1411                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1412            android.os.Process.setCanSelfBackground(false);
1413
1414            ActivityManagerService m = new ActivityManagerService();
1415
1416            synchronized (this) {
1417                mService = m;
1418                notifyAll();
1419            }
1420
1421            synchronized (this) {
1422                while (!mReady) {
1423                    try {
1424                        wait();
1425                    } catch (InterruptedException e) {
1426                    }
1427                }
1428            }
1429
1430            // For debug builds, log event loop stalls to dropbox for analysis.
1431            if (StrictMode.conditionallyEnableDebugLogging()) {
1432                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1433            }
1434
1435            Looper.loop();
1436        }
1437    }
1438
1439    static class MemBinder extends Binder {
1440        ActivityManagerService mActivityManagerService;
1441        MemBinder(ActivityManagerService activityManagerService) {
1442            mActivityManagerService = activityManagerService;
1443        }
1444
1445        @Override
1446        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1447            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args);
1448        }
1449    }
1450
1451    static class GraphicsBinder extends Binder {
1452        ActivityManagerService mActivityManagerService;
1453        GraphicsBinder(ActivityManagerService activityManagerService) {
1454            mActivityManagerService = activityManagerService;
1455        }
1456
1457        @Override
1458        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1459            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1460        }
1461    }
1462
1463    static class CpuBinder extends Binder {
1464        ActivityManagerService mActivityManagerService;
1465        CpuBinder(ActivityManagerService activityManagerService) {
1466            mActivityManagerService = activityManagerService;
1467        }
1468
1469        @Override
1470        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1471            synchronized (mActivityManagerService.mProcessStatsThread) {
1472                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1473                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1474                        SystemClock.uptimeMillis()));
1475            }
1476        }
1477    }
1478
1479    private ActivityManagerService() {
1480        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1481
1482        File dataDir = Environment.getDataDirectory();
1483        File systemDir = new File(dataDir, "system");
1484        systemDir.mkdirs();
1485        mBatteryStatsService = new BatteryStatsService(new File(
1486                systemDir, "batterystats.bin").toString());
1487        mBatteryStatsService.getActiveStatistics().readLocked();
1488        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1489        mOnBattery = DEBUG_POWER ? true
1490                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1491        mBatteryStatsService.getActiveStatistics().setCallback(this);
1492
1493        mUsageStatsService = new UsageStatsService(new File(
1494                systemDir, "usagestats").toString());
1495
1496        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1497            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1498
1499        mConfiguration.setToDefaults();
1500        mConfiguration.locale = Locale.getDefault();
1501        mProcessStats.init();
1502
1503        mCompatModePackages = new CompatModePackages(this, systemDir);
1504
1505        // Add ourself to the Watchdog monitors.
1506        Watchdog.getInstance().addMonitor(this);
1507
1508        mProcessStatsThread = new Thread("ProcessStats") {
1509            public void run() {
1510                while (true) {
1511                    try {
1512                        try {
1513                            synchronized(this) {
1514                                final long now = SystemClock.uptimeMillis();
1515                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1516                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1517                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1518                                //        + ", write delay=" + nextWriteDelay);
1519                                if (nextWriteDelay < nextCpuDelay) {
1520                                    nextCpuDelay = nextWriteDelay;
1521                                }
1522                                if (nextCpuDelay > 0) {
1523                                    mProcessStatsMutexFree.set(true);
1524                                    this.wait(nextCpuDelay);
1525                                }
1526                            }
1527                        } catch (InterruptedException e) {
1528                        }
1529                        updateCpuStatsNow();
1530                    } catch (Exception e) {
1531                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1532                    }
1533                }
1534            }
1535        };
1536        mProcessStatsThread.start();
1537    }
1538
1539    @Override
1540    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1541            throws RemoteException {
1542        try {
1543            return super.onTransact(code, data, reply, flags);
1544        } catch (RuntimeException e) {
1545            // The activity manager only throws security exceptions, so let's
1546            // log all others.
1547            if (!(e instanceof SecurityException)) {
1548                Slog.e(TAG, "Activity Manager Crash", e);
1549            }
1550            throw e;
1551        }
1552    }
1553
1554    void updateCpuStats() {
1555        final long now = SystemClock.uptimeMillis();
1556        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1557            return;
1558        }
1559        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1560            synchronized (mProcessStatsThread) {
1561                mProcessStatsThread.notify();
1562            }
1563        }
1564    }
1565
1566    void updateCpuStatsNow() {
1567        synchronized (mProcessStatsThread) {
1568            mProcessStatsMutexFree.set(false);
1569            final long now = SystemClock.uptimeMillis();
1570            boolean haveNewCpuStats = false;
1571
1572            if (MONITOR_CPU_USAGE &&
1573                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1574                mLastCpuTime.set(now);
1575                haveNewCpuStats = true;
1576                mProcessStats.update();
1577                //Slog.i(TAG, mProcessStats.printCurrentState());
1578                //Slog.i(TAG, "Total CPU usage: "
1579                //        + mProcessStats.getTotalCpuPercent() + "%");
1580
1581                // Slog the cpu usage if the property is set.
1582                if ("true".equals(SystemProperties.get("events.cpu"))) {
1583                    int user = mProcessStats.getLastUserTime();
1584                    int system = mProcessStats.getLastSystemTime();
1585                    int iowait = mProcessStats.getLastIoWaitTime();
1586                    int irq = mProcessStats.getLastIrqTime();
1587                    int softIrq = mProcessStats.getLastSoftIrqTime();
1588                    int idle = mProcessStats.getLastIdleTime();
1589
1590                    int total = user + system + iowait + irq + softIrq + idle;
1591                    if (total == 0) total = 1;
1592
1593                    EventLog.writeEvent(EventLogTags.CPU,
1594                            ((user+system+iowait+irq+softIrq) * 100) / total,
1595                            (user * 100) / total,
1596                            (system * 100) / total,
1597                            (iowait * 100) / total,
1598                            (irq * 100) / total,
1599                            (softIrq * 100) / total);
1600                }
1601            }
1602
1603            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1604            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1605            synchronized(bstats) {
1606                synchronized(mPidsSelfLocked) {
1607                    if (haveNewCpuStats) {
1608                        if (mOnBattery) {
1609                            int perc = bstats.startAddingCpuLocked();
1610                            int totalUTime = 0;
1611                            int totalSTime = 0;
1612                            final int N = mProcessStats.countStats();
1613                            for (int i=0; i<N; i++) {
1614                                ProcessStats.Stats st = mProcessStats.getStats(i);
1615                                if (!st.working) {
1616                                    continue;
1617                                }
1618                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1619                                int otherUTime = (st.rel_utime*perc)/100;
1620                                int otherSTime = (st.rel_stime*perc)/100;
1621                                totalUTime += otherUTime;
1622                                totalSTime += otherSTime;
1623                                if (pr != null) {
1624                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1625                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1626                                            st.rel_stime-otherSTime);
1627                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1628                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1629                                } else {
1630                                    BatteryStatsImpl.Uid.Proc ps =
1631                                            bstats.getProcessStatsLocked(st.name, st.pid);
1632                                    if (ps != null) {
1633                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1634                                                st.rel_stime-otherSTime);
1635                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1636                                    }
1637                                }
1638                            }
1639                            bstats.finishAddingCpuLocked(perc, totalUTime,
1640                                    totalSTime, cpuSpeedTimes);
1641                        }
1642                    }
1643                }
1644
1645                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1646                    mLastWriteTime = now;
1647                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1648                }
1649            }
1650        }
1651    }
1652
1653    @Override
1654    public void batteryNeedsCpuUpdate() {
1655        updateCpuStatsNow();
1656    }
1657
1658    @Override
1659    public void batteryPowerChanged(boolean onBattery) {
1660        // When plugging in, update the CPU stats first before changing
1661        // the plug state.
1662        updateCpuStatsNow();
1663        synchronized (this) {
1664            synchronized(mPidsSelfLocked) {
1665                mOnBattery = DEBUG_POWER ? true : onBattery;
1666            }
1667        }
1668    }
1669
1670    /**
1671     * Initialize the application bind args. These are passed to each
1672     * process when the bindApplication() IPC is sent to the process. They're
1673     * lazily setup to make sure the services are running when they're asked for.
1674     */
1675    private HashMap<String, IBinder> getCommonServicesLocked() {
1676        if (mAppBindArgs == null) {
1677            mAppBindArgs = new HashMap<String, IBinder>();
1678
1679            // Setup the application init args
1680            mAppBindArgs.put("package", ServiceManager.getService("package"));
1681            mAppBindArgs.put("window", ServiceManager.getService("window"));
1682            mAppBindArgs.put(Context.ALARM_SERVICE,
1683                    ServiceManager.getService(Context.ALARM_SERVICE));
1684        }
1685        return mAppBindArgs;
1686    }
1687
1688    final void setFocusedActivityLocked(ActivityRecord r) {
1689        if (mFocusedActivity != r) {
1690            mFocusedActivity = r;
1691            mWindowManager.setFocusedApp(r, true);
1692        }
1693    }
1694
1695    private final void updateLruProcessInternalLocked(ProcessRecord app,
1696            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1697        // put it on the LRU to keep track of when it should be exited.
1698        int lrui = mLruProcesses.indexOf(app);
1699        if (lrui >= 0) mLruProcesses.remove(lrui);
1700
1701        int i = mLruProcesses.size()-1;
1702        int skipTop = 0;
1703
1704        app.lruSeq = mLruSeq;
1705
1706        // compute the new weight for this process.
1707        if (updateActivityTime) {
1708            app.lastActivityTime = SystemClock.uptimeMillis();
1709        }
1710        if (app.activities.size() > 0) {
1711            // If this process has activities, we more strongly want to keep
1712            // it around.
1713            app.lruWeight = app.lastActivityTime;
1714        } else if (app.pubProviders.size() > 0) {
1715            // If this process contains content providers, we want to keep
1716            // it a little more strongly.
1717            app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
1718            // Also don't let it kick out the first few "real" hidden processes.
1719            skipTop = MIN_HIDDEN_APPS;
1720        } else {
1721            // If this process doesn't have activities, we less strongly
1722            // want to keep it around, and generally want to avoid getting
1723            // in front of any very recently used activities.
1724            app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
1725            // Also don't let it kick out the first few "real" hidden processes.
1726            skipTop = MIN_HIDDEN_APPS;
1727        }
1728
1729        while (i >= 0) {
1730            ProcessRecord p = mLruProcesses.get(i);
1731            // If this app shouldn't be in front of the first N background
1732            // apps, then skip over that many that are currently hidden.
1733            if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
1734                skipTop--;
1735            }
1736            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1737                mLruProcesses.add(i+1, app);
1738                break;
1739            }
1740            i--;
1741        }
1742        if (i < 0) {
1743            mLruProcesses.add(0, app);
1744        }
1745
1746        // If the app is currently using a content provider or service,
1747        // bump those processes as well.
1748        if (app.connections.size() > 0) {
1749            for (ConnectionRecord cr : app.connections) {
1750                if (cr.binding != null && cr.binding.service != null
1751                        && cr.binding.service.app != null
1752                        && cr.binding.service.app.lruSeq != mLruSeq) {
1753                    updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1754                            updateActivityTime, i+1);
1755                }
1756            }
1757        }
1758        if (app.conProviders.size() > 0) {
1759            for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1760                if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1761                    updateLruProcessInternalLocked(cpr.app, oomAdj,
1762                            updateActivityTime, i+1);
1763                }
1764            }
1765        }
1766
1767        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1768        if (oomAdj) {
1769            updateOomAdjLocked();
1770        }
1771    }
1772
1773    final void updateLruProcessLocked(ProcessRecord app,
1774            boolean oomAdj, boolean updateActivityTime) {
1775        mLruSeq++;
1776        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1777    }
1778
1779    final ProcessRecord getProcessRecordLocked(
1780            String processName, int uid) {
1781        if (uid == Process.SYSTEM_UID) {
1782            // The system gets to run in any process.  If there are multiple
1783            // processes with the same uid, just pick the first (this
1784            // should never happen).
1785            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1786                    processName);
1787            return procs != null ? procs.valueAt(0) : null;
1788        }
1789        ProcessRecord proc = mProcessNames.get(processName, uid);
1790        return proc;
1791    }
1792
1793    void ensurePackageDexOpt(String packageName) {
1794        IPackageManager pm = AppGlobals.getPackageManager();
1795        try {
1796            if (pm.performDexOpt(packageName)) {
1797                mDidDexOpt = true;
1798            }
1799        } catch (RemoteException e) {
1800        }
1801    }
1802
1803    boolean isNextTransitionForward() {
1804        int transit = mWindowManager.getPendingAppTransition();
1805        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1806                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1807                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1808    }
1809
1810    final ProcessRecord startProcessLocked(String processName,
1811            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1812            String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
1813        ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1814        // We don't have to do anything more if:
1815        // (1) There is an existing application record; and
1816        // (2) The caller doesn't think it is dead, OR there is no thread
1817        //     object attached to it so we know it couldn't have crashed; and
1818        // (3) There is a pid assigned to it, so it is either starting or
1819        //     already running.
1820        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1821                + " app=" + app + " knownToBeDead=" + knownToBeDead
1822                + " thread=" + (app != null ? app.thread : null)
1823                + " pid=" + (app != null ? app.pid : -1));
1824        if (app != null && app.pid > 0) {
1825            if (!knownToBeDead || app.thread == null) {
1826                // We already have the app running, or are waiting for it to
1827                // come up (we have a pid but not yet its thread), so keep it.
1828                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1829                return app;
1830            } else {
1831                // An application record is attached to a previous process,
1832                // clean it up now.
1833                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1834                handleAppDiedLocked(app, true);
1835            }
1836        }
1837
1838        String hostingNameStr = hostingName != null
1839                ? hostingName.flattenToShortString() : null;
1840
1841        if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1842            // If we are in the background, then check to see if this process
1843            // is bad.  If so, we will just silently fail.
1844            if (mBadProcesses.get(info.processName, info.uid) != null) {
1845                if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1846                        + "/" + info.processName);
1847                return null;
1848            }
1849        } else {
1850            // When the user is explicitly starting a process, then clear its
1851            // crash count so that we won't make it bad until they see at
1852            // least one crash dialog again, and make the process good again
1853            // if it had been bad.
1854            if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1855                    + "/" + info.processName);
1856            mProcessCrashTimes.remove(info.processName, info.uid);
1857            if (mBadProcesses.get(info.processName, info.uid) != null) {
1858                EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1859                        info.processName);
1860                mBadProcesses.remove(info.processName, info.uid);
1861                if (app != null) {
1862                    app.bad = false;
1863                }
1864            }
1865        }
1866
1867        if (app == null) {
1868            app = newProcessRecordLocked(null, info, processName);
1869            mProcessNames.put(processName, info.uid, app);
1870        } else {
1871            // If this is a new package in the process, add the package to the list
1872            app.addPackage(info.packageName);
1873        }
1874
1875        // If the system is not ready yet, then hold off on starting this
1876        // process until it is.
1877        if (!mProcessesReady
1878                && !isAllowedWhileBooting(info)
1879                && !allowWhileBooting) {
1880            if (!mProcessesOnHold.contains(app)) {
1881                mProcessesOnHold.add(app);
1882            }
1883            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1884            return app;
1885        }
1886
1887        startProcessLocked(app, hostingType, hostingNameStr);
1888        return (app.pid != 0) ? app : null;
1889    }
1890
1891    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1892        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1893    }
1894
1895    private final void startProcessLocked(ProcessRecord app,
1896            String hostingType, String hostingNameStr) {
1897        if (app.pid > 0 && app.pid != MY_PID) {
1898            synchronized (mPidsSelfLocked) {
1899                mPidsSelfLocked.remove(app.pid);
1900                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1901            }
1902            app.pid = 0;
1903        }
1904
1905        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1906                "startProcessLocked removing on hold: " + app);
1907        mProcessesOnHold.remove(app);
1908
1909        updateCpuStats();
1910
1911        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1912        mProcDeaths[0] = 0;
1913
1914        try {
1915            int uid = app.info.uid;
1916            int[] gids = null;
1917            try {
1918                gids = mContext.getPackageManager().getPackageGids(
1919                        app.info.packageName);
1920            } catch (PackageManager.NameNotFoundException e) {
1921                Slog.w(TAG, "Unable to retrieve gids", e);
1922            }
1923            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1924                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1925                        && mTopComponent != null
1926                        && app.processName.equals(mTopComponent.getPackageName())) {
1927                    uid = 0;
1928                }
1929                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1930                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1931                    uid = 0;
1932                }
1933            }
1934            int debugFlags = 0;
1935            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1936                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1937            }
1938            // Run the app in safe mode if its manifest requests so or the
1939            // system is booted in safe mode.
1940            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1941                Zygote.systemInSafeMode == true) {
1942                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1943            }
1944            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1945                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1946            }
1947            if ("1".equals(SystemProperties.get("debug.assert"))) {
1948                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1949            }
1950            int pid = Process.start("android.app.ActivityThread",
1951                    app.processName, uid, uid, gids, debugFlags, null);
1952            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1953            synchronized (bs) {
1954                if (bs.isOnBattery()) {
1955                    app.batteryStats.incStartsLocked();
1956                }
1957            }
1958
1959            EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
1960                    app.processName, hostingType,
1961                    hostingNameStr != null ? hostingNameStr : "");
1962
1963            if (app.persistent) {
1964                Watchdog.getInstance().processStarted(app.processName, pid);
1965            }
1966
1967            StringBuilder buf = mStringBuilder;
1968            buf.setLength(0);
1969            buf.append("Start proc ");
1970            buf.append(app.processName);
1971            buf.append(" for ");
1972            buf.append(hostingType);
1973            if (hostingNameStr != null) {
1974                buf.append(" ");
1975                buf.append(hostingNameStr);
1976            }
1977            buf.append(": pid=");
1978            buf.append(pid);
1979            buf.append(" uid=");
1980            buf.append(uid);
1981            buf.append(" gids={");
1982            if (gids != null) {
1983                for (int gi=0; gi<gids.length; gi++) {
1984                    if (gi != 0) buf.append(", ");
1985                    buf.append(gids[gi]);
1986
1987                }
1988            }
1989            buf.append("}");
1990            Slog.i(TAG, buf.toString());
1991            if (pid == 0 || pid == MY_PID) {
1992                // Processes are being emulated with threads.
1993                app.pid = MY_PID;
1994                app.removed = false;
1995                mStartingProcesses.add(app);
1996            } else if (pid > 0) {
1997                app.pid = pid;
1998                app.removed = false;
1999                synchronized (mPidsSelfLocked) {
2000                    this.mPidsSelfLocked.put(pid, app);
2001                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2002                    msg.obj = app;
2003                    mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
2004                }
2005            } else {
2006                app.pid = 0;
2007                RuntimeException e = new RuntimeException(
2008                        "Failure starting process " + app.processName
2009                        + ": returned pid=" + pid);
2010                Slog.e(TAG, e.getMessage(), e);
2011            }
2012        } catch (RuntimeException e) {
2013            // XXX do better error recovery.
2014            app.pid = 0;
2015            Slog.e(TAG, "Failure starting process " + app.processName, e);
2016        }
2017    }
2018
2019    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2020        if (resumed) {
2021            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2022        } else {
2023            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2024        }
2025    }
2026
2027    boolean startHomeActivityLocked() {
2028        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2029                && mTopAction == null) {
2030            // We are running in factory test mode, but unable to find
2031            // the factory test app, so just sit around displaying the
2032            // error message and don't try to start anything.
2033            return false;
2034        }
2035        Intent intent = new Intent(
2036            mTopAction,
2037            mTopData != null ? Uri.parse(mTopData) : null);
2038        intent.setComponent(mTopComponent);
2039        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2040            intent.addCategory(Intent.CATEGORY_HOME);
2041        }
2042        ActivityInfo aInfo =
2043            intent.resolveActivityInfo(mContext.getPackageManager(),
2044                    STOCK_PM_FLAGS);
2045        if (aInfo != null) {
2046            intent.setComponent(new ComponentName(
2047                    aInfo.applicationInfo.packageName, aInfo.name));
2048            // Don't do this if the home app is currently being
2049            // instrumented.
2050            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2051                    aInfo.applicationInfo.uid);
2052            if (app == null || app.instrumentationClass == null) {
2053                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2054                mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
2055                        null, null, 0, 0, 0, false, false, null);
2056            }
2057        }
2058
2059
2060        return true;
2061    }
2062
2063    /**
2064     * Starts the "new version setup screen" if appropriate.
2065     */
2066    void startSetupActivityLocked() {
2067        // Only do this once per boot.
2068        if (mCheckedForSetup) {
2069            return;
2070        }
2071
2072        // We will show this screen if the current one is a different
2073        // version than the last one shown, and we are not running in
2074        // low-level factory test mode.
2075        final ContentResolver resolver = mContext.getContentResolver();
2076        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2077                Settings.Secure.getInt(resolver,
2078                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2079            mCheckedForSetup = true;
2080
2081            // See if we should be showing the platform update setup UI.
2082            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2083            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2084                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2085
2086            // We don't allow third party apps to replace this.
2087            ResolveInfo ri = null;
2088            for (int i=0; ris != null && i<ris.size(); i++) {
2089                if ((ris.get(i).activityInfo.applicationInfo.flags
2090                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2091                    ri = ris.get(i);
2092                    break;
2093                }
2094            }
2095
2096            if (ri != null) {
2097                String vers = ri.activityInfo.metaData != null
2098                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2099                        : null;
2100                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2101                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2102                            Intent.METADATA_SETUP_VERSION);
2103                }
2104                String lastVers = Settings.Secure.getString(
2105                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2106                if (vers != null && !vers.equals(lastVers)) {
2107                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2108                    intent.setComponent(new ComponentName(
2109                            ri.activityInfo.packageName, ri.activityInfo.name));
2110                    mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
2111                            null, null, 0, 0, 0, false, false, null);
2112                }
2113            }
2114        }
2115    }
2116
2117    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2118        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2119    }
2120
2121    public int getFrontActivityScreenCompatMode() {
2122        synchronized (this) {
2123            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2124        }
2125    }
2126
2127    public void setFrontActivityScreenCompatMode(int mode) {
2128        synchronized (this) {
2129            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2130        }
2131    }
2132
2133    public int getPackageScreenCompatMode(String packageName) {
2134        synchronized (this) {
2135            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2136        }
2137    }
2138
2139    public void setPackageScreenCompatMode(String packageName, int mode) {
2140        synchronized (this) {
2141            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2142        }
2143    }
2144
2145    public boolean getPackageAskScreenCompat(String packageName) {
2146        synchronized (this) {
2147            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2148        }
2149    }
2150
2151    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2152        synchronized (this) {
2153            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2154        }
2155    }
2156
2157    void reportResumedActivityLocked(ActivityRecord r) {
2158        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2159
2160        final int identHash = System.identityHashCode(r);
2161        updateUsageStats(r, true);
2162
2163        int i = mWatchers.beginBroadcast();
2164        while (i > 0) {
2165            i--;
2166            IActivityWatcher w = mWatchers.getBroadcastItem(i);
2167            if (w != null) {
2168                try {
2169                    w.activityResuming(identHash);
2170                } catch (RemoteException e) {
2171                }
2172            }
2173        }
2174        mWatchers.finishBroadcast();
2175    }
2176
2177    private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2178        int i = mProcessObservers.beginBroadcast();
2179        while (i > 0) {
2180            i--;
2181            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2182            if (observer != null) {
2183                try {
2184                    observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2185                } catch (RemoteException e) {
2186                }
2187            }
2188        }
2189        mProcessObservers.finishBroadcast();
2190    }
2191
2192    private void dispatchProcessDied(int pid, int uid) {
2193        int i = mProcessObservers.beginBroadcast();
2194        while (i > 0) {
2195            i--;
2196            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2197            if (observer != null) {
2198                try {
2199                    observer.onProcessDied(pid, uid);
2200                } catch (RemoteException e) {
2201                }
2202            }
2203        }
2204        mProcessObservers.finishBroadcast();
2205    }
2206
2207    final void doPendingActivityLaunchesLocked(boolean doResume) {
2208        final int N = mPendingActivityLaunches.size();
2209        if (N <= 0) {
2210            return;
2211        }
2212        for (int i=0; i<N; i++) {
2213            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2214            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2215                    pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2216                    doResume && i == (N-1));
2217        }
2218        mPendingActivityLaunches.clear();
2219    }
2220
2221    public final int startActivity(IApplicationThread caller,
2222            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2223            int grantedMode, IBinder resultTo,
2224            String resultWho, int requestCode, boolean onlyIfNeeded,
2225            boolean debug) {
2226        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2227                grantedUriPermissions, grantedMode, resultTo, resultWho,
2228                requestCode, onlyIfNeeded, debug, null, null);
2229    }
2230
2231    public final WaitResult startActivityAndWait(IApplicationThread caller,
2232            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2233            int grantedMode, IBinder resultTo,
2234            String resultWho, int requestCode, boolean onlyIfNeeded,
2235            boolean debug) {
2236        WaitResult res = new WaitResult();
2237        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2238                grantedUriPermissions, grantedMode, resultTo, resultWho,
2239                requestCode, onlyIfNeeded, debug, res, null);
2240        return res;
2241    }
2242
2243    public final int startActivityWithConfig(IApplicationThread caller,
2244            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2245            int grantedMode, IBinder resultTo,
2246            String resultWho, int requestCode, boolean onlyIfNeeded,
2247            boolean debug, Configuration config) {
2248        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2249                grantedUriPermissions, grantedMode, resultTo, resultWho,
2250                requestCode, onlyIfNeeded, debug, null, config);
2251    }
2252
2253    public int startActivityIntentSender(IApplicationThread caller,
2254            IntentSender intent, Intent fillInIntent, String resolvedType,
2255            IBinder resultTo, String resultWho, int requestCode,
2256            int flagsMask, int flagsValues) {
2257        // Refuse possible leaked file descriptors
2258        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2259            throw new IllegalArgumentException("File descriptors passed in Intent");
2260        }
2261
2262        IIntentSender sender = intent.getTarget();
2263        if (!(sender instanceof PendingIntentRecord)) {
2264            throw new IllegalArgumentException("Bad PendingIntent object");
2265        }
2266
2267        PendingIntentRecord pir = (PendingIntentRecord)sender;
2268
2269        synchronized (this) {
2270            // If this is coming from the currently resumed activity, it is
2271            // effectively saying that app switches are allowed at this point.
2272            if (mMainStack.mResumedActivity != null
2273                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2274                            Binder.getCallingUid()) {
2275                mAppSwitchesAllowedTime = 0;
2276            }
2277        }
2278
2279        return pir.sendInner(0, fillInIntent, resolvedType,
2280                null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2281    }
2282
2283    public boolean startNextMatchingActivity(IBinder callingActivity,
2284            Intent intent) {
2285        // Refuse possible leaked file descriptors
2286        if (intent != null && intent.hasFileDescriptors() == true) {
2287            throw new IllegalArgumentException("File descriptors passed in Intent");
2288        }
2289
2290        synchronized (this) {
2291            int index = mMainStack.indexOfTokenLocked(callingActivity);
2292            if (index < 0) {
2293                return false;
2294            }
2295            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
2296            if (r.app == null || r.app.thread == null) {
2297                // The caller is not running...  d'oh!
2298                return false;
2299            }
2300            intent = new Intent(intent);
2301            // The caller is not allowed to change the data.
2302            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2303            // And we are resetting to find the next component...
2304            intent.setComponent(null);
2305
2306            ActivityInfo aInfo = null;
2307            try {
2308                List<ResolveInfo> resolves =
2309                    AppGlobals.getPackageManager().queryIntentActivities(
2310                            intent, r.resolvedType,
2311                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
2312
2313                // Look for the original activity in the list...
2314                final int N = resolves != null ? resolves.size() : 0;
2315                for (int i=0; i<N; i++) {
2316                    ResolveInfo rInfo = resolves.get(i);
2317                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2318                            && rInfo.activityInfo.name.equals(r.info.name)) {
2319                        // We found the current one...  the next matching is
2320                        // after it.
2321                        i++;
2322                        if (i<N) {
2323                            aInfo = resolves.get(i).activityInfo;
2324                        }
2325                        break;
2326                    }
2327                }
2328            } catch (RemoteException e) {
2329            }
2330
2331            if (aInfo == null) {
2332                // Nobody who is next!
2333                return false;
2334            }
2335
2336            intent.setComponent(new ComponentName(
2337                    aInfo.applicationInfo.packageName, aInfo.name));
2338            intent.setFlags(intent.getFlags()&~(
2339                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2340                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2341                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2342                    Intent.FLAG_ACTIVITY_NEW_TASK));
2343
2344            // Okay now we need to start the new activity, replacing the
2345            // currently running activity.  This is a little tricky because
2346            // we want to start the new one as if the current one is finished,
2347            // but not finish the current one first so that there is no flicker.
2348            // And thus...
2349            final boolean wasFinishing = r.finishing;
2350            r.finishing = true;
2351
2352            // Propagate reply information over to the new activity.
2353            final ActivityRecord resultTo = r.resultTo;
2354            final String resultWho = r.resultWho;
2355            final int requestCode = r.requestCode;
2356            r.resultTo = null;
2357            if (resultTo != null) {
2358                resultTo.removeResultsLocked(r, resultWho, requestCode);
2359            }
2360
2361            final long origId = Binder.clearCallingIdentity();
2362            // XXX we are not dealing with propagating grantedUriPermissions...
2363            // those are not yet exposed to user code, so there is no need.
2364            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2365                    r.resolvedType, null, 0, aInfo, resultTo, resultWho,
2366                    requestCode, -1, r.launchedFromUid, false, false, null);
2367            Binder.restoreCallingIdentity(origId);
2368
2369            r.finishing = wasFinishing;
2370            if (res != START_SUCCESS) {
2371                return false;
2372            }
2373            return true;
2374        }
2375    }
2376
2377    public final int startActivityInPackage(int uid,
2378            Intent intent, String resolvedType, IBinder resultTo,
2379            String resultWho, int requestCode, boolean onlyIfNeeded) {
2380
2381        // This is so super not safe, that only the system (or okay root)
2382        // can do it.
2383        final int callingUid = Binder.getCallingUid();
2384        if (callingUid != 0 && callingUid != Process.myUid()) {
2385            throw new SecurityException(
2386                    "startActivityInPackage only available to the system");
2387        }
2388
2389        return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2390                null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false, null, null);
2391    }
2392
2393    public final int startActivities(IApplicationThread caller,
2394            Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2395        return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2396    }
2397
2398    public final int startActivitiesInPackage(int uid,
2399            Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2400
2401        // This is so super not safe, that only the system (or okay root)
2402        // can do it.
2403        final int callingUid = Binder.getCallingUid();
2404        if (callingUid != 0 && callingUid != Process.myUid()) {
2405            throw new SecurityException(
2406                    "startActivityInPackage only available to the system");
2407        }
2408
2409        return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
2410    }
2411
2412    final void addRecentTaskLocked(TaskRecord task) {
2413        int N = mRecentTasks.size();
2414        // Quick case: check if the top-most recent task is the same.
2415        if (N > 0 && mRecentTasks.get(0) == task) {
2416            return;
2417        }
2418        // Remove any existing entries that are the same kind of task.
2419        for (int i=0; i<N; i++) {
2420            TaskRecord tr = mRecentTasks.get(i);
2421            if ((task.affinity != null && task.affinity.equals(tr.affinity))
2422                    || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2423                mRecentTasks.remove(i);
2424                i--;
2425                N--;
2426                if (task.intent == null) {
2427                    // If the new recent task we are adding is not fully
2428                    // specified, then replace it with the existing recent task.
2429                    task = tr;
2430                }
2431            }
2432        }
2433        if (N >= MAX_RECENT_TASKS) {
2434            mRecentTasks.remove(N-1);
2435        }
2436        mRecentTasks.add(0, task);
2437    }
2438
2439    public void setRequestedOrientation(IBinder token,
2440            int requestedOrientation) {
2441        synchronized (this) {
2442            int index = mMainStack.indexOfTokenLocked(token);
2443            if (index < 0) {
2444                return;
2445            }
2446            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
2447            final long origId = Binder.clearCallingIdentity();
2448            mWindowManager.setAppOrientation(r, requestedOrientation);
2449            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2450                    mConfiguration,
2451                    r.mayFreezeScreenLocked(r.app) ? r : null);
2452            if (config != null) {
2453                r.frozenBeforeDestroy = true;
2454                if (!updateConfigurationLocked(config, r)) {
2455                    mMainStack.resumeTopActivityLocked(null);
2456                }
2457            }
2458            Binder.restoreCallingIdentity(origId);
2459        }
2460    }
2461
2462    public int getRequestedOrientation(IBinder token) {
2463        synchronized (this) {
2464            int index = mMainStack.indexOfTokenLocked(token);
2465            if (index < 0) {
2466                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2467            }
2468            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
2469            return mWindowManager.getAppOrientation(r);
2470        }
2471    }
2472
2473    /**
2474     * This is the internal entry point for handling Activity.finish().
2475     *
2476     * @param token The Binder token referencing the Activity we want to finish.
2477     * @param resultCode Result code, if any, from this Activity.
2478     * @param resultData Result data (Intent), if any, from this Activity.
2479     *
2480     * @return Returns true if the activity successfully finished, or false if it is still running.
2481     */
2482    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2483        // Refuse possible leaked file descriptors
2484        if (resultData != null && resultData.hasFileDescriptors() == true) {
2485            throw new IllegalArgumentException("File descriptors passed in Intent");
2486        }
2487
2488        synchronized(this) {
2489            if (mController != null) {
2490                // Find the first activity that is not finishing.
2491                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2492                if (next != null) {
2493                    // ask watcher if this is allowed
2494                    boolean resumeOK = true;
2495                    try {
2496                        resumeOK = mController.activityResuming(next.packageName);
2497                    } catch (RemoteException e) {
2498                        mController = null;
2499                    }
2500
2501                    if (!resumeOK) {
2502                        return false;
2503                    }
2504                }
2505            }
2506            final long origId = Binder.clearCallingIdentity();
2507            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2508                    resultData, "app-request");
2509            Binder.restoreCallingIdentity(origId);
2510            return res;
2511        }
2512    }
2513
2514    public final void finishHeavyWeightApp() {
2515        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2516                != PackageManager.PERMISSION_GRANTED) {
2517            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2518                    + Binder.getCallingPid()
2519                    + ", uid=" + Binder.getCallingUid()
2520                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2521            Slog.w(TAG, msg);
2522            throw new SecurityException(msg);
2523        }
2524
2525        synchronized(this) {
2526            if (mHeavyWeightProcess == null) {
2527                return;
2528            }
2529
2530            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2531                    mHeavyWeightProcess.activities);
2532            for (int i=0; i<activities.size(); i++) {
2533                ActivityRecord r = activities.get(i);
2534                if (!r.finishing) {
2535                    int index = mMainStack.indexOfTokenLocked(r);
2536                    if (index >= 0) {
2537                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2538                                null, "finish-heavy");
2539                    }
2540                }
2541            }
2542
2543            mHeavyWeightProcess = null;
2544            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2545        }
2546    }
2547
2548    public void crashApplication(int uid, int initialPid, String packageName,
2549            String message) {
2550        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2551                != PackageManager.PERMISSION_GRANTED) {
2552            String msg = "Permission Denial: crashApplication() from pid="
2553                    + Binder.getCallingPid()
2554                    + ", uid=" + Binder.getCallingUid()
2555                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2556            Slog.w(TAG, msg);
2557            throw new SecurityException(msg);
2558        }
2559
2560        synchronized(this) {
2561            ProcessRecord proc = null;
2562
2563            // Figure out which process to kill.  We don't trust that initialPid
2564            // still has any relation to current pids, so must scan through the
2565            // list.
2566            synchronized (mPidsSelfLocked) {
2567                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2568                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2569                    if (p.info.uid != uid) {
2570                        continue;
2571                    }
2572                    if (p.pid == initialPid) {
2573                        proc = p;
2574                        break;
2575                    }
2576                    for (String str : p.pkgList) {
2577                        if (str.equals(packageName)) {
2578                            proc = p;
2579                        }
2580                    }
2581                }
2582            }
2583
2584            if (proc == null) {
2585                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2586                        + " initialPid=" + initialPid
2587                        + " packageName=" + packageName);
2588                return;
2589            }
2590
2591            if (proc.thread != null) {
2592                if (proc.pid == Process.myPid()) {
2593                    Log.w(TAG, "crashApplication: trying to crash self!");
2594                    return;
2595                }
2596                long ident = Binder.clearCallingIdentity();
2597                try {
2598                    proc.thread.scheduleCrash(message);
2599                } catch (RemoteException e) {
2600                }
2601                Binder.restoreCallingIdentity(ident);
2602            }
2603        }
2604    }
2605
2606    public final void finishSubActivity(IBinder token, String resultWho,
2607            int requestCode) {
2608        synchronized(this) {
2609            int index = mMainStack.indexOfTokenLocked(token);
2610            if (index < 0) {
2611                return;
2612            }
2613            ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
2614
2615            final long origId = Binder.clearCallingIdentity();
2616
2617            int i;
2618            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2619                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2620                if (r.resultTo == self && r.requestCode == requestCode) {
2621                    if ((r.resultWho == null && resultWho == null) ||
2622                        (r.resultWho != null && r.resultWho.equals(resultWho))) {
2623                        mMainStack.finishActivityLocked(r, i,
2624                                Activity.RESULT_CANCELED, null, "request-sub");
2625                    }
2626                }
2627            }
2628
2629            Binder.restoreCallingIdentity(origId);
2630        }
2631    }
2632
2633    public boolean willActivityBeVisible(IBinder token) {
2634        synchronized(this) {
2635            int i;
2636            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2637                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2638                if (r == token) {
2639                    return true;
2640                }
2641                if (r.fullscreen && !r.finishing) {
2642                    return false;
2643                }
2644            }
2645            return true;
2646        }
2647    }
2648
2649    public void overridePendingTransition(IBinder token, String packageName,
2650            int enterAnim, int exitAnim) {
2651        synchronized(this) {
2652            int index = mMainStack.indexOfTokenLocked(token);
2653            if (index < 0) {
2654                return;
2655            }
2656            ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
2657
2658            final long origId = Binder.clearCallingIdentity();
2659
2660            if (self.state == ActivityState.RESUMED
2661                    || self.state == ActivityState.PAUSING) {
2662                mWindowManager.overridePendingAppTransition(packageName,
2663                        enterAnim, exitAnim);
2664            }
2665
2666            Binder.restoreCallingIdentity(origId);
2667        }
2668    }
2669
2670    /**
2671     * Main function for removing an existing process from the activity manager
2672     * as a result of that process going away.  Clears out all connections
2673     * to the process.
2674     */
2675    private final void handleAppDiedLocked(ProcessRecord app,
2676            boolean restarting) {
2677        cleanUpApplicationRecordLocked(app, restarting, -1);
2678        if (!restarting) {
2679            mLruProcesses.remove(app);
2680        }
2681
2682        // Just in case...
2683        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2684            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2685            mMainStack.mPausingActivity = null;
2686        }
2687        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2688            mMainStack.mLastPausedActivity = null;
2689        }
2690
2691        // Remove this application's activities from active lists.
2692        mMainStack.removeHistoryRecordsForAppLocked(app);
2693
2694        boolean atTop = true;
2695        boolean hasVisibleActivities = false;
2696
2697        // Clean out the history list.
2698        int i = mMainStack.mHistory.size();
2699        if (localLOGV) Slog.v(
2700            TAG, "Removing app " + app + " from history with " + i + " entries");
2701        while (i > 0) {
2702            i--;
2703            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2704            if (localLOGV) Slog.v(
2705                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2706            if (r.app == app) {
2707                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2708                    if (localLOGV) Slog.v(
2709                        TAG, "Removing this entry!  frozen=" + r.haveState
2710                        + " finishing=" + r.finishing);
2711                    r.makeFinishing();
2712                    mMainStack.mHistory.remove(i);
2713                    r.takeFromHistory();
2714                    mWindowManager.removeAppToken(r);
2715                    if (VALIDATE_TOKENS) {
2716                        mWindowManager.validateAppTokens(mMainStack.mHistory);
2717                    }
2718                    r.removeUriPermissionsLocked();
2719
2720                } else {
2721                    // We have the current state for this activity, so
2722                    // it can be restarted later when needed.
2723                    if (localLOGV) Slog.v(
2724                        TAG, "Keeping entry, setting app to null");
2725                    if (r.visible) {
2726                        hasVisibleActivities = true;
2727                    }
2728                    r.app = null;
2729                    r.nowVisible = false;
2730                    if (!r.haveState) {
2731                        r.icicle = null;
2732                    }
2733                }
2734
2735                r.stack.cleanUpActivityLocked(r, true);
2736                r.state = ActivityState.STOPPED;
2737            }
2738            atTop = false;
2739        }
2740
2741        app.activities.clear();
2742
2743        if (app.instrumentationClass != null) {
2744            Slog.w(TAG, "Crash of app " + app.processName
2745                  + " running instrumentation " + app.instrumentationClass);
2746            Bundle info = new Bundle();
2747            info.putString("shortMsg", "Process crashed.");
2748            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2749        }
2750
2751        if (!restarting) {
2752            if (!mMainStack.resumeTopActivityLocked(null)) {
2753                // If there was nothing to resume, and we are not already
2754                // restarting this process, but there is a visible activity that
2755                // is hosted by the process...  then make sure all visible
2756                // activities are running, taking care of restarting this
2757                // process.
2758                if (hasVisibleActivities) {
2759                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2760                }
2761            }
2762        }
2763    }
2764
2765    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2766        IBinder threadBinder = thread.asBinder();
2767
2768        // Find the application record.
2769        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2770            ProcessRecord rec = mLruProcesses.get(i);
2771            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2772                return i;
2773            }
2774        }
2775        return -1;
2776    }
2777
2778    final ProcessRecord getRecordForAppLocked(
2779            IApplicationThread thread) {
2780        if (thread == null) {
2781            return null;
2782        }
2783
2784        int appIndex = getLRURecordIndexForAppLocked(thread);
2785        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2786    }
2787
2788    final void appDiedLocked(ProcessRecord app, int pid,
2789            IApplicationThread thread) {
2790
2791        mProcDeaths[0]++;
2792
2793        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2794        synchronized (stats) {
2795            stats.noteProcessDiedLocked(app.info.uid, pid);
2796        }
2797
2798        // Clean up already done if the process has been re-started.
2799        if (app.pid == pid && app.thread != null &&
2800                app.thread.asBinder() == thread.asBinder()) {
2801            if (!app.killedBackground) {
2802                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2803                        + ") has died.");
2804            }
2805            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2806            if (localLOGV) Slog.v(
2807                TAG, "Dying app: " + app + ", pid: " + pid
2808                + ", thread: " + thread.asBinder());
2809            boolean doLowMem = app.instrumentationClass == null;
2810            handleAppDiedLocked(app, false);
2811
2812            if (doLowMem) {
2813                // If there are no longer any background processes running,
2814                // and the app that died was not running instrumentation,
2815                // then tell everyone we are now low on memory.
2816                boolean haveBg = false;
2817                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2818                    ProcessRecord rec = mLruProcesses.get(i);
2819                    if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
2820                        haveBg = true;
2821                        break;
2822                    }
2823                }
2824
2825                if (!haveBg) {
2826                    Slog.i(TAG, "Low Memory: No more background processes.");
2827                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2828                    long now = SystemClock.uptimeMillis();
2829                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2830                        ProcessRecord rec = mLruProcesses.get(i);
2831                        if (rec != app && rec.thread != null &&
2832                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2833                            // The low memory report is overriding any current
2834                            // state for a GC request.  Make sure to do
2835                            // heavy/important/visible/foreground processes first.
2836                            if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) {
2837                                rec.lastRequestedGc = 0;
2838                            } else {
2839                                rec.lastRequestedGc = rec.lastLowMemory;
2840                            }
2841                            rec.reportLowMemory = true;
2842                            rec.lastLowMemory = now;
2843                            mProcessesToGc.remove(rec);
2844                            addProcessToGcListLocked(rec);
2845                        }
2846                    }
2847                    scheduleAppGcsLocked();
2848                }
2849            }
2850        } else if (app.pid != pid) {
2851            // A new process has already been started.
2852            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2853                    + ") has died and restarted (pid " + app.pid + ").");
2854            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2855        } else if (DEBUG_PROCESSES) {
2856            Slog.d(TAG, "Received spurious death notification for thread "
2857                    + thread.asBinder());
2858        }
2859    }
2860
2861    /**
2862     * If a stack trace dump file is configured, dump process stack traces.
2863     * @param clearTraces causes the dump file to be erased prior to the new
2864     *    traces being written, if true; when false, the new traces will be
2865     *    appended to any existing file content.
2866     * @param firstPids of dalvik VM processes to dump stack traces for first
2867     * @param lastPids of dalvik VM processes to dump stack traces for last
2868     * @return file containing stack traces, or null if no dump file is configured
2869     */
2870    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2871            ProcessStats processStats, SparseArray<Boolean> lastPids) {
2872        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2873        if (tracesPath == null || tracesPath.length() == 0) {
2874            return null;
2875        }
2876
2877        File tracesFile = new File(tracesPath);
2878        try {
2879            File tracesDir = tracesFile.getParentFile();
2880            if (!tracesDir.exists()) tracesFile.mkdirs();
2881            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
2882
2883            if (clearTraces && tracesFile.exists()) tracesFile.delete();
2884            tracesFile.createNewFile();
2885            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2886        } catch (IOException e) {
2887            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
2888            return null;
2889        }
2890
2891        // Use a FileObserver to detect when traces finish writing.
2892        // The order of traces is considered important to maintain for legibility.
2893        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2894            public synchronized void onEvent(int event, String path) { notify(); }
2895        };
2896
2897        try {
2898            observer.startWatching();
2899
2900            // First collect all of the stacks of the most important pids.
2901            try {
2902                int num = firstPids.size();
2903                for (int i = 0; i < num; i++) {
2904                    synchronized (observer) {
2905                        Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2906                        observer.wait(200);  // Wait for write-close, give up after 200msec
2907                    }
2908                }
2909            } catch (InterruptedException e) {
2910                Log.wtf(TAG, e);
2911            }
2912
2913            // Next measure CPU usage.
2914            if (processStats != null) {
2915                processStats.init();
2916                System.gc();
2917                processStats.update();
2918                try {
2919                    synchronized (processStats) {
2920                        processStats.wait(500); // measure over 1/2 second.
2921                    }
2922                } catch (InterruptedException e) {
2923                }
2924                processStats.update();
2925
2926                // We'll take the stack crawls of just the top apps using CPU.
2927                final int N = processStats.countWorkingStats();
2928                int numProcs = 0;
2929                for (int i=0; i<N && numProcs<5; i++) {
2930                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
2931                    if (lastPids.indexOfKey(stats.pid) >= 0) {
2932                        numProcs++;
2933                        try {
2934                            synchronized (observer) {
2935                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2936                                observer.wait(200);  // Wait for write-close, give up after 200msec
2937                            }
2938                        } catch (InterruptedException e) {
2939                            Log.wtf(TAG, e);
2940                        }
2941
2942                    }
2943                }
2944            }
2945
2946            return tracesFile;
2947
2948        } finally {
2949            observer.stopWatching();
2950        }
2951    }
2952
2953    private final class AppNotResponding implements Runnable {
2954        private final ProcessRecord mApp;
2955        private final String mAnnotation;
2956
2957        public AppNotResponding(ProcessRecord app, String annotation) {
2958            mApp = app;
2959            mAnnotation = annotation;
2960        }
2961
2962        @Override
2963        public void run() {
2964            appNotResponding(mApp, null, null, mAnnotation);
2965        }
2966    }
2967
2968    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2969            ActivityRecord parent, final String annotation) {
2970        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2971        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2972
2973        if (mController != null) {
2974            try {
2975                // 0 == continue, -1 = kill process immediately
2976                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2977                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2978            } catch (RemoteException e) {
2979                mController = null;
2980            }
2981        }
2982
2983        long anrTime = SystemClock.uptimeMillis();
2984        if (MONITOR_CPU_USAGE) {
2985            updateCpuStatsNow();
2986        }
2987
2988        synchronized (this) {
2989            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2990            if (mShuttingDown) {
2991                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2992                return;
2993            } else if (app.notResponding) {
2994                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2995                return;
2996            } else if (app.crashing) {
2997                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2998                return;
2999            }
3000
3001            // In case we come through here for the same app before completing
3002            // this one, mark as anring now so we will bail out.
3003            app.notResponding = true;
3004
3005            // Log the ANR to the event log.
3006            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3007                    annotation);
3008
3009            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3010            firstPids.add(app.pid);
3011
3012            int parentPid = app.pid;
3013            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3014            if (parentPid != app.pid) firstPids.add(parentPid);
3015
3016            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3017
3018            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3019                ProcessRecord r = mLruProcesses.get(i);
3020                if (r != null && r.thread != null) {
3021                    int pid = r.pid;
3022                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3023                        if (r.persistent) {
3024                            firstPids.add(pid);
3025                        } else {
3026                            lastPids.put(pid, Boolean.TRUE);
3027                        }
3028                    }
3029                }
3030            }
3031        }
3032
3033        // Log the ANR to the main log.
3034        StringBuilder info = mStringBuilder;
3035        info.setLength(0);
3036        info.append("ANR in ").append(app.processName);
3037        if (activity != null && activity.shortComponentName != null) {
3038            info.append(" (").append(activity.shortComponentName).append(")");
3039        }
3040        info.append("\n");
3041        if (annotation != null) {
3042            info.append("Reason: ").append(annotation).append("\n");
3043        }
3044        if (parent != null && parent != activity) {
3045            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3046        }
3047
3048        final ProcessStats processStats = new ProcessStats(true);
3049
3050        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3051
3052        String cpuInfo = null;
3053        if (MONITOR_CPU_USAGE) {
3054            updateCpuStatsNow();
3055            synchronized (mProcessStatsThread) {
3056                cpuInfo = mProcessStats.printCurrentState(anrTime);
3057            }
3058            info.append(processStats.printCurrentLoad());
3059            info.append(cpuInfo);
3060        }
3061
3062        info.append(processStats.printCurrentState(anrTime));
3063
3064        Slog.e(TAG, info.toString());
3065        if (tracesFile == null) {
3066            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3067            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3068        }
3069
3070        addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
3071
3072        if (mController != null) {
3073            try {
3074                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3075                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3076                if (res != 0) {
3077                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3078                    return;
3079                }
3080            } catch (RemoteException e) {
3081                mController = null;
3082            }
3083        }
3084
3085        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3086        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3087                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3088
3089        synchronized (this) {
3090            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3091                Slog.w(TAG, "Killing " + app + ": background ANR");
3092                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3093                        app.processName, app.setAdj, "background ANR");
3094                Process.killProcessQuiet(app.pid);
3095                return;
3096            }
3097
3098            // Set the app's notResponding state, and look up the errorReportReceiver
3099            makeAppNotRespondingLocked(app,
3100                    activity != null ? activity.shortComponentName : null,
3101                    annotation != null ? "ANR " + annotation : "ANR",
3102                    info.toString());
3103
3104            // Bring up the infamous App Not Responding dialog
3105            Message msg = Message.obtain();
3106            HashMap map = new HashMap();
3107            msg.what = SHOW_NOT_RESPONDING_MSG;
3108            msg.obj = map;
3109            map.put("app", app);
3110            if (activity != null) {
3111                map.put("activity", activity);
3112            }
3113
3114            mHandler.sendMessage(msg);
3115        }
3116    }
3117
3118    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3119        if (!mLaunchWarningShown) {
3120            mLaunchWarningShown = true;
3121            mHandler.post(new Runnable() {
3122                @Override
3123                public void run() {
3124                    synchronized (ActivityManagerService.this) {
3125                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3126                        d.show();
3127                        mHandler.postDelayed(new Runnable() {
3128                            @Override
3129                            public void run() {
3130                                synchronized (ActivityManagerService.this) {
3131                                    d.dismiss();
3132                                    mLaunchWarningShown = false;
3133                                }
3134                            }
3135                        }, 4000);
3136                    }
3137                }
3138            });
3139        }
3140    }
3141
3142    public boolean clearApplicationUserData(final String packageName,
3143            final IPackageDataObserver observer) {
3144        int uid = Binder.getCallingUid();
3145        int pid = Binder.getCallingPid();
3146        long callingId = Binder.clearCallingIdentity();
3147        try {
3148            IPackageManager pm = AppGlobals.getPackageManager();
3149            int pkgUid = -1;
3150            synchronized(this) {
3151                try {
3152                    pkgUid = pm.getPackageUid(packageName);
3153                } catch (RemoteException e) {
3154                }
3155                if (pkgUid == -1) {
3156                    Slog.w(TAG, "Invalid packageName:" + packageName);
3157                    return false;
3158                }
3159                if (uid == pkgUid || checkComponentPermission(
3160                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3161                        pid, uid, -1, true)
3162                        == PackageManager.PERMISSION_GRANTED) {
3163                    forceStopPackageLocked(packageName, pkgUid);
3164                } else {
3165                    throw new SecurityException(pid+" does not have permission:"+
3166                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3167                                    "for process:"+packageName);
3168                }
3169            }
3170
3171            try {
3172                //clear application user data
3173                pm.clearApplicationUserData(packageName, observer);
3174                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3175                        Uri.fromParts("package", packageName, null));
3176                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3177                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3178                        null, null, 0, null, null, null, false, false);
3179            } catch (RemoteException e) {
3180            }
3181        } finally {
3182            Binder.restoreCallingIdentity(callingId);
3183        }
3184        return true;
3185    }
3186
3187    public void killBackgroundProcesses(final String packageName) {
3188        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3189                != PackageManager.PERMISSION_GRANTED &&
3190                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3191                        != PackageManager.PERMISSION_GRANTED) {
3192            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3193                    + Binder.getCallingPid()
3194                    + ", uid=" + Binder.getCallingUid()
3195                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3196            Slog.w(TAG, msg);
3197            throw new SecurityException(msg);
3198        }
3199
3200        long callingId = Binder.clearCallingIdentity();
3201        try {
3202            IPackageManager pm = AppGlobals.getPackageManager();
3203            int pkgUid = -1;
3204            synchronized(this) {
3205                try {
3206                    pkgUid = pm.getPackageUid(packageName);
3207                } catch (RemoteException e) {
3208                }
3209                if (pkgUid == -1) {
3210                    Slog.w(TAG, "Invalid packageName: " + packageName);
3211                    return;
3212                }
3213                killPackageProcessesLocked(packageName, pkgUid,
3214                        SECONDARY_SERVER_ADJ, false, true);
3215            }
3216        } finally {
3217            Binder.restoreCallingIdentity(callingId);
3218        }
3219    }
3220
3221    public void forceStopPackage(final String packageName) {
3222        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3223                != PackageManager.PERMISSION_GRANTED) {
3224            String msg = "Permission Denial: forceStopPackage() from pid="
3225                    + Binder.getCallingPid()
3226                    + ", uid=" + Binder.getCallingUid()
3227                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3228            Slog.w(TAG, msg);
3229            throw new SecurityException(msg);
3230        }
3231
3232        long callingId = Binder.clearCallingIdentity();
3233        try {
3234            IPackageManager pm = AppGlobals.getPackageManager();
3235            int pkgUid = -1;
3236            synchronized(this) {
3237                try {
3238                    pkgUid = pm.getPackageUid(packageName);
3239                } catch (RemoteException e) {
3240                }
3241                if (pkgUid == -1) {
3242                    Slog.w(TAG, "Invalid packageName: " + packageName);
3243                    return;
3244                }
3245                forceStopPackageLocked(packageName, pkgUid);
3246                try {
3247                    pm.setPackageStoppedState(packageName, true);
3248                } catch (RemoteException e) {
3249                } catch (IllegalArgumentException e) {
3250                    Slog.w(TAG, "Failed trying to unstop package "
3251                            + packageName + ": " + e);
3252                }
3253            }
3254        } finally {
3255            Binder.restoreCallingIdentity(callingId);
3256        }
3257    }
3258
3259    /*
3260     * The pkg name and uid have to be specified.
3261     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3262     */
3263    public void killApplicationWithUid(String pkg, int uid) {
3264        if (pkg == null) {
3265            return;
3266        }
3267        // Make sure the uid is valid.
3268        if (uid < 0) {
3269            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3270            return;
3271        }
3272        int callerUid = Binder.getCallingUid();
3273        // Only the system server can kill an application
3274        if (callerUid == Process.SYSTEM_UID) {
3275            // Post an aysnc message to kill the application
3276            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3277            msg.arg1 = uid;
3278            msg.arg2 = 0;
3279            msg.obj = pkg;
3280            mHandler.sendMessage(msg);
3281        } else {
3282            throw new SecurityException(callerUid + " cannot kill pkg: " +
3283                    pkg);
3284        }
3285    }
3286
3287    public void closeSystemDialogs(String reason) {
3288        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3289        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3290        if (reason != null) {
3291            intent.putExtra("reason", reason);
3292        }
3293
3294        final int uid = Binder.getCallingUid();
3295        final long origId = Binder.clearCallingIdentity();
3296        synchronized (this) {
3297            int i = mWatchers.beginBroadcast();
3298            while (i > 0) {
3299                i--;
3300                IActivityWatcher w = mWatchers.getBroadcastItem(i);
3301                if (w != null) {
3302                    try {
3303                        w.closingSystemDialogs(reason);
3304                    } catch (RemoteException e) {
3305                    }
3306                }
3307            }
3308            mWatchers.finishBroadcast();
3309
3310            mWindowManager.closeSystemDialogs(reason);
3311
3312            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3313                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3314                if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3315                    r.stack.finishActivityLocked(r, i,
3316                            Activity.RESULT_CANCELED, null, "close-sys");
3317                }
3318            }
3319
3320            broadcastIntentLocked(null, null, intent, null,
3321                    null, 0, null, null, null, false, false, -1, uid);
3322        }
3323        Binder.restoreCallingIdentity(origId);
3324    }
3325
3326    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3327            throws RemoteException {
3328        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3329        for (int i=pids.length-1; i>=0; i--) {
3330            infos[i] = new Debug.MemoryInfo();
3331            Debug.getMemoryInfo(pids[i], infos[i]);
3332        }
3333        return infos;
3334    }
3335
3336    public void killApplicationProcess(String processName, int uid) {
3337        if (processName == null) {
3338            return;
3339        }
3340
3341        int callerUid = Binder.getCallingUid();
3342        // Only the system server can kill an application
3343        if (callerUid == Process.SYSTEM_UID) {
3344            synchronized (this) {
3345                ProcessRecord app = getProcessRecordLocked(processName, uid);
3346                if (app != null && app.thread != null) {
3347                    try {
3348                        app.thread.scheduleSuicide();
3349                    } catch (RemoteException e) {
3350                        // If the other end already died, then our work here is done.
3351                    }
3352                } else {
3353                    Slog.w(TAG, "Process/uid not found attempting kill of "
3354                            + processName + " / " + uid);
3355                }
3356            }
3357        } else {
3358            throw new SecurityException(callerUid + " cannot kill app process: " +
3359                    processName);
3360        }
3361    }
3362
3363    private void forceStopPackageLocked(final String packageName, int uid) {
3364        forceStopPackageLocked(packageName, uid, false, false, true);
3365        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3366                Uri.fromParts("package", packageName, null));
3367        if (!mProcessesReady) {
3368            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3369        }
3370        intent.putExtra(Intent.EXTRA_UID, uid);
3371        broadcastIntentLocked(null, null, intent,
3372                null, null, 0, null, null, null,
3373                false, false, MY_PID, Process.SYSTEM_UID);
3374    }
3375
3376    private final boolean killPackageProcessesLocked(String packageName, int uid,
3377            int minOomAdj, boolean callerWillRestart, boolean doit) {
3378        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3379
3380        // Remove all processes this package may have touched: all with the
3381        // same UID (except for the system or root user), and all whose name
3382        // matches the package name.
3383        final String procNamePrefix = packageName + ":";
3384        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3385            final int NA = apps.size();
3386            for (int ia=0; ia<NA; ia++) {
3387                ProcessRecord app = apps.valueAt(ia);
3388                if (app.removed) {
3389                    if (doit) {
3390                        procs.add(app);
3391                    }
3392                } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3393                        || app.processName.equals(packageName)
3394                        || app.processName.startsWith(procNamePrefix)) {
3395                    if (app.setAdj >= minOomAdj) {
3396                        if (!doit) {
3397                            return true;
3398                        }
3399                        app.removed = true;
3400                        procs.add(app);
3401                    }
3402                }
3403            }
3404        }
3405
3406        int N = procs.size();
3407        for (int i=0; i<N; i++) {
3408            removeProcessLocked(procs.get(i), callerWillRestart);
3409        }
3410        return N > 0;
3411    }
3412
3413    private final boolean forceStopPackageLocked(String name, int uid,
3414            boolean callerWillRestart, boolean purgeCache, boolean doit) {
3415        int i;
3416        int N;
3417
3418        if (uid < 0) {
3419            try {
3420                uid = AppGlobals.getPackageManager().getPackageUid(name);
3421            } catch (RemoteException e) {
3422            }
3423        }
3424
3425        if (doit) {
3426            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3427
3428            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3429            while (badApps.hasNext()) {
3430                SparseArray<Long> ba = badApps.next();
3431                if (ba.get(uid) != null) {
3432                    badApps.remove();
3433                }
3434            }
3435        }
3436
3437        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3438                callerWillRestart, doit);
3439
3440        for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3441            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3442            if (r.packageName.equals(name)) {
3443                if (!doit) {
3444                    return true;
3445                }
3446                didSomething = true;
3447                Slog.i(TAG, "  Force finishing activity " + r);
3448                if (r.app != null) {
3449                    r.app.removed = true;
3450                }
3451                r.app = null;
3452                r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
3453            }
3454        }
3455
3456        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3457        for (ServiceRecord service : mServices.values()) {
3458            if (service.packageName.equals(name)) {
3459                if (!doit) {
3460                    return true;
3461                }
3462                didSomething = true;
3463                Slog.i(TAG, "  Force stopping service " + service);
3464                if (service.app != null) {
3465                    service.app.removed = true;
3466                }
3467                service.app = null;
3468                services.add(service);
3469            }
3470        }
3471
3472        N = services.size();
3473        for (i=0; i<N; i++) {
3474            bringDownServiceLocked(services.get(i), true);
3475        }
3476
3477        if (doit) {
3478            if (purgeCache) {
3479                AttributeCache ac = AttributeCache.instance();
3480                if (ac != null) {
3481                    ac.removePackage(name);
3482                }
3483            }
3484            mMainStack.resumeTopActivityLocked(null);
3485        }
3486
3487        return didSomething;
3488    }
3489
3490    private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
3491        final String name = app.processName;
3492        final int uid = app.info.uid;
3493        if (DEBUG_PROCESSES) Slog.d(
3494            TAG, "Force removing process " + app + " (" + name
3495            + "/" + uid + ")");
3496
3497        mProcessNames.remove(name, uid);
3498        if (mHeavyWeightProcess == app) {
3499            mHeavyWeightProcess = null;
3500            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3501        }
3502        boolean needRestart = false;
3503        if (app.pid > 0 && app.pid != MY_PID) {
3504            int pid = app.pid;
3505            synchronized (mPidsSelfLocked) {
3506                mPidsSelfLocked.remove(pid);
3507                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3508            }
3509            handleAppDiedLocked(app, true);
3510            mLruProcesses.remove(app);
3511            Process.killProcess(pid);
3512
3513            if (app.persistent) {
3514                if (!callerWillRestart) {
3515                    addAppLocked(app.info);
3516                } else {
3517                    needRestart = true;
3518                }
3519            }
3520        } else {
3521            mRemovedProcesses.add(app);
3522        }
3523
3524        return needRestart;
3525    }
3526
3527    private final void processStartTimedOutLocked(ProcessRecord app) {
3528        final int pid = app.pid;
3529        boolean gone = false;
3530        synchronized (mPidsSelfLocked) {
3531            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3532            if (knownApp != null && knownApp.thread == null) {
3533                mPidsSelfLocked.remove(pid);
3534                gone = true;
3535            }
3536        }
3537
3538        if (gone) {
3539            Slog.w(TAG, "Process " + app + " failed to attach");
3540            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
3541                    app.processName);
3542            mProcessNames.remove(app.processName, app.info.uid);
3543            if (mHeavyWeightProcess == app) {
3544                mHeavyWeightProcess = null;
3545                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3546            }
3547            // Take care of any launching providers waiting for this process.
3548            checkAppInLaunchingProvidersLocked(app, true);
3549            // Take care of any services that are waiting for the process.
3550            for (int i=0; i<mPendingServices.size(); i++) {
3551                ServiceRecord sr = mPendingServices.get(i);
3552                if (app.info.uid == sr.appInfo.uid
3553                        && app.processName.equals(sr.processName)) {
3554                    Slog.w(TAG, "Forcing bringing down service: " + sr);
3555                    mPendingServices.remove(i);
3556                    i--;
3557                    bringDownServiceLocked(sr, true);
3558                }
3559            }
3560            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3561                    app.processName, app.setAdj, "start timeout");
3562            Process.killProcessQuiet(pid);
3563            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3564                Slog.w(TAG, "Unattached app died before backup, skipping");
3565                try {
3566                    IBackupManager bm = IBackupManager.Stub.asInterface(
3567                            ServiceManager.getService(Context.BACKUP_SERVICE));
3568                    bm.agentDisconnected(app.info.packageName);
3569                } catch (RemoteException e) {
3570                    // Can't happen; the backup manager is local
3571                }
3572            }
3573            if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
3574                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3575                mPendingBroadcast.state = BroadcastRecord.IDLE;
3576                mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
3577                mPendingBroadcast = null;
3578                scheduleBroadcastsLocked();
3579            }
3580        } else {
3581            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3582        }
3583    }
3584
3585    private final boolean attachApplicationLocked(IApplicationThread thread,
3586            int pid) {
3587
3588        // Find the application record that is being attached...  either via
3589        // the pid if we are running in multiple processes, or just pull the
3590        // next app record if we are emulating process with anonymous threads.
3591        ProcessRecord app;
3592        if (pid != MY_PID && pid >= 0) {
3593            synchronized (mPidsSelfLocked) {
3594                app = mPidsSelfLocked.get(pid);
3595            }
3596        } else if (mStartingProcesses.size() > 0) {
3597            app = mStartingProcesses.remove(0);
3598            app.setPid(pid);
3599        } else {
3600            app = null;
3601        }
3602
3603        if (app == null) {
3604            Slog.w(TAG, "No pending application record for pid " + pid
3605                    + " (IApplicationThread " + thread + "); dropping process");
3606            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3607            if (pid > 0 && pid != MY_PID) {
3608                Process.killProcessQuiet(pid);
3609            } else {
3610                try {
3611                    thread.scheduleExit();
3612                } catch (Exception e) {
3613                    // Ignore exceptions.
3614                }
3615            }
3616            return false;
3617        }
3618
3619        // If this application record is still attached to a previous
3620        // process, clean it up now.
3621        if (app.thread != null) {
3622            handleAppDiedLocked(app, true);
3623        }
3624
3625        // Tell the process all about itself.
3626
3627        if (localLOGV) Slog.v(
3628                TAG, "Binding process pid " + pid + " to record " + app);
3629
3630        String processName = app.processName;
3631        try {
3632            thread.asBinder().linkToDeath(new AppDeathRecipient(
3633                    app, pid, thread), 0);
3634        } catch (RemoteException e) {
3635            app.resetPackageList();
3636            startProcessLocked(app, "link fail", processName);
3637            return false;
3638        }
3639
3640        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3641
3642        app.thread = thread;
3643        app.curAdj = app.setAdj = -100;
3644        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3645        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3646        app.forcingToForeground = null;
3647        app.foregroundServices = false;
3648        app.debugging = false;
3649
3650        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3651
3652        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3653        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3654
3655        if (!normalMode) {
3656            Slog.i(TAG, "Launching preboot mode app: " + app);
3657        }
3658
3659        if (localLOGV) Slog.v(
3660            TAG, "New app record " + app
3661            + " thread=" + thread.asBinder() + " pid=" + pid);
3662        try {
3663            int testMode = IApplicationThread.DEBUG_OFF;
3664            if (mDebugApp != null && mDebugApp.equals(processName)) {
3665                testMode = mWaitForDebugger
3666                    ? IApplicationThread.DEBUG_WAIT
3667                    : IApplicationThread.DEBUG_ON;
3668                app.debugging = true;
3669                if (mDebugTransient) {
3670                    mDebugApp = mOrigDebugApp;
3671                    mWaitForDebugger = mOrigWaitForDebugger;
3672                }
3673            }
3674
3675            // If the app is being launched for restore or full backup, set it up specially
3676            boolean isRestrictedBackupMode = false;
3677            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3678                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3679                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
3680                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3681            }
3682
3683            ensurePackageDexOpt(app.instrumentationInfo != null
3684                    ? app.instrumentationInfo.packageName
3685                    : app.info.packageName);
3686            if (app.instrumentationClass != null) {
3687                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
3688            }
3689            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
3690                    + processName + " with config " + mConfiguration);
3691            ApplicationInfo appInfo = app.instrumentationInfo != null
3692                    ? app.instrumentationInfo : app.info;
3693            thread.bindApplication(processName, appInfo, providers,
3694                    app.instrumentationClass, app.instrumentationProfileFile,
3695                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
3696                    isRestrictedBackupMode || !normalMode,
3697                    mConfiguration, compatibilityInfoForPackageLocked(appInfo),
3698                    getCommonServicesLocked(),
3699                    mCoreSettingsObserver.getCoreSettingsLocked());
3700            updateLruProcessLocked(app, false, true);
3701            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
3702        } catch (Exception e) {
3703            // todo: Yikes!  What should we do?  For now we will try to
3704            // start another process, but that could easily get us in
3705            // an infinite loop of restarting processes...
3706            Slog.w(TAG, "Exception thrown during bind!", e);
3707
3708            app.resetPackageList();
3709            startProcessLocked(app, "bind fail", processName);
3710            return false;
3711        }
3712
3713        // Remove this record from the list of starting applications.
3714        mPersistentStartingProcesses.remove(app);
3715        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3716                "Attach application locked removing on hold: " + app);
3717        mProcessesOnHold.remove(app);
3718
3719        boolean badApp = false;
3720        boolean didSomething = false;
3721
3722        // See if the top visible activity is waiting to run in this process...
3723        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
3724        if (hr != null && normalMode) {
3725            if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3726                    && processName.equals(hr.processName)) {
3727                try {
3728                    if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
3729                        didSomething = true;
3730                    }
3731                } catch (Exception e) {
3732                    Slog.w(TAG, "Exception in new application when starting activity "
3733                          + hr.intent.getComponent().flattenToShortString(), e);
3734                    badApp = true;
3735                }
3736            } else {
3737                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
3738            }
3739        }
3740
3741        // Find any services that should be running in this process...
3742        if (!badApp && mPendingServices.size() > 0) {
3743            ServiceRecord sr = null;
3744            try {
3745                for (int i=0; i<mPendingServices.size(); i++) {
3746                    sr = mPendingServices.get(i);
3747                    if (app.info.uid != sr.appInfo.uid
3748                            || !processName.equals(sr.processName)) {
3749                        continue;
3750                    }
3751
3752                    mPendingServices.remove(i);
3753                    i--;
3754                    realStartServiceLocked(sr, app);
3755                    didSomething = true;
3756                }
3757            } catch (Exception e) {
3758                Slog.w(TAG, "Exception in new application when starting service "
3759                      + sr.shortName, e);
3760                badApp = true;
3761            }
3762        }
3763
3764        // Check if the next broadcast receiver is in this process...
3765        BroadcastRecord br = mPendingBroadcast;
3766        if (!badApp && br != null && br.curApp == app) {
3767            try {
3768                mPendingBroadcast = null;
3769                processCurBroadcastLocked(br, app);
3770                didSomething = true;
3771            } catch (Exception e) {
3772                Slog.w(TAG, "Exception in new application when starting receiver "
3773                      + br.curComponent.flattenToShortString(), e);
3774                badApp = true;
3775                logBroadcastReceiverDiscardLocked(br);
3776                finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3777                        br.resultExtras, br.resultAbort, true);
3778                scheduleBroadcastsLocked();
3779                // We need to reset the state if we fails to start the receiver.
3780                br.state = BroadcastRecord.IDLE;
3781            }
3782        }
3783
3784        // Check whether the next backup agent is in this process...
3785        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
3786            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
3787            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
3788            try {
3789                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3790                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3791                        mBackupTarget.backupMode);
3792            } catch (Exception e) {
3793                Slog.w(TAG, "Exception scheduling backup agent creation: ");
3794                e.printStackTrace();
3795            }
3796        }
3797
3798        if (badApp) {
3799            // todo: Also need to kill application to deal with all
3800            // kinds of exceptions.
3801            handleAppDiedLocked(app, false);
3802            return false;
3803        }
3804
3805        if (!didSomething) {
3806            updateOomAdjLocked();
3807        }
3808
3809        return true;
3810    }
3811
3812    public final void attachApplication(IApplicationThread thread) {
3813        synchronized (this) {
3814            int callingPid = Binder.getCallingPid();
3815            final long origId = Binder.clearCallingIdentity();
3816            attachApplicationLocked(thread, callingPid);
3817            Binder.restoreCallingIdentity(origId);
3818        }
3819    }
3820
3821    public final void activityIdle(IBinder token, Configuration config) {
3822        final long origId = Binder.clearCallingIdentity();
3823        mMainStack.activityIdleInternal(token, false, config);
3824        Binder.restoreCallingIdentity(origId);
3825    }
3826
3827    void enableScreenAfterBoot() {
3828        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
3829                SystemClock.uptimeMillis());
3830        mWindowManager.enableScreenAfterBoot();
3831    }
3832
3833    final void finishBooting() {
3834        IntentFilter pkgFilter = new IntentFilter();
3835        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3836        pkgFilter.addDataScheme("package");
3837        mContext.registerReceiver(new BroadcastReceiver() {
3838            @Override
3839            public void onReceive(Context context, Intent intent) {
3840                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3841                if (pkgs != null) {
3842                    for (String pkg : pkgs) {
3843                        synchronized (ActivityManagerService.this) {
3844                          if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3845                              setResultCode(Activity.RESULT_OK);
3846                              return;
3847                          }
3848                       }
3849                    }
3850                }
3851            }
3852        }, pkgFilter);
3853
3854        synchronized (this) {
3855            // Ensure that any processes we had put on hold are now started
3856            // up.
3857            final int NP = mProcessesOnHold.size();
3858            if (NP > 0) {
3859                ArrayList<ProcessRecord> procs =
3860                    new ArrayList<ProcessRecord>(mProcessesOnHold);
3861                for (int ip=0; ip<NP; ip++) {
3862                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3863                            + procs.get(ip));
3864                    startProcessLocked(procs.get(ip), "on-hold", null);
3865                }
3866            }
3867
3868            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
3869                // Start looking for apps that are abusing wake locks.
3870                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
3871                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
3872                // Tell anyone interested that we are done booting!
3873                SystemProperties.set("sys.boot_completed", "1");
3874                broadcastIntentLocked(null, null,
3875                        new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3876                        null, null, 0, null, null,
3877                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3878                        false, false, MY_PID, Process.SYSTEM_UID);
3879            }
3880        }
3881    }
3882
3883    final void ensureBootCompleted() {
3884        boolean booting;
3885        boolean enableScreen;
3886        synchronized (this) {
3887            booting = mBooting;
3888            mBooting = false;
3889            enableScreen = !mBooted;
3890            mBooted = true;
3891        }
3892
3893        if (booting) {
3894            finishBooting();
3895        }
3896
3897        if (enableScreen) {
3898            enableScreenAfterBoot();
3899        }
3900    }
3901
3902    public final void activityPaused(IBinder token) {
3903        final long origId = Binder.clearCallingIdentity();
3904        mMainStack.activityPaused(token, false);
3905        Binder.restoreCallingIdentity(origId);
3906    }
3907
3908    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3909            CharSequence description) {
3910        if (localLOGV) Slog.v(
3911            TAG, "Activity stopped: token=" + token);
3912
3913        // Refuse possible leaked file descriptors
3914        if (icicle != null && icicle.hasFileDescriptors()) {
3915            throw new IllegalArgumentException("File descriptors passed in Bundle");
3916        }
3917
3918        ActivityRecord r = null;
3919
3920        final long origId = Binder.clearCallingIdentity();
3921
3922        synchronized (this) {
3923            int index = mMainStack.indexOfTokenLocked(token);
3924            if (index >= 0) {
3925                r = (ActivityRecord)mMainStack.mHistory.get(index);
3926                r.icicle = icicle;
3927                r.haveState = true;
3928                r.updateThumbnail(thumbnail, description);
3929                r.stopped = true;
3930                r.state = ActivityState.STOPPED;
3931                if (!r.finishing) {
3932                    if (r.configDestroy) {
3933                        r.stack.destroyActivityLocked(r, true);
3934                        r.stack.resumeTopActivityLocked(null);
3935                    }
3936                }
3937            }
3938        }
3939
3940        if (r != null) {
3941            sendPendingThumbnail(r, null, null, null, false);
3942        }
3943
3944        trimApplications();
3945
3946        Binder.restoreCallingIdentity(origId);
3947    }
3948
3949    public final void activityDestroyed(IBinder token) {
3950        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
3951        mMainStack.activityDestroyed(token);
3952    }
3953
3954    public String getCallingPackage(IBinder token) {
3955        synchronized (this) {
3956            ActivityRecord r = getCallingRecordLocked(token);
3957            return r != null && r.app != null ? r.info.packageName : null;
3958        }
3959    }
3960
3961    public ComponentName getCallingActivity(IBinder token) {
3962        synchronized (this) {
3963            ActivityRecord r = getCallingRecordLocked(token);
3964            return r != null ? r.intent.getComponent() : null;
3965        }
3966    }
3967
3968    private ActivityRecord getCallingRecordLocked(IBinder token) {
3969        int index = mMainStack.indexOfTokenLocked(token);
3970        if (index >= 0) {
3971            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
3972            if (r != null) {
3973                return r.resultTo;
3974            }
3975        }
3976        return null;
3977    }
3978
3979    public ComponentName getActivityClassForToken(IBinder token) {
3980        synchronized(this) {
3981            int index = mMainStack.indexOfTokenLocked(token);
3982            if (index >= 0) {
3983                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
3984                return r.intent.getComponent();
3985            }
3986            return null;
3987        }
3988    }
3989
3990    public String getPackageForToken(IBinder token) {
3991        synchronized(this) {
3992            int index = mMainStack.indexOfTokenLocked(token);
3993            if (index >= 0) {
3994                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
3995                return r.packageName;
3996            }
3997            return null;
3998        }
3999    }
4000
4001    public IIntentSender getIntentSender(int type,
4002            String packageName, IBinder token, String resultWho,
4003            int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
4004        // Refuse possible leaked file descriptors
4005        if (intents != null) {
4006            if (intents.length < 1) {
4007                throw new IllegalArgumentException("Intents array length must be >= 1");
4008            }
4009            for (int i=0; i<intents.length; i++) {
4010                Intent intent = intents[i];
4011                if (intent != null) {
4012                    if (intent.hasFileDescriptors()) {
4013                        throw new IllegalArgumentException("File descriptors passed in Intent");
4014                    }
4015                    if (type == INTENT_SENDER_BROADCAST &&
4016                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4017                        throw new IllegalArgumentException(
4018                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4019                    }
4020                    intents[i] = new Intent(intent);
4021                }
4022            }
4023            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4024                throw new IllegalArgumentException(
4025                        "Intent array length does not match resolvedTypes length");
4026            }
4027        }
4028
4029        synchronized(this) {
4030            int callingUid = Binder.getCallingUid();
4031            try {
4032                if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
4033                        Process.supportsProcesses()) {
4034                    int uid = AppGlobals.getPackageManager()
4035                            .getPackageUid(packageName);
4036                    if (uid != Binder.getCallingUid()) {
4037                        String msg = "Permission Denial: getIntentSender() from pid="
4038                            + Binder.getCallingPid()
4039                            + ", uid=" + Binder.getCallingUid()
4040                            + ", (need uid=" + uid + ")"
4041                            + " is not allowed to send as package " + packageName;
4042                        Slog.w(TAG, msg);
4043                        throw new SecurityException(msg);
4044                    }
4045                }
4046
4047                return getIntentSenderLocked(type, packageName, callingUid,
4048                        token, resultWho, requestCode, intents, resolvedTypes, flags);
4049
4050            } catch (RemoteException e) {
4051                throw new SecurityException(e);
4052            }
4053        }
4054    }
4055
4056    IIntentSender getIntentSenderLocked(int type,
4057            String packageName, int callingUid, IBinder token, String resultWho,
4058            int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
4059        ActivityRecord activity = null;
4060        if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4061            int index = mMainStack.indexOfTokenLocked(token);
4062            if (index < 0) {
4063                return null;
4064            }
4065            activity = (ActivityRecord)mMainStack.mHistory.get(index);
4066            if (activity.finishing) {
4067                return null;
4068            }
4069        }
4070
4071        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4072        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4073        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4074        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4075                |PendingIntent.FLAG_UPDATE_CURRENT);
4076
4077        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4078                type, packageName, activity, resultWho,
4079                requestCode, intents, resolvedTypes, flags);
4080        WeakReference<PendingIntentRecord> ref;
4081        ref = mIntentSenderRecords.get(key);
4082        PendingIntentRecord rec = ref != null ? ref.get() : null;
4083        if (rec != null) {
4084            if (!cancelCurrent) {
4085                if (updateCurrent) {
4086                    if (rec.key.requestIntent != null) {
4087                        rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4088                    }
4089                    if (intents != null) {
4090                        intents[intents.length-1] = rec.key.requestIntent;
4091                        rec.key.allIntents = intents;
4092                        rec.key.allResolvedTypes = resolvedTypes;
4093                    } else {
4094                        rec.key.allIntents = null;
4095                        rec.key.allResolvedTypes = null;
4096                    }
4097                }
4098                return rec;
4099            }
4100            rec.canceled = true;
4101            mIntentSenderRecords.remove(key);
4102        }
4103        if (noCreate) {
4104            return rec;
4105        }
4106        rec = new PendingIntentRecord(this, key, callingUid);
4107        mIntentSenderRecords.put(key, rec.ref);
4108        if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4109            if (activity.pendingResults == null) {
4110                activity.pendingResults
4111                        = new HashSet<WeakReference<PendingIntentRecord>>();
4112            }
4113            activity.pendingResults.add(rec.ref);
4114        }
4115        return rec;
4116    }
4117
4118    public void cancelIntentSender(IIntentSender sender) {
4119        if (!(sender instanceof PendingIntentRecord)) {
4120            return;
4121        }
4122        synchronized(this) {
4123            PendingIntentRecord rec = (PendingIntentRecord)sender;
4124            try {
4125                int uid = AppGlobals.getPackageManager()
4126                        .getPackageUid(rec.key.packageName);
4127                if (uid != Binder.getCallingUid()) {
4128                    String msg = "Permission Denial: cancelIntentSender() from pid="
4129                        + Binder.getCallingPid()
4130                        + ", uid=" + Binder.getCallingUid()
4131                        + " is not allowed to cancel packges "
4132                        + rec.key.packageName;
4133                    Slog.w(TAG, msg);
4134                    throw new SecurityException(msg);
4135                }
4136            } catch (RemoteException e) {
4137                throw new SecurityException(e);
4138            }
4139            cancelIntentSenderLocked(rec, true);
4140        }
4141    }
4142
4143    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4144        rec.canceled = true;
4145        mIntentSenderRecords.remove(rec.key);
4146        if (cleanActivity && rec.key.activity != null) {
4147            rec.key.activity.pendingResults.remove(rec.ref);
4148        }
4149    }
4150
4151    public String getPackageForIntentSender(IIntentSender pendingResult) {
4152        if (!(pendingResult instanceof PendingIntentRecord)) {
4153            return null;
4154        }
4155        try {
4156            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4157            return res.key.packageName;
4158        } catch (ClassCastException e) {
4159        }
4160        return null;
4161    }
4162
4163    public void setProcessLimit(int max) {
4164        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4165                "setProcessLimit()");
4166        mProcessLimit = max;
4167    }
4168
4169    public int getProcessLimit() {
4170        return mProcessLimit;
4171    }
4172
4173    void foregroundTokenDied(ForegroundToken token) {
4174        synchronized (ActivityManagerService.this) {
4175            synchronized (mPidsSelfLocked) {
4176                ForegroundToken cur
4177                    = mForegroundProcesses.get(token.pid);
4178                if (cur != token) {
4179                    return;
4180                }
4181                mForegroundProcesses.remove(token.pid);
4182                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4183                if (pr == null) {
4184                    return;
4185                }
4186                pr.forcingToForeground = null;
4187                pr.foregroundServices = false;
4188            }
4189            updateOomAdjLocked();
4190        }
4191    }
4192
4193    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4194        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4195                "setProcessForeground()");
4196        synchronized(this) {
4197            boolean changed = false;
4198
4199            synchronized (mPidsSelfLocked) {
4200                ProcessRecord pr = mPidsSelfLocked.get(pid);
4201                if (pr == null) {
4202                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4203                    return;
4204                }
4205                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4206                if (oldToken != null) {
4207                    oldToken.token.unlinkToDeath(oldToken, 0);
4208                    mForegroundProcesses.remove(pid);
4209                    pr.forcingToForeground = null;
4210                    changed = true;
4211                }
4212                if (isForeground && token != null) {
4213                    ForegroundToken newToken = new ForegroundToken() {
4214                        public void binderDied() {
4215                            foregroundTokenDied(this);
4216                        }
4217                    };
4218                    newToken.pid = pid;
4219                    newToken.token = token;
4220                    try {
4221                        token.linkToDeath(newToken, 0);
4222                        mForegroundProcesses.put(pid, newToken);
4223                        pr.forcingToForeground = token;
4224                        changed = true;
4225                    } catch (RemoteException e) {
4226                        // If the process died while doing this, we will later
4227                        // do the cleanup with the process death link.
4228                    }
4229                }
4230            }
4231
4232            if (changed) {
4233                updateOomAdjLocked();
4234            }
4235        }
4236    }
4237
4238    // =========================================================
4239    // PERMISSIONS
4240    // =========================================================
4241
4242    static class PermissionController extends IPermissionController.Stub {
4243        ActivityManagerService mActivityManagerService;
4244        PermissionController(ActivityManagerService activityManagerService) {
4245            mActivityManagerService = activityManagerService;
4246        }
4247
4248        public boolean checkPermission(String permission, int pid, int uid) {
4249            return mActivityManagerService.checkPermission(permission, pid,
4250                    uid) == PackageManager.PERMISSION_GRANTED;
4251        }
4252    }
4253
4254    /**
4255     * This can be called with or without the global lock held.
4256     */
4257    int checkComponentPermission(String permission, int pid, int uid,
4258            int owningUid, boolean exported) {
4259        // We might be performing an operation on behalf of an indirect binder
4260        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4261        // client identity accordingly before proceeding.
4262        Identity tlsIdentity = sCallerIdentity.get();
4263        if (tlsIdentity != null) {
4264            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4265                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4266            uid = tlsIdentity.uid;
4267            pid = tlsIdentity.pid;
4268        }
4269
4270        // Root, system server and our own process get to do everything.
4271        if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
4272            !Process.supportsProcesses()) {
4273            return PackageManager.PERMISSION_GRANTED;
4274        }
4275        // If there is a uid that owns whatever is being accessed, it has
4276        // blanket access to it regardless of the permissions it requires.
4277        if (owningUid >= 0 && uid == owningUid) {
4278            return PackageManager.PERMISSION_GRANTED;
4279        }
4280        // If the target is not exported, then nobody else can get to it.
4281        if (!exported) {
4282            Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
4283            return PackageManager.PERMISSION_DENIED;
4284        }
4285        if (permission == null) {
4286            return PackageManager.PERMISSION_GRANTED;
4287        }
4288        try {
4289            return AppGlobals.getPackageManager()
4290                    .checkUidPermission(permission, uid);
4291        } catch (RemoteException e) {
4292            // Should never happen, but if it does... deny!
4293            Slog.e(TAG, "PackageManager is dead?!?", e);
4294        }
4295        return PackageManager.PERMISSION_DENIED;
4296    }
4297
4298    /**
4299     * As the only public entry point for permissions checking, this method
4300     * can enforce the semantic that requesting a check on a null global
4301     * permission is automatically denied.  (Internally a null permission
4302     * string is used when calling {@link #checkComponentPermission} in cases
4303     * when only uid-based security is needed.)
4304     *
4305     * This can be called with or without the global lock held.
4306     */
4307    public int checkPermission(String permission, int pid, int uid) {
4308        if (permission == null) {
4309            return PackageManager.PERMISSION_DENIED;
4310        }
4311        return checkComponentPermission(permission, pid, uid, -1, true);
4312    }
4313
4314    /**
4315     * Binder IPC calls go through the public entry point.
4316     * This can be called with or without the global lock held.
4317     */
4318    int checkCallingPermission(String permission) {
4319        return checkPermission(permission,
4320                Binder.getCallingPid(),
4321                Binder.getCallingUid());
4322    }
4323
4324    /**
4325     * This can be called with or without the global lock held.
4326     */
4327    void enforceCallingPermission(String permission, String func) {
4328        if (checkCallingPermission(permission)
4329                == PackageManager.PERMISSION_GRANTED) {
4330            return;
4331        }
4332
4333        String msg = "Permission Denial: " + func + " from pid="
4334                + Binder.getCallingPid()
4335                + ", uid=" + Binder.getCallingUid()
4336                + " requires " + permission;
4337        Slog.w(TAG, msg);
4338        throw new SecurityException(msg);
4339    }
4340
4341    private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
4342            ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4343        boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4344        boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4345        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4346                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4347        try {
4348            // Is the component private from the target uid?
4349            final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4350
4351            // Acceptable if the there is no read permission needed from the
4352            // target or the target is holding the read permission.
4353            if (!readPerm) {
4354                if ((!prv && pi.readPermission == null) ||
4355                        (pm.checkUidPermission(pi.readPermission, uid)
4356                                == PackageManager.PERMISSION_GRANTED)) {
4357                    readPerm = true;
4358                }
4359            }
4360
4361            // Acceptable if the there is no write permission needed from the
4362            // target or the target is holding the read permission.
4363            if (!writePerm) {
4364                if (!prv && (pi.writePermission == null) ||
4365                        (pm.checkUidPermission(pi.writePermission, uid)
4366                                == PackageManager.PERMISSION_GRANTED)) {
4367                    writePerm = true;
4368                }
4369            }
4370
4371            // Acceptable if there is a path permission matching the URI that
4372            // the target holds the permission on.
4373            PathPermission[] pps = pi.pathPermissions;
4374            if (pps != null && (!readPerm || !writePerm)) {
4375                final String path = uri.getPath();
4376                int i = pps.length;
4377                while (i > 0 && (!readPerm || !writePerm)) {
4378                    i--;
4379                    PathPermission pp = pps[i];
4380                    if (!readPerm) {
4381                        final String pprperm = pp.getReadPermission();
4382                        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4383                                + pprperm + " for " + pp.getPath()
4384                                + ": match=" + pp.match(path)
4385                                + " check=" + pm.checkUidPermission(pprperm, uid));
4386                        if (pprperm != null && pp.match(path) &&
4387                                (pm.checkUidPermission(pprperm, uid)
4388                                        == PackageManager.PERMISSION_GRANTED)) {
4389                            readPerm = true;
4390                        }
4391                    }
4392                    if (!writePerm) {
4393                        final String ppwperm = pp.getWritePermission();
4394                        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4395                                + ppwperm + " for " + pp.getPath()
4396                                + ": match=" + pp.match(path)
4397                                + " check=" + pm.checkUidPermission(ppwperm, uid));
4398                        if (ppwperm != null && pp.match(path) &&
4399                                (pm.checkUidPermission(ppwperm, uid)
4400                                        == PackageManager.PERMISSION_GRANTED)) {
4401                            writePerm = true;
4402                        }
4403                    }
4404                }
4405            }
4406        } catch (RemoteException e) {
4407            return false;
4408        }
4409
4410        return readPerm && writePerm;
4411    }
4412
4413    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4414            int modeFlags) {
4415        // Root gets to do everything.
4416        if (uid == 0 || !Process.supportsProcesses()) {
4417            return true;
4418        }
4419        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4420        if (perms == null) return false;
4421        UriPermission perm = perms.get(uri);
4422        if (perm == null) return false;
4423        return (modeFlags&perm.modeFlags) == modeFlags;
4424    }
4425
4426    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4427        // Another redirected-binder-call permissions check as in
4428        // {@link checkComponentPermission}.
4429        Identity tlsIdentity = sCallerIdentity.get();
4430        if (tlsIdentity != null) {
4431            uid = tlsIdentity.uid;
4432            pid = tlsIdentity.pid;
4433        }
4434
4435        // Our own process gets to do everything.
4436        if (pid == MY_PID) {
4437            return PackageManager.PERMISSION_GRANTED;
4438        }
4439        synchronized(this) {
4440            return checkUriPermissionLocked(uri, uid, modeFlags)
4441                    ? PackageManager.PERMISSION_GRANTED
4442                    : PackageManager.PERMISSION_DENIED;
4443        }
4444    }
4445
4446    /**
4447     * Check if the targetPkg can be granted permission to access uri by
4448     * the callingUid using the given modeFlags.  Throws a security exception
4449     * if callingUid is not allowed to do this.  Returns the uid of the target
4450     * if the URI permission grant should be performed; returns -1 if it is not
4451     * needed (for example targetPkg already has permission to access the URI).
4452     */
4453    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4454            Uri uri, int modeFlags) {
4455        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4456                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4457        if (modeFlags == 0) {
4458            return -1;
4459        }
4460
4461        if (targetPkg != null) {
4462            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4463                    "Checking grant " + targetPkg + " permission to " + uri);
4464        }
4465
4466        final IPackageManager pm = AppGlobals.getPackageManager();
4467
4468        // If this is not a content: uri, we can't do anything with it.
4469        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4470            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4471                    "Can't grant URI permission for non-content URI: " + uri);
4472            return -1;
4473        }
4474
4475        String name = uri.getAuthority();
4476        ProviderInfo pi = null;
4477        ContentProviderRecord cpr = mProvidersByName.get(name);
4478        if (cpr != null) {
4479            pi = cpr.info;
4480        } else {
4481            try {
4482                pi = pm.resolveContentProvider(name,
4483                        PackageManager.GET_URI_PERMISSION_PATTERNS);
4484            } catch (RemoteException ex) {
4485            }
4486        }
4487        if (pi == null) {
4488            Slog.w(TAG, "No content provider found for: " + name);
4489            return -1;
4490        }
4491
4492        int targetUid;
4493        if (targetPkg != null) {
4494            try {
4495                targetUid = pm.getPackageUid(targetPkg);
4496                if (targetUid < 0) {
4497                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4498                            "Can't grant URI permission no uid for: " + targetPkg);
4499                    return -1;
4500                }
4501            } catch (RemoteException ex) {
4502                return -1;
4503            }
4504        } else {
4505            targetUid = -1;
4506        }
4507
4508        if (targetUid >= 0) {
4509            // First...  does the target actually need this permission?
4510            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4511                // No need to grant the target this permission.
4512                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4513                        "Target " + targetPkg + " already has full permission to " + uri);
4514                return -1;
4515            }
4516        } else {
4517            // First...  there is no target package, so can anyone access it?
4518            boolean allowed = pi.exported;
4519            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4520                if (pi.readPermission != null) {
4521                    allowed = false;
4522                }
4523            }
4524            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4525                if (pi.writePermission != null) {
4526                    allowed = false;
4527                }
4528            }
4529            if (allowed) {
4530                return -1;
4531            }
4532        }
4533
4534        // Second...  is the provider allowing granting of URI permissions?
4535        if (!pi.grantUriPermissions) {
4536            throw new SecurityException("Provider " + pi.packageName
4537                    + "/" + pi.name
4538                    + " does not allow granting of Uri permissions (uri "
4539                    + uri + ")");
4540        }
4541        if (pi.uriPermissionPatterns != null) {
4542            final int N = pi.uriPermissionPatterns.length;
4543            boolean allowed = false;
4544            for (int i=0; i<N; i++) {
4545                if (pi.uriPermissionPatterns[i] != null
4546                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4547                    allowed = true;
4548                    break;
4549                }
4550            }
4551            if (!allowed) {
4552                throw new SecurityException("Provider " + pi.packageName
4553                        + "/" + pi.name
4554                        + " does not allow granting of permission to path of Uri "
4555                        + uri);
4556            }
4557        }
4558
4559        // Third...  does the caller itself have permission to access
4560        // this uri?
4561        if (callingUid != Process.myUid()) {
4562            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4563                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4564                    throw new SecurityException("Uid " + callingUid
4565                            + " does not have permission to uri " + uri);
4566                }
4567            }
4568        }
4569
4570        return targetUid;
4571    }
4572
4573    public int checkGrantUriPermission(int callingUid, String targetPkg,
4574            Uri uri, int modeFlags) {
4575        synchronized(this) {
4576            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4577        }
4578    }
4579
4580    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4581            Uri uri, int modeFlags, UriPermissionOwner owner) {
4582        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4583                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4584        if (modeFlags == 0) {
4585            return;
4586        }
4587
4588        // So here we are: the caller has the assumed permission
4589        // to the uri, and the target doesn't.  Let's now give this to
4590        // the target.
4591
4592        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4593                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
4594
4595        HashMap<Uri, UriPermission> targetUris
4596                = mGrantedUriPermissions.get(targetUid);
4597        if (targetUris == null) {
4598            targetUris = new HashMap<Uri, UriPermission>();
4599            mGrantedUriPermissions.put(targetUid, targetUris);
4600        }
4601
4602        UriPermission perm = targetUris.get(uri);
4603        if (perm == null) {
4604            perm = new UriPermission(targetUid, uri);
4605            targetUris.put(uri, perm);
4606        }
4607
4608        perm.modeFlags |= modeFlags;
4609        if (owner == null) {
4610            perm.globalModeFlags |= modeFlags;
4611        } else {
4612            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4613                 perm.readOwners.add(owner);
4614                 owner.addReadPermission(perm);
4615            }
4616            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4617                 perm.writeOwners.add(owner);
4618                 owner.addWritePermission(perm);
4619            }
4620        }
4621    }
4622
4623    void grantUriPermissionLocked(int callingUid,
4624            String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
4625        if (targetPkg == null) {
4626            throw new NullPointerException("targetPkg");
4627        }
4628
4629        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4630        if (targetUid < 0) {
4631            return;
4632        }
4633
4634        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4635    }
4636
4637    /**
4638     * Like checkGrantUriPermissionLocked, but takes an Intent.
4639     */
4640    int checkGrantUriPermissionFromIntentLocked(int callingUid,
4641            String targetPkg, Intent intent) {
4642        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4643                "Checking URI perm to " + (intent != null ? intent.getData() : null)
4644                + " from " + intent + "; flags=0x"
4645                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4646
4647        if (targetPkg == null) {
4648            throw new NullPointerException("targetPkg");
4649        }
4650
4651        if (intent == null) {
4652            return -1;
4653        }
4654        Uri data = intent.getData();
4655        if (data == null) {
4656            return -1;
4657        }
4658        return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4659                intent.getFlags());
4660    }
4661
4662    /**
4663     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4664     */
4665    void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4666            String targetPkg, Intent intent, UriPermissionOwner owner) {
4667        grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4668                intent.getFlags(), owner);
4669    }
4670
4671    void grantUriPermissionFromIntentLocked(int callingUid,
4672            String targetPkg, Intent intent, UriPermissionOwner owner) {
4673        int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4674        if (targetUid < 0) {
4675            return;
4676        }
4677
4678        grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
4679    }
4680
4681    public void grantUriPermission(IApplicationThread caller, String targetPkg,
4682            Uri uri, int modeFlags) {
4683        synchronized(this) {
4684            final ProcessRecord r = getRecordForAppLocked(caller);
4685            if (r == null) {
4686                throw new SecurityException("Unable to find app for caller "
4687                        + caller
4688                        + " when granting permission to uri " + uri);
4689            }
4690            if (targetPkg == null) {
4691                throw new IllegalArgumentException("null target");
4692            }
4693            if (uri == null) {
4694                throw new IllegalArgumentException("null uri");
4695            }
4696
4697            grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4698                    null);
4699        }
4700    }
4701
4702    void removeUriPermissionIfNeededLocked(UriPermission perm) {
4703        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4704                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4705            HashMap<Uri, UriPermission> perms
4706                    = mGrantedUriPermissions.get(perm.uid);
4707            if (perms != null) {
4708                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4709                        "Removing " + perm.uid + " permission to " + perm.uri);
4710                perms.remove(perm.uri);
4711                if (perms.size() == 0) {
4712                    mGrantedUriPermissions.remove(perm.uid);
4713                }
4714            }
4715        }
4716    }
4717
4718    private void revokeUriPermissionLocked(int callingUid, Uri uri,
4719            int modeFlags) {
4720        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4721                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4722        if (modeFlags == 0) {
4723            return;
4724        }
4725
4726        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4727                "Revoking all granted permissions to " + uri);
4728
4729        final IPackageManager pm = AppGlobals.getPackageManager();
4730
4731        final String authority = uri.getAuthority();
4732        ProviderInfo pi = null;
4733        ContentProviderRecord cpr = mProvidersByName.get(authority);
4734        if (cpr != null) {
4735            pi = cpr.info;
4736        } else {
4737            try {
4738                pi = pm.resolveContentProvider(authority,
4739                        PackageManager.GET_URI_PERMISSION_PATTERNS);
4740            } catch (RemoteException ex) {
4741            }
4742        }
4743        if (pi == null) {
4744            Slog.w(TAG, "No content provider found for: " + authority);
4745            return;
4746        }
4747
4748        // Does the caller have this permission on the URI?
4749        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4750            // Right now, if you are not the original owner of the permission,
4751            // you are not allowed to revoke it.
4752            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4753                throw new SecurityException("Uid " + callingUid
4754                        + " does not have permission to uri " + uri);
4755            //}
4756        }
4757
4758        // Go through all of the permissions and remove any that match.
4759        final List<String> SEGMENTS = uri.getPathSegments();
4760        if (SEGMENTS != null) {
4761            final int NS = SEGMENTS.size();
4762            int N = mGrantedUriPermissions.size();
4763            for (int i=0; i<N; i++) {
4764                HashMap<Uri, UriPermission> perms
4765                        = mGrantedUriPermissions.valueAt(i);
4766                Iterator<UriPermission> it = perms.values().iterator();
4767            toploop:
4768                while (it.hasNext()) {
4769                    UriPermission perm = it.next();
4770                    Uri targetUri = perm.uri;
4771                    if (!authority.equals(targetUri.getAuthority())) {
4772                        continue;
4773                    }
4774                    List<String> targetSegments = targetUri.getPathSegments();
4775                    if (targetSegments == null) {
4776                        continue;
4777                    }
4778                    if (targetSegments.size() < NS) {
4779                        continue;
4780                    }
4781                    for (int j=0; j<NS; j++) {
4782                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4783                            continue toploop;
4784                        }
4785                    }
4786                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4787                            "Revoking " + perm.uid + " permission to " + perm.uri);
4788                    perm.clearModes(modeFlags);
4789                    if (perm.modeFlags == 0) {
4790                        it.remove();
4791                    }
4792                }
4793                if (perms.size() == 0) {
4794                    mGrantedUriPermissions.remove(
4795                            mGrantedUriPermissions.keyAt(i));
4796                    N--;
4797                    i--;
4798                }
4799            }
4800        }
4801    }
4802
4803    public void revokeUriPermission(IApplicationThread caller, Uri uri,
4804            int modeFlags) {
4805        synchronized(this) {
4806            final ProcessRecord r = getRecordForAppLocked(caller);
4807            if (r == null) {
4808                throw new SecurityException("Unable to find app for caller "
4809                        + caller
4810                        + " when revoking permission to uri " + uri);
4811            }
4812            if (uri == null) {
4813                Slog.w(TAG, "revokeUriPermission: null uri");
4814                return;
4815            }
4816
4817            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4818                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4819            if (modeFlags == 0) {
4820                return;
4821            }
4822
4823            final IPackageManager pm = AppGlobals.getPackageManager();
4824
4825            final String authority = uri.getAuthority();
4826            ProviderInfo pi = null;
4827            ContentProviderRecord cpr = mProvidersByName.get(authority);
4828            if (cpr != null) {
4829                pi = cpr.info;
4830            } else {
4831                try {
4832                    pi = pm.resolveContentProvider(authority,
4833                            PackageManager.GET_URI_PERMISSION_PATTERNS);
4834                } catch (RemoteException ex) {
4835                }
4836            }
4837            if (pi == null) {
4838                Slog.w(TAG, "No content provider found for: " + authority);
4839                return;
4840            }
4841
4842            revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4843        }
4844    }
4845
4846    @Override
4847    public IBinder newUriPermissionOwner(String name) {
4848        synchronized(this) {
4849            UriPermissionOwner owner = new UriPermissionOwner(this, name);
4850            return owner.getExternalTokenLocked();
4851        }
4852    }
4853
4854    @Override
4855    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4856            Uri uri, int modeFlags) {
4857        synchronized(this) {
4858            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4859            if (owner == null) {
4860                throw new IllegalArgumentException("Unknown owner: " + token);
4861            }
4862            if (fromUid != Binder.getCallingUid()) {
4863                if (Binder.getCallingUid() != Process.myUid()) {
4864                    // Only system code can grant URI permissions on behalf
4865                    // of other users.
4866                    throw new SecurityException("nice try");
4867                }
4868            }
4869            if (targetPkg == null) {
4870                throw new IllegalArgumentException("null target");
4871            }
4872            if (uri == null) {
4873                throw new IllegalArgumentException("null uri");
4874            }
4875
4876            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4877        }
4878    }
4879
4880    @Override
4881    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4882        synchronized(this) {
4883            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4884            if (owner == null) {
4885                throw new IllegalArgumentException("Unknown owner: " + token);
4886            }
4887
4888            if (uri == null) {
4889                owner.removeUriPermissionsLocked(mode);
4890            } else {
4891                owner.removeUriPermissionLocked(uri, mode);
4892            }
4893        }
4894    }
4895
4896    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4897        synchronized (this) {
4898            ProcessRecord app =
4899                who != null ? getRecordForAppLocked(who) : null;
4900            if (app == null) return;
4901
4902            Message msg = Message.obtain();
4903            msg.what = WAIT_FOR_DEBUGGER_MSG;
4904            msg.obj = app;
4905            msg.arg1 = waiting ? 1 : 0;
4906            mHandler.sendMessage(msg);
4907        }
4908    }
4909
4910    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
4911        outInfo.availMem = Process.getFreeMemory();
4912        outInfo.threshold = HOME_APP_MEM;
4913        outInfo.lowMemory = outInfo.availMem <
4914                (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
4915    }
4916
4917    // =========================================================
4918    // TASK MANAGEMENT
4919    // =========================================================
4920
4921    public List getTasks(int maxNum, int flags,
4922                         IThumbnailReceiver receiver) {
4923        ArrayList list = new ArrayList();
4924
4925        PendingThumbnailsRecord pending = null;
4926        IApplicationThread topThumbnail = null;
4927        ActivityRecord topRecord = null;
4928
4929        synchronized(this) {
4930            if (localLOGV) Slog.v(
4931                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4932                + ", receiver=" + receiver);
4933
4934            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4935                    != PackageManager.PERMISSION_GRANTED) {
4936                if (receiver != null) {
4937                    // If the caller wants to wait for pending thumbnails,
4938                    // it ain't gonna get them.
4939                    try {
4940                        receiver.finished();
4941                    } catch (RemoteException ex) {
4942                    }
4943                }
4944                String msg = "Permission Denial: getTasks() from pid="
4945                        + Binder.getCallingPid()
4946                        + ", uid=" + Binder.getCallingUid()
4947                        + " requires " + android.Manifest.permission.GET_TASKS;
4948                Slog.w(TAG, msg);
4949                throw new SecurityException(msg);
4950            }
4951
4952            int pos = mMainStack.mHistory.size()-1;
4953            ActivityRecord next =
4954                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
4955            ActivityRecord top = null;
4956            TaskRecord curTask = null;
4957            int numActivities = 0;
4958            int numRunning = 0;
4959            while (pos >= 0 && maxNum > 0) {
4960                final ActivityRecord r = next;
4961                pos--;
4962                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
4963
4964                // Initialize state for next task if needed.
4965                if (top == null ||
4966                        (top.state == ActivityState.INITIALIZING
4967                            && top.task == r.task)) {
4968                    top = r;
4969                    curTask = r.task;
4970                    numActivities = numRunning = 0;
4971                }
4972
4973                // Add 'r' into the current task.
4974                numActivities++;
4975                if (r.app != null && r.app.thread != null) {
4976                    numRunning++;
4977                }
4978
4979                if (localLOGV) Slog.v(
4980                    TAG, r.intent.getComponent().flattenToShortString()
4981                    + ": task=" + r.task);
4982
4983                // If the next one is a different task, generate a new
4984                // TaskInfo entry for what we have.
4985                if (next == null || next.task != curTask) {
4986                    ActivityManager.RunningTaskInfo ci
4987                            = new ActivityManager.RunningTaskInfo();
4988                    ci.id = curTask.taskId;
4989                    ci.baseActivity = r.intent.getComponent();
4990                    ci.topActivity = top.intent.getComponent();
4991                    if (top.thumbHolder != null) {
4992                        ci.description = top.thumbHolder.lastDescription;
4993                    }
4994                    ci.numActivities = numActivities;
4995                    ci.numRunning = numRunning;
4996                    //System.out.println(
4997                    //    "#" + maxNum + ": " + " descr=" + ci.description);
4998                    if (ci.thumbnail == null && receiver != null) {
4999                        if (localLOGV) Slog.v(
5000                            TAG, "State=" + top.state + "Idle=" + top.idle
5001                            + " app=" + top.app
5002                            + " thr=" + (top.app != null ? top.app.thread : null));
5003                        if (top.state == ActivityState.RESUMED
5004                                || top.state == ActivityState.PAUSING) {
5005                            if (top.idle && top.app != null
5006                                && top.app.thread != null) {
5007                                topRecord = top;
5008                                topThumbnail = top.app.thread;
5009                            } else {
5010                                top.thumbnailNeeded = true;
5011                            }
5012                        }
5013                        if (pending == null) {
5014                            pending = new PendingThumbnailsRecord(receiver);
5015                        }
5016                        pending.pendingRecords.add(top);
5017                    }
5018                    list.add(ci);
5019                    maxNum--;
5020                    top = null;
5021                }
5022            }
5023
5024            if (pending != null) {
5025                mPendingThumbnails.add(pending);
5026            }
5027        }
5028
5029        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5030
5031        if (topThumbnail != null) {
5032            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5033            try {
5034                topThumbnail.requestThumbnail(topRecord);
5035            } catch (Exception e) {
5036                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5037                sendPendingThumbnail(null, topRecord, null, null, true);
5038            }
5039        }
5040
5041        if (pending == null && receiver != null) {
5042            // In this case all thumbnails were available and the client
5043            // is being asked to be told when the remaining ones come in...
5044            // which is unusually, since the top-most currently running
5045            // activity should never have a canned thumbnail!  Oh well.
5046            try {
5047                receiver.finished();
5048            } catch (RemoteException ex) {
5049            }
5050        }
5051
5052        return list;
5053    }
5054
5055    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5056            int flags) {
5057        synchronized (this) {
5058            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5059                    "getRecentTasks()");
5060
5061            IPackageManager pm = AppGlobals.getPackageManager();
5062
5063            final int N = mRecentTasks.size();
5064            ArrayList<ActivityManager.RecentTaskInfo> res
5065                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5066                            maxNum < N ? maxNum : N);
5067            for (int i=0; i<N && maxNum > 0; i++) {
5068                TaskRecord tr = mRecentTasks.get(i);
5069                if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5070                        || (tr.intent == null)
5071                        || ((tr.intent.getFlags()
5072                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5073                    ActivityManager.RecentTaskInfo rti
5074                            = new ActivityManager.RecentTaskInfo();
5075                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5076                    rti.persistentId = tr.taskId;
5077                    rti.baseIntent = new Intent(
5078                            tr.intent != null ? tr.intent : tr.affinityIntent);
5079                    rti.origActivity = tr.origActivity;
5080                    rti.description = tr.lastDescription;
5081
5082                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5083                        // Check whether this activity is currently available.
5084                        try {
5085                            if (rti.origActivity != null) {
5086                                if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5087                                    continue;
5088                                }
5089                            } else if (rti.baseIntent != null) {
5090                                if (pm.queryIntentActivities(rti.baseIntent,
5091                                        null, 0) == null) {
5092                                    continue;
5093                                }
5094                            }
5095                        } catch (RemoteException e) {
5096                            // Will never happen.
5097                        }
5098                    }
5099
5100                    res.add(rti);
5101                    maxNum--;
5102                }
5103            }
5104            return res;
5105        }
5106    }
5107
5108    private TaskRecord taskForIdLocked(int id) {
5109        final int N = mRecentTasks.size();
5110        for (int i=0; i<N; i++) {
5111            TaskRecord tr = mRecentTasks.get(i);
5112            if (tr.taskId == id) {
5113                return tr;
5114            }
5115        }
5116        return null;
5117    }
5118
5119    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5120        synchronized (this) {
5121            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5122                    "getTaskThumbnails()");
5123            TaskRecord tr = taskForIdLocked(id);
5124            if (tr != null) {
5125                return mMainStack.getTaskThumbnailsLocked(tr);
5126            }
5127        }
5128        return null;
5129    }
5130
5131    public boolean removeSubTask(int taskId, int subTaskIndex) {
5132        synchronized (this) {
5133            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5134                    "removeSubTask()");
5135            long ident = Binder.clearCallingIdentity();
5136            try {
5137                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5138            } finally {
5139                Binder.restoreCallingIdentity(ident);
5140            }
5141        }
5142    }
5143
5144    private void removeTaskProcessesLocked(ActivityRecord root) {
5145        TaskRecord tr = root.task;
5146        Intent baseIntent = new Intent(
5147                tr.intent != null ? tr.intent : tr.affinityIntent);
5148        ComponentName component = baseIntent.getComponent();
5149        if (component == null) {
5150            Slog.w(TAG, "Now component for base intent of task: " + tr);
5151            return;
5152        }
5153
5154        // Find any running services associated with this app.
5155        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5156        for (ServiceRecord sr : mServices.values()) {
5157            if (sr.packageName.equals(component.getPackageName())) {
5158                services.add(sr);
5159            }
5160        }
5161
5162        // Take care of any running services associated with the app.
5163        for (int i=0; i<services.size(); i++) {
5164            ServiceRecord sr = services.get(i);
5165            if (sr.startRequested) {
5166                if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
5167                    stopServiceLocked(sr);
5168                } else {
5169                    sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5170                            sr.makeNextStartId(), baseIntent, -1));
5171                    if (sr.app != null && sr.app.thread != null) {
5172                        sendServiceArgsLocked(sr, false);
5173                    }
5174                }
5175            }
5176        }
5177
5178        // Find any running processes associated with this app.
5179        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5180        SparseArray<ProcessRecord> appProcs
5181                = mProcessNames.getMap().get(component.getPackageName());
5182        if (appProcs != null) {
5183            for (int i=0; i<appProcs.size(); i++) {
5184                procs.add(appProcs.valueAt(i));
5185            }
5186        }
5187
5188        // Kill the running processes.
5189        for (int i=0; i<procs.size(); i++) {
5190            ProcessRecord pr = procs.get(i);
5191            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5192                Slog.i(TAG, "Killing " + pr + ": remove task");
5193                EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5194                        pr.processName, pr.setAdj, "remove task");
5195                Process.killProcessQuiet(pr.pid);
5196            } else {
5197                pr.waitingToKill = "remove task";
5198            }
5199        }
5200    }
5201
5202    public boolean removeTask(int taskId, int flags) {
5203        synchronized (this) {
5204            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5205                    "removeTask()");
5206            long ident = Binder.clearCallingIdentity();
5207            try {
5208                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5209                if (r != null) {
5210                    mRecentTasks.remove(r.task);
5211
5212                    if ((flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0) {
5213                        removeTaskProcessesLocked(r);
5214                    }
5215
5216                    return true;
5217                }
5218            } finally {
5219                Binder.restoreCallingIdentity(ident);
5220            }
5221        }
5222        return false;
5223    }
5224
5225    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5226        int j;
5227        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5228        TaskRecord jt = startTask;
5229
5230        // First look backwards
5231        for (j=startIndex-1; j>=0; j--) {
5232            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5233            if (r.task != jt) {
5234                jt = r.task;
5235                if (affinity.equals(jt.affinity)) {
5236                    return j;
5237                }
5238            }
5239        }
5240
5241        // Now look forwards
5242        final int N = mMainStack.mHistory.size();
5243        jt = startTask;
5244        for (j=startIndex+1; j<N; j++) {
5245            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5246            if (r.task != jt) {
5247                if (affinity.equals(jt.affinity)) {
5248                    return j;
5249                }
5250                jt = r.task;
5251            }
5252        }
5253
5254        // Might it be at the top?
5255        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5256            return N-1;
5257        }
5258
5259        return -1;
5260    }
5261
5262    /**
5263     * TODO: Add mController hook
5264     */
5265    public void moveTaskToFront(int task, int flags) {
5266        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5267                "moveTaskToFront()");
5268
5269        synchronized(this) {
5270            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5271                    Binder.getCallingUid(), "Task to front")) {
5272                return;
5273            }
5274            final long origId = Binder.clearCallingIdentity();
5275            try {
5276                TaskRecord tr = taskForIdLocked(task);
5277                if (tr != null) {
5278                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5279                        mMainStack.mUserLeaving = true;
5280                    }
5281                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5282                        // Caller wants the home activity moved with it.  To accomplish this,
5283                        // we'll just move the home task to the top first.
5284                        mMainStack.moveHomeToFrontLocked();
5285                    }
5286                    mMainStack.moveTaskToFrontLocked(tr, null);
5287                    return;
5288                }
5289                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5290                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5291                    if (hr.task.taskId == task) {
5292                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5293                            mMainStack.mUserLeaving = true;
5294                        }
5295                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5296                            // Caller wants the home activity moved with it.  To accomplish this,
5297                            // we'll just move the home task to the top first.
5298                            mMainStack.moveHomeToFrontLocked();
5299                        }
5300                        mMainStack.moveTaskToFrontLocked(hr.task, null);
5301                        return;
5302                    }
5303                }
5304            } finally {
5305                Binder.restoreCallingIdentity(origId);
5306            }
5307        }
5308    }
5309
5310    public void moveTaskToBack(int task) {
5311        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5312                "moveTaskToBack()");
5313
5314        synchronized(this) {
5315            if (mMainStack.mResumedActivity != null
5316                    && mMainStack.mResumedActivity.task.taskId == task) {
5317                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5318                        Binder.getCallingUid(), "Task to back")) {
5319                    return;
5320                }
5321            }
5322            final long origId = Binder.clearCallingIdentity();
5323            mMainStack.moveTaskToBackLocked(task, null);
5324            Binder.restoreCallingIdentity(origId);
5325        }
5326    }
5327
5328    /**
5329     * Moves an activity, and all of the other activities within the same task, to the bottom
5330     * of the history stack.  The activity's order within the task is unchanged.
5331     *
5332     * @param token A reference to the activity we wish to move
5333     * @param nonRoot If false then this only works if the activity is the root
5334     *                of a task; if true it will work for any activity in a task.
5335     * @return Returns true if the move completed, false if not.
5336     */
5337    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5338        synchronized(this) {
5339            final long origId = Binder.clearCallingIdentity();
5340            int taskId = getTaskForActivityLocked(token, !nonRoot);
5341            if (taskId >= 0) {
5342                return mMainStack.moveTaskToBackLocked(taskId, null);
5343            }
5344            Binder.restoreCallingIdentity(origId);
5345        }
5346        return false;
5347    }
5348
5349    public void moveTaskBackwards(int task) {
5350        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5351                "moveTaskBackwards()");
5352
5353        synchronized(this) {
5354            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5355                    Binder.getCallingUid(), "Task backwards")) {
5356                return;
5357            }
5358            final long origId = Binder.clearCallingIdentity();
5359            moveTaskBackwardsLocked(task);
5360            Binder.restoreCallingIdentity(origId);
5361        }
5362    }
5363
5364    private final void moveTaskBackwardsLocked(int task) {
5365        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5366    }
5367
5368    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5369        synchronized(this) {
5370            return getTaskForActivityLocked(token, onlyRoot);
5371        }
5372    }
5373
5374    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5375        final int N = mMainStack.mHistory.size();
5376        TaskRecord lastTask = null;
5377        for (int i=0; i<N; i++) {
5378            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5379            if (r == token) {
5380                if (!onlyRoot || lastTask != r.task) {
5381                    return r.task.taskId;
5382                }
5383                return -1;
5384            }
5385            lastTask = r.task;
5386        }
5387
5388        return -1;
5389    }
5390
5391    public void finishOtherInstances(IBinder token, ComponentName className) {
5392        synchronized(this) {
5393            final long origId = Binder.clearCallingIdentity();
5394
5395            int N = mMainStack.mHistory.size();
5396            TaskRecord lastTask = null;
5397            for (int i=0; i<N; i++) {
5398                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5399                if (r.realActivity.equals(className)
5400                        && r != token && lastTask != r.task) {
5401                    if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
5402                            null, "others")) {
5403                        i--;
5404                        N--;
5405                    }
5406                }
5407                lastTask = r.task;
5408            }
5409
5410            Binder.restoreCallingIdentity(origId);
5411        }
5412    }
5413
5414    // =========================================================
5415    // THUMBNAILS
5416    // =========================================================
5417
5418    public void reportThumbnail(IBinder token,
5419            Bitmap thumbnail, CharSequence description) {
5420        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5421        final long origId = Binder.clearCallingIdentity();
5422        sendPendingThumbnail(null, token, thumbnail, description, true);
5423        Binder.restoreCallingIdentity(origId);
5424    }
5425
5426    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5427            Bitmap thumbnail, CharSequence description, boolean always) {
5428        TaskRecord task = null;
5429        ArrayList receivers = null;
5430
5431        //System.out.println("Send pending thumbnail: " + r);
5432
5433        synchronized(this) {
5434            if (r == null) {
5435                int index = mMainStack.indexOfTokenLocked(token);
5436                if (index < 0) {
5437                    return;
5438                }
5439                r = (ActivityRecord)mMainStack.mHistory.get(index);
5440            }
5441            if (thumbnail == null && r.thumbHolder != null) {
5442                thumbnail = r.thumbHolder.lastThumbnail;
5443                description = r.thumbHolder.lastDescription;
5444            }
5445            if (thumbnail == null && !always) {
5446                // If there is no thumbnail, and this entry is not actually
5447                // going away, then abort for now and pick up the next
5448                // thumbnail we get.
5449                return;
5450            }
5451            task = r.task;
5452
5453            int N = mPendingThumbnails.size();
5454            int i=0;
5455            while (i<N) {
5456                PendingThumbnailsRecord pr =
5457                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5458                //System.out.println("Looking in " + pr.pendingRecords);
5459                if (pr.pendingRecords.remove(r)) {
5460                    if (receivers == null) {
5461                        receivers = new ArrayList();
5462                    }
5463                    receivers.add(pr);
5464                    if (pr.pendingRecords.size() == 0) {
5465                        pr.finished = true;
5466                        mPendingThumbnails.remove(i);
5467                        N--;
5468                        continue;
5469                    }
5470                }
5471                i++;
5472            }
5473        }
5474
5475        if (receivers != null) {
5476            final int N = receivers.size();
5477            for (int i=0; i<N; i++) {
5478                try {
5479                    PendingThumbnailsRecord pr =
5480                        (PendingThumbnailsRecord)receivers.get(i);
5481                    pr.receiver.newThumbnail(
5482                        task != null ? task.taskId : -1, thumbnail, description);
5483                    if (pr.finished) {
5484                        pr.receiver.finished();
5485                    }
5486                } catch (Exception e) {
5487                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
5488                }
5489            }
5490        }
5491    }
5492
5493    // =========================================================
5494    // CONTENT PROVIDERS
5495    // =========================================================
5496
5497    private final List generateApplicationProvidersLocked(ProcessRecord app) {
5498        List providers = null;
5499        try {
5500            providers = AppGlobals.getPackageManager().
5501                queryContentProviders(app.processName, app.info.uid,
5502                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
5503        } catch (RemoteException ex) {
5504        }
5505        if (providers != null) {
5506            final int N = providers.size();
5507            for (int i=0; i<N; i++) {
5508                ProviderInfo cpi =
5509                    (ProviderInfo)providers.get(i);
5510                ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
5511                if (cpr == null) {
5512                    cpr = new ContentProviderRecord(cpi, app.info);
5513                    mProvidersByClass.put(cpi.name, cpr);
5514                }
5515                app.pubProviders.put(cpi.name, cpr);
5516                app.addPackage(cpi.applicationInfo.packageName);
5517                ensurePackageDexOpt(cpi.applicationInfo.packageName);
5518            }
5519        }
5520        return providers;
5521    }
5522
5523    private final String checkContentProviderPermissionLocked(
5524            ProviderInfo cpi, ProcessRecord r) {
5525        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5526        final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5527        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
5528                cpi.applicationInfo.uid, cpi.exported)
5529                == PackageManager.PERMISSION_GRANTED) {
5530            return null;
5531        }
5532        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
5533                cpi.applicationInfo.uid, cpi.exported)
5534                == PackageManager.PERMISSION_GRANTED) {
5535            return null;
5536        }
5537
5538        PathPermission[] pps = cpi.pathPermissions;
5539        if (pps != null) {
5540            int i = pps.length;
5541            while (i > 0) {
5542                i--;
5543                PathPermission pp = pps[i];
5544                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
5545                        cpi.applicationInfo.uid, cpi.exported)
5546                        == PackageManager.PERMISSION_GRANTED) {
5547                    return null;
5548                }
5549                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
5550                        cpi.applicationInfo.uid, cpi.exported)
5551                        == PackageManager.PERMISSION_GRANTED) {
5552                    return null;
5553                }
5554            }
5555        }
5556
5557        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5558        if (perms != null) {
5559            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5560                if (uri.getKey().getAuthority().equals(cpi.authority)) {
5561                    return null;
5562                }
5563            }
5564        }
5565
5566        String msg;
5567        if (!cpi.exported) {
5568            msg = "Permission Denial: opening provider " + cpi.name
5569                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5570                    + ", uid=" + callingUid + ") that is not exported from uid "
5571                    + cpi.applicationInfo.uid;
5572        } else {
5573            msg = "Permission Denial: opening provider " + cpi.name
5574                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5575                    + ", uid=" + callingUid + ") requires "
5576                    + cpi.readPermission + " or " + cpi.writePermission;
5577        }
5578        Slog.w(TAG, msg);
5579        return msg;
5580    }
5581
5582    private final ContentProviderHolder getContentProviderImpl(
5583        IApplicationThread caller, String name) {
5584        ContentProviderRecord cpr;
5585        ProviderInfo cpi = null;
5586
5587        synchronized(this) {
5588            ProcessRecord r = null;
5589            if (caller != null) {
5590                r = getRecordForAppLocked(caller);
5591                if (r == null) {
5592                    throw new SecurityException(
5593                            "Unable to find app for caller " + caller
5594                          + " (pid=" + Binder.getCallingPid()
5595                          + ") when getting content provider " + name);
5596                }
5597            }
5598
5599            // First check if this content provider has been published...
5600            cpr = mProvidersByName.get(name);
5601            if (cpr != null) {
5602                cpi = cpr.info;
5603                String msg;
5604                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5605                    throw new SecurityException(msg);
5606                }
5607
5608                if (r != null && cpr.canRunHere(r)) {
5609                    // This provider has been published or is in the process
5610                    // of being published...  but it is also allowed to run
5611                    // in the caller's process, so don't make a connection
5612                    // and just let the caller instantiate its own instance.
5613                    if (cpr.provider != null) {
5614                        // don't give caller the provider object, it needs
5615                        // to make its own.
5616                        cpr = new ContentProviderRecord(cpr);
5617                    }
5618                    return cpr;
5619                }
5620
5621                final long origId = Binder.clearCallingIdentity();
5622
5623                // In this case the provider instance already exists, so we can
5624                // return it right away.
5625                if (r != null) {
5626                    if (DEBUG_PROVIDER) Slog.v(TAG,
5627                            "Adding provider requested by "
5628                            + r.processName + " from process "
5629                            + cpr.info.processName);
5630                    Integer cnt = r.conProviders.get(cpr);
5631                    if (cnt == null) {
5632                        r.conProviders.put(cpr, new Integer(1));
5633                    } else {
5634                        r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5635                    }
5636                    cpr.clients.add(r);
5637                    if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) {
5638                        // If this is a perceptible app accessing the provider,
5639                        // make sure to count it as being accessed and thus
5640                        // back up on the LRU list.  This is good because
5641                        // content providers are often expensive to start.
5642                        updateLruProcessLocked(cpr.app, false, true);
5643                    }
5644                } else {
5645                    cpr.externals++;
5646                }
5647
5648                if (cpr.app != null) {
5649                    updateOomAdjLocked(cpr.app);
5650                }
5651
5652                Binder.restoreCallingIdentity(origId);
5653
5654            } else {
5655                try {
5656                    cpi = AppGlobals.getPackageManager().
5657                        resolveContentProvider(name,
5658                                STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
5659                } catch (RemoteException ex) {
5660                }
5661                if (cpi == null) {
5662                    return null;
5663                }
5664
5665                String msg;
5666                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5667                    throw new SecurityException(msg);
5668                }
5669
5670                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
5671                        && !cpi.processName.equals("system")) {
5672                    // If this content provider does not run in the system
5673                    // process, and the system is not yet ready to run other
5674                    // processes, then fail fast instead of hanging.
5675                    throw new IllegalArgumentException(
5676                            "Attempt to launch content provider before system ready");
5677                }
5678
5679                cpr = mProvidersByClass.get(cpi.name);
5680                final boolean firstClass = cpr == null;
5681                if (firstClass) {
5682                    try {
5683                        ApplicationInfo ai =
5684                            AppGlobals.getPackageManager().
5685                                getApplicationInfo(
5686                                        cpi.applicationInfo.packageName,
5687                                        STOCK_PM_FLAGS);
5688                        if (ai == null) {
5689                            Slog.w(TAG, "No package info for content provider "
5690                                    + cpi.name);
5691                            return null;
5692                        }
5693                        cpr = new ContentProviderRecord(cpi, ai);
5694                    } catch (RemoteException ex) {
5695                        // pm is in same process, this will never happen.
5696                    }
5697                }
5698
5699                if (r != null && cpr.canRunHere(r)) {
5700                    // If this is a multiprocess provider, then just return its
5701                    // info and allow the caller to instantiate it.  Only do
5702                    // this if the provider is the same user as the caller's
5703                    // process, or can run as root (so can be in any process).
5704                    return cpr;
5705                }
5706
5707                if (DEBUG_PROVIDER) {
5708                    RuntimeException e = new RuntimeException("here");
5709                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
5710                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
5711                }
5712
5713                // This is single process, and our app is now connecting to it.
5714                // See if we are already in the process of launching this
5715                // provider.
5716                final int N = mLaunchingProviders.size();
5717                int i;
5718                for (i=0; i<N; i++) {
5719                    if (mLaunchingProviders.get(i) == cpr) {
5720                        break;
5721                    }
5722                }
5723
5724                // If the provider is not already being launched, then get it
5725                // started.
5726                if (i >= N) {
5727                    final long origId = Binder.clearCallingIdentity();
5728
5729                    try {
5730                        // Content provider is now in use, its package can't be stopped.
5731                        try {
5732                            AppGlobals.getPackageManager().setPackageStoppedState(
5733                                    cpr.appInfo.packageName, false);
5734                        } catch (RemoteException e) {
5735                        } catch (IllegalArgumentException e) {
5736                            Slog.w(TAG, "Failed trying to unstop package "
5737                                    + cpr.appInfo.packageName + ": " + e);
5738                        }
5739
5740                        ProcessRecord proc = startProcessLocked(cpi.processName,
5741                                cpr.appInfo, false, 0, "content provider",
5742                                new ComponentName(cpi.applicationInfo.packageName,
5743                                        cpi.name), false);
5744                        if (proc == null) {
5745                            Slog.w(TAG, "Unable to launch app "
5746                                    + cpi.applicationInfo.packageName + "/"
5747                                    + cpi.applicationInfo.uid + " for provider "
5748                                    + name + ": process is bad");
5749                            return null;
5750                        }
5751                        cpr.launchingApp = proc;
5752                        mLaunchingProviders.add(cpr);
5753                    } finally {
5754                        Binder.restoreCallingIdentity(origId);
5755                    }
5756                }
5757
5758                // Make sure the provider is published (the same provider class
5759                // may be published under multiple names).
5760                if (firstClass) {
5761                    mProvidersByClass.put(cpi.name, cpr);
5762                }
5763                mProvidersByName.put(name, cpr);
5764
5765                if (r != null) {
5766                    if (DEBUG_PROVIDER) Slog.v(TAG,
5767                            "Adding provider requested by "
5768                            + r.processName + " from process "
5769                            + cpr.info.processName);
5770                    Integer cnt = r.conProviders.get(cpr);
5771                    if (cnt == null) {
5772                        r.conProviders.put(cpr, new Integer(1));
5773                    } else {
5774                        r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5775                    }
5776                    cpr.clients.add(r);
5777                } else {
5778                    cpr.externals++;
5779                }
5780            }
5781        }
5782
5783        // Wait for the provider to be published...
5784        synchronized (cpr) {
5785            while (cpr.provider == null) {
5786                if (cpr.launchingApp == null) {
5787                    Slog.w(TAG, "Unable to launch app "
5788                            + cpi.applicationInfo.packageName + "/"
5789                            + cpi.applicationInfo.uid + " for provider "
5790                            + name + ": launching app became null");
5791                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
5792                            cpi.applicationInfo.packageName,
5793                            cpi.applicationInfo.uid, name);
5794                    return null;
5795                }
5796                try {
5797                    cpr.wait();
5798                } catch (InterruptedException ex) {
5799                }
5800            }
5801        }
5802        return cpr;
5803    }
5804
5805    public final ContentProviderHolder getContentProvider(
5806            IApplicationThread caller, String name) {
5807        if (caller == null) {
5808            String msg = "null IApplicationThread when getting content provider "
5809                    + name;
5810            Slog.w(TAG, msg);
5811            throw new SecurityException(msg);
5812        }
5813
5814        return getContentProviderImpl(caller, name);
5815    }
5816
5817    private ContentProviderHolder getContentProviderExternal(String name) {
5818        return getContentProviderImpl(null, name);
5819    }
5820
5821    /**
5822     * Drop a content provider from a ProcessRecord's bookkeeping
5823     * @param cpr
5824     */
5825    public void removeContentProvider(IApplicationThread caller, String name) {
5826        synchronized (this) {
5827            ContentProviderRecord cpr = mProvidersByName.get(name);
5828            if(cpr == null) {
5829                // remove from mProvidersByClass
5830                if (DEBUG_PROVIDER) Slog.v(TAG, name +
5831                        " provider not found in providers list");
5832                return;
5833            }
5834            final ProcessRecord r = getRecordForAppLocked(caller);
5835            if (r == null) {
5836                throw new SecurityException(
5837                        "Unable to find app for caller " + caller +
5838                        " when removing content provider " + name);
5839            }
5840            //update content provider record entry info
5841            ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
5842            if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
5843                    + r.info.processName + " from process "
5844                    + localCpr.appInfo.processName);
5845            if (localCpr.app == r) {
5846                //should not happen. taken care of as a local provider
5847                Slog.w(TAG, "removeContentProvider called on local provider: "
5848                        + cpr.info.name + " in process " + r.processName);
5849                return;
5850            } else {
5851                Integer cnt = r.conProviders.get(localCpr);
5852                if (cnt == null || cnt.intValue() <= 1) {
5853                    localCpr.clients.remove(r);
5854                    r.conProviders.remove(localCpr);
5855                } else {
5856                    r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5857                }
5858            }
5859            updateOomAdjLocked();
5860        }
5861    }
5862
5863    private void removeContentProviderExternal(String name) {
5864        synchronized (this) {
5865            ContentProviderRecord cpr = mProvidersByName.get(name);
5866            if(cpr == null) {
5867                //remove from mProvidersByClass
5868                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
5869                return;
5870            }
5871
5872            //update content provider record entry info
5873            ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
5874            localCpr.externals--;
5875            if (localCpr.externals < 0) {
5876                Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
5877            }
5878            updateOomAdjLocked();
5879        }
5880    }
5881
5882    public final void publishContentProviders(IApplicationThread caller,
5883            List<ContentProviderHolder> providers) {
5884        if (providers == null) {
5885            return;
5886        }
5887
5888        synchronized(this) {
5889            final ProcessRecord r = getRecordForAppLocked(caller);
5890            if (r == null) {
5891                throw new SecurityException(
5892                        "Unable to find app for caller " + caller
5893                      + " (pid=" + Binder.getCallingPid()
5894                      + ") when publishing content providers");
5895            }
5896
5897            final long origId = Binder.clearCallingIdentity();
5898
5899            final int N = providers.size();
5900            for (int i=0; i<N; i++) {
5901                ContentProviderHolder src = providers.get(i);
5902                if (src == null || src.info == null || src.provider == null) {
5903                    continue;
5904                }
5905                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
5906                if (dst != null) {
5907                    mProvidersByClass.put(dst.info.name, dst);
5908                    String names[] = dst.info.authority.split(";");
5909                    for (int j = 0; j < names.length; j++) {
5910                        mProvidersByName.put(names[j], dst);
5911                    }
5912
5913                    int NL = mLaunchingProviders.size();
5914                    int j;
5915                    for (j=0; j<NL; j++) {
5916                        if (mLaunchingProviders.get(j) == dst) {
5917                            mLaunchingProviders.remove(j);
5918                            j--;
5919                            NL--;
5920                        }
5921                    }
5922                    synchronized (dst) {
5923                        dst.provider = src.provider;
5924                        dst.app = r;
5925                        dst.notifyAll();
5926                    }
5927                    updateOomAdjLocked(r);
5928                }
5929            }
5930
5931            Binder.restoreCallingIdentity(origId);
5932        }
5933    }
5934
5935    public static final void installSystemProviders() {
5936        List providers;
5937        synchronized (mSelf) {
5938            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5939            providers = mSelf.generateApplicationProvidersLocked(app);
5940            if (providers != null) {
5941                for (int i=providers.size()-1; i>=0; i--) {
5942                    ProviderInfo pi = (ProviderInfo)providers.get(i);
5943                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5944                        Slog.w(TAG, "Not installing system proc provider " + pi.name
5945                                + ": not system .apk");
5946                        providers.remove(i);
5947                    }
5948                }
5949            }
5950        }
5951        if (providers != null) {
5952            mSystemThread.installSystemProviders(providers);
5953        }
5954
5955        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
5956    }
5957
5958    /**
5959     * Allows app to retrieve the MIME type of a URI without having permission
5960     * to access its content provider.
5961     *
5962     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5963     *
5964     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5965     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5966     */
5967    public String getProviderMimeType(Uri uri) {
5968        final String name = uri.getAuthority();
5969        final long ident = Binder.clearCallingIdentity();
5970        ContentProviderHolder holder = null;
5971
5972        try {
5973            holder = getContentProviderExternal(name);
5974            if (holder != null) {
5975                return holder.provider.getType(uri);
5976            }
5977        } catch (RemoteException e) {
5978            Log.w(TAG, "Content provider dead retrieving " + uri, e);
5979            return null;
5980        } finally {
5981            if (holder != null) {
5982                removeContentProviderExternal(name);
5983            }
5984            Binder.restoreCallingIdentity(ident);
5985        }
5986
5987        return null;
5988    }
5989
5990    // =========================================================
5991    // GLOBAL MANAGEMENT
5992    // =========================================================
5993
5994    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5995            ApplicationInfo info, String customProcess) {
5996        String proc = customProcess != null ? customProcess : info.processName;
5997        BatteryStatsImpl.Uid.Proc ps = null;
5998        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5999        synchronized (stats) {
6000            ps = stats.getProcessStatsLocked(info.uid, proc);
6001        }
6002        return new ProcessRecord(ps, thread, info, proc);
6003    }
6004
6005    final ProcessRecord addAppLocked(ApplicationInfo info) {
6006        ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6007
6008        if (app == null) {
6009            app = newProcessRecordLocked(null, info, null);
6010            mProcessNames.put(info.processName, info.uid, app);
6011            updateLruProcessLocked(app, true, true);
6012        }
6013
6014        // This package really, really can not be stopped.
6015        try {
6016            AppGlobals.getPackageManager().setPackageStoppedState(
6017                    info.packageName, false);
6018        } catch (RemoteException e) {
6019        } catch (IllegalArgumentException e) {
6020            Slog.w(TAG, "Failed trying to unstop package "
6021                    + info.packageName + ": " + e);
6022        }
6023
6024        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6025                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6026            app.persistent = true;
6027            app.maxAdj = CORE_SERVER_ADJ;
6028        }
6029        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6030            mPersistentStartingProcesses.add(app);
6031            startProcessLocked(app, "added application", app.processName);
6032        }
6033
6034        return app;
6035    }
6036
6037    public void unhandledBack() {
6038        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6039                "unhandledBack()");
6040
6041        synchronized(this) {
6042            int count = mMainStack.mHistory.size();
6043            if (DEBUG_SWITCH) Slog.d(
6044                TAG, "Performing unhandledBack(): stack size = " + count);
6045            if (count > 1) {
6046                final long origId = Binder.clearCallingIdentity();
6047                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6048                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6049                Binder.restoreCallingIdentity(origId);
6050            }
6051        }
6052    }
6053
6054    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6055        String name = uri.getAuthority();
6056        ContentProviderHolder cph = getContentProviderExternal(name);
6057        ParcelFileDescriptor pfd = null;
6058        if (cph != null) {
6059            // We record the binder invoker's uid in thread-local storage before
6060            // going to the content provider to open the file.  Later, in the code
6061            // that handles all permissions checks, we look for this uid and use
6062            // that rather than the Activity Manager's own uid.  The effect is that
6063            // we do the check against the caller's permissions even though it looks
6064            // to the content provider like the Activity Manager itself is making
6065            // the request.
6066            sCallerIdentity.set(new Identity(
6067                    Binder.getCallingPid(), Binder.getCallingUid()));
6068            try {
6069                pfd = cph.provider.openFile(uri, "r");
6070            } catch (FileNotFoundException e) {
6071                // do nothing; pfd will be returned null
6072            } finally {
6073                // Ensure that whatever happens, we clean up the identity state
6074                sCallerIdentity.remove();
6075            }
6076
6077            // We've got the fd now, so we're done with the provider.
6078            removeContentProviderExternal(name);
6079        } else {
6080            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6081        }
6082        return pfd;
6083    }
6084
6085    // Actually is sleeping or shutting down or whatever else in the future
6086    // is an inactive state.
6087    public boolean isSleeping() {
6088        return mSleeping || mShuttingDown;
6089    }
6090
6091    public void goingToSleep() {
6092        synchronized(this) {
6093            mSleeping = true;
6094            mWindowManager.setEventDispatching(false);
6095
6096            mMainStack.stopIfSleepingLocked();
6097
6098            // Initialize the wake times of all processes.
6099            checkExcessivePowerUsageLocked(false);
6100            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6101            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6102            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6103        }
6104    }
6105
6106    public boolean shutdown(int timeout) {
6107        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6108                != PackageManager.PERMISSION_GRANTED) {
6109            throw new SecurityException("Requires permission "
6110                    + android.Manifest.permission.SHUTDOWN);
6111        }
6112
6113        boolean timedout = false;
6114
6115        synchronized(this) {
6116            mShuttingDown = true;
6117            mWindowManager.setEventDispatching(false);
6118
6119            if (mMainStack.mResumedActivity != null) {
6120                mMainStack.stopIfSleepingLocked();
6121                final long endTime = System.currentTimeMillis() + timeout;
6122                while (mMainStack.mResumedActivity != null
6123                        || mMainStack.mPausingActivity != null) {
6124                    long delay = endTime - System.currentTimeMillis();
6125                    if (delay <= 0) {
6126                        Slog.w(TAG, "Activity manager shutdown timed out");
6127                        timedout = true;
6128                        break;
6129                    }
6130                    try {
6131                        this.wait();
6132                    } catch (InterruptedException e) {
6133                    }
6134                }
6135            }
6136        }
6137
6138        mUsageStatsService.shutdown();
6139        mBatteryStatsService.shutdown();
6140
6141        return timedout;
6142    }
6143
6144    public final void activitySlept(IBinder token) {
6145        if (localLOGV) Slog.v(
6146            TAG, "Activity slept: token=" + token);
6147
6148        ActivityRecord r = null;
6149
6150        final long origId = Binder.clearCallingIdentity();
6151
6152        synchronized (this) {
6153            int index = mMainStack.indexOfTokenLocked(token);
6154            if (index >= 0) {
6155                r = (ActivityRecord)mMainStack.mHistory.get(index);
6156                mMainStack.activitySleptLocked(r);
6157            }
6158        }
6159
6160        Binder.restoreCallingIdentity(origId);
6161    }
6162
6163    public void wakingUp() {
6164        synchronized(this) {
6165            mWindowManager.setEventDispatching(true);
6166            mSleeping = false;
6167            mMainStack.awakeFromSleepingLocked();
6168            mMainStack.resumeTopActivityLocked(null);
6169        }
6170    }
6171
6172    public void stopAppSwitches() {
6173        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6174                != PackageManager.PERMISSION_GRANTED) {
6175            throw new SecurityException("Requires permission "
6176                    + android.Manifest.permission.STOP_APP_SWITCHES);
6177        }
6178
6179        synchronized(this) {
6180            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6181                    + APP_SWITCH_DELAY_TIME;
6182            mDidAppSwitch = false;
6183            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6184            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6185            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6186        }
6187    }
6188
6189    public void resumeAppSwitches() {
6190        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6191                != PackageManager.PERMISSION_GRANTED) {
6192            throw new SecurityException("Requires permission "
6193                    + android.Manifest.permission.STOP_APP_SWITCHES);
6194        }
6195
6196        synchronized(this) {
6197            // Note that we don't execute any pending app switches... we will
6198            // let those wait until either the timeout, or the next start
6199            // activity request.
6200            mAppSwitchesAllowedTime = 0;
6201        }
6202    }
6203
6204    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6205            String name) {
6206        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6207            return true;
6208        }
6209
6210        final int perm = checkComponentPermission(
6211                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
6212                callingUid, -1, true);
6213        if (perm == PackageManager.PERMISSION_GRANTED) {
6214            return true;
6215        }
6216
6217        Slog.w(TAG, name + " request from " + callingUid + " stopped");
6218        return false;
6219    }
6220
6221    public void setDebugApp(String packageName, boolean waitForDebugger,
6222            boolean persistent) {
6223        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6224                "setDebugApp()");
6225
6226        // Note that this is not really thread safe if there are multiple
6227        // callers into it at the same time, but that's not a situation we
6228        // care about.
6229        if (persistent) {
6230            final ContentResolver resolver = mContext.getContentResolver();
6231            Settings.System.putString(
6232                resolver, Settings.System.DEBUG_APP,
6233                packageName);
6234            Settings.System.putInt(
6235                resolver, Settings.System.WAIT_FOR_DEBUGGER,
6236                waitForDebugger ? 1 : 0);
6237        }
6238
6239        synchronized (this) {
6240            if (!persistent) {
6241                mOrigDebugApp = mDebugApp;
6242                mOrigWaitForDebugger = mWaitForDebugger;
6243            }
6244            mDebugApp = packageName;
6245            mWaitForDebugger = waitForDebugger;
6246            mDebugTransient = !persistent;
6247            if (packageName != null) {
6248                final long origId = Binder.clearCallingIdentity();
6249                forceStopPackageLocked(packageName, -1, false, false, true);
6250                Binder.restoreCallingIdentity(origId);
6251            }
6252        }
6253    }
6254
6255    public void setAlwaysFinish(boolean enabled) {
6256        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6257                "setAlwaysFinish()");
6258
6259        Settings.System.putInt(
6260                mContext.getContentResolver(),
6261                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6262
6263        synchronized (this) {
6264            mAlwaysFinishActivities = enabled;
6265        }
6266    }
6267
6268    public void setActivityController(IActivityController controller) {
6269        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
6270                "setActivityController()");
6271        synchronized (this) {
6272            mController = controller;
6273        }
6274    }
6275
6276    public boolean isUserAMonkey() {
6277        // For now the fact that there is a controller implies
6278        // we have a monkey.
6279        synchronized (this) {
6280            return mController != null;
6281        }
6282    }
6283
6284    public void registerActivityWatcher(IActivityWatcher watcher) {
6285        synchronized (this) {
6286            mWatchers.register(watcher);
6287        }
6288    }
6289
6290    public void unregisterActivityWatcher(IActivityWatcher watcher) {
6291        synchronized (this) {
6292            mWatchers.unregister(watcher);
6293        }
6294    }
6295
6296    public void registerProcessObserver(IProcessObserver observer) {
6297        mProcessObservers.register(observer);
6298    }
6299
6300    public void unregisterProcessObserver(IProcessObserver observer) {
6301        mProcessObservers.unregister(observer);
6302    }
6303
6304    public void setImmersive(IBinder token, boolean immersive) {
6305        synchronized(this) {
6306            int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
6307            if (index < 0) {
6308                throw new IllegalArgumentException();
6309            }
6310            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
6311            r.immersive = immersive;
6312        }
6313    }
6314
6315    public boolean isImmersive(IBinder token) {
6316        synchronized (this) {
6317            int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
6318            if (index < 0) {
6319                throw new IllegalArgumentException();
6320            }
6321            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
6322            return r.immersive;
6323        }
6324    }
6325
6326    public boolean isTopActivityImmersive() {
6327        synchronized (this) {
6328            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
6329            return (r != null) ? r.immersive : false;
6330        }
6331    }
6332
6333    public final void enterSafeMode() {
6334        synchronized(this) {
6335            // It only makes sense to do this before the system is ready
6336            // and started launching other packages.
6337            if (!mSystemReady) {
6338                try {
6339                    AppGlobals.getPackageManager().enterSafeMode();
6340                } catch (RemoteException e) {
6341                }
6342            }
6343        }
6344    }
6345
6346    public final void showSafeModeOverlay() {
6347        View v = LayoutInflater.from(mContext).inflate(
6348                com.android.internal.R.layout.safe_mode, null);
6349        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6350        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6351        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6352        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6353        lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6354        lp.format = v.getBackground().getOpacity();
6355        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6356                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6357        ((WindowManager)mContext.getSystemService(
6358                Context.WINDOW_SERVICE)).addView(v, lp);
6359    }
6360
6361    public void noteWakeupAlarm(IIntentSender sender) {
6362        if (!(sender instanceof PendingIntentRecord)) {
6363            return;
6364        }
6365        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6366        synchronized (stats) {
6367            if (mBatteryStatsService.isOnBattery()) {
6368                mBatteryStatsService.enforceCallingPermission();
6369                PendingIntentRecord rec = (PendingIntentRecord)sender;
6370                int MY_UID = Binder.getCallingUid();
6371                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6372                BatteryStatsImpl.Uid.Pkg pkg =
6373                    stats.getPackageStatsLocked(uid, rec.key.packageName);
6374                pkg.incWakeupsLocked();
6375            }
6376        }
6377    }
6378
6379    public boolean killPids(int[] pids, String pReason, boolean secure) {
6380        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
6381            throw new SecurityException("killPids only available to the system");
6382        }
6383        String reason = (pReason == null) ? "Unknown" : pReason;
6384        // XXX Note: don't acquire main activity lock here, because the window
6385        // manager calls in with its locks held.
6386
6387        boolean killed = false;
6388        synchronized (mPidsSelfLocked) {
6389            int[] types = new int[pids.length];
6390            int worstType = 0;
6391            for (int i=0; i<pids.length; i++) {
6392                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6393                if (proc != null) {
6394                    int type = proc.setAdj;
6395                    types[i] = type;
6396                    if (type > worstType) {
6397                        worstType = type;
6398                    }
6399                }
6400            }
6401
6402            // If the worst oom_adj is somewhere in the hidden proc LRU range,
6403            // then constrain it so we will kill all hidden procs.
6404            if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
6405                worstType = HIDDEN_APP_MIN_ADJ;
6406            }
6407
6408            // If this is not a secure call, don't let it kill processes that
6409            // are important.
6410            if (!secure && worstType < SECONDARY_SERVER_ADJ) {
6411                worstType = SECONDARY_SERVER_ADJ;
6412            }
6413
6414            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
6415            for (int i=0; i<pids.length; i++) {
6416                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6417                if (proc == null) {
6418                    continue;
6419                }
6420                int adj = proc.setAdj;
6421                if (adj >= worstType && !proc.killedBackground) {
6422                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
6423                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6424                            proc.processName, adj, reason);
6425                    killed = true;
6426                    proc.killedBackground = true;
6427                    Process.killProcessQuiet(pids[i]);
6428                }
6429            }
6430        }
6431        return killed;
6432    }
6433
6434    public final void startRunning(String pkg, String cls, String action,
6435            String data) {
6436        synchronized(this) {
6437            if (mStartRunning) {
6438                return;
6439            }
6440            mStartRunning = true;
6441            mTopComponent = pkg != null && cls != null
6442                    ? new ComponentName(pkg, cls) : null;
6443            mTopAction = action != null ? action : Intent.ACTION_MAIN;
6444            mTopData = data;
6445            if (!mSystemReady) {
6446                return;
6447            }
6448        }
6449
6450        systemReady(null);
6451    }
6452
6453    private void retrieveSettings() {
6454        final ContentResolver resolver = mContext.getContentResolver();
6455        String debugApp = Settings.System.getString(
6456            resolver, Settings.System.DEBUG_APP);
6457        boolean waitForDebugger = Settings.System.getInt(
6458            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6459        boolean alwaysFinishActivities = Settings.System.getInt(
6460            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6461
6462        Configuration configuration = new Configuration();
6463        Settings.System.getConfiguration(resolver, configuration);
6464
6465        synchronized (this) {
6466            mDebugApp = mOrigDebugApp = debugApp;
6467            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6468            mAlwaysFinishActivities = alwaysFinishActivities;
6469            // This happens before any activities are started, so we can
6470            // change mConfiguration in-place.
6471            mConfiguration.updateFrom(configuration);
6472            mConfigurationSeq = mConfiguration.seq = 1;
6473            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
6474        }
6475    }
6476
6477    public boolean testIsSystemReady() {
6478        // no need to synchronize(this) just to read & return the value
6479        return mSystemReady;
6480    }
6481
6482    private static File getCalledPreBootReceiversFile() {
6483        File dataDir = Environment.getDataDirectory();
6484        File systemDir = new File(dataDir, "system");
6485        File fname = new File(systemDir, "called_pre_boots.dat");
6486        return fname;
6487    }
6488
6489    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6490        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6491        File file = getCalledPreBootReceiversFile();
6492        FileInputStream fis = null;
6493        try {
6494            fis = new FileInputStream(file);
6495            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6496            int vers = dis.readInt();
6497            String codename = dis.readUTF();
6498            if (vers == android.os.Build.VERSION.SDK_INT
6499                    && codename.equals(android.os.Build.VERSION.CODENAME)) {
6500                int num = dis.readInt();
6501                while (num > 0) {
6502                    num--;
6503                    String pkg = dis.readUTF();
6504                    String cls = dis.readUTF();
6505                    lastDoneReceivers.add(new ComponentName(pkg, cls));
6506                }
6507            }
6508        } catch (FileNotFoundException e) {
6509        } catch (IOException e) {
6510            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6511        } finally {
6512            if (fis != null) {
6513                try {
6514                    fis.close();
6515                } catch (IOException e) {
6516                }
6517            }
6518        }
6519        return lastDoneReceivers;
6520    }
6521
6522    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6523        File file = getCalledPreBootReceiversFile();
6524        FileOutputStream fos = null;
6525        DataOutputStream dos = null;
6526        try {
6527            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6528            fos = new FileOutputStream(file);
6529            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6530            dos.writeInt(android.os.Build.VERSION.SDK_INT);
6531            dos.writeUTF(android.os.Build.VERSION.CODENAME);
6532            dos.writeInt(list.size());
6533            for (int i=0; i<list.size(); i++) {
6534                dos.writeUTF(list.get(i).getPackageName());
6535                dos.writeUTF(list.get(i).getClassName());
6536            }
6537        } catch (IOException e) {
6538            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6539            file.delete();
6540        } finally {
6541            FileUtils.sync(fos);
6542            if (dos != null) {
6543                try {
6544                    dos.close();
6545                } catch (IOException e) {
6546                    // TODO Auto-generated catch block
6547                    e.printStackTrace();
6548                }
6549            }
6550        }
6551    }
6552
6553    public void systemReady(final Runnable goingCallback) {
6554        // In the simulator, startRunning will never have been called, which
6555        // normally sets a few crucial variables. Do it here instead.
6556        if (!Process.supportsProcesses()) {
6557            mStartRunning = true;
6558            mTopAction = Intent.ACTION_MAIN;
6559        }
6560
6561        synchronized(this) {
6562            if (mSystemReady) {
6563                if (goingCallback != null) goingCallback.run();
6564                return;
6565            }
6566
6567            // Check to see if there are any update receivers to run.
6568            if (!mDidUpdate) {
6569                if (mWaitingUpdate) {
6570                    return;
6571                }
6572                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6573                List<ResolveInfo> ris = null;
6574                try {
6575                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
6576                                intent, null, 0);
6577                } catch (RemoteException e) {
6578                }
6579                if (ris != null) {
6580                    for (int i=ris.size()-1; i>=0; i--) {
6581                        if ((ris.get(i).activityInfo.applicationInfo.flags
6582                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
6583                            ris.remove(i);
6584                        }
6585                    }
6586                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
6587
6588                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6589
6590                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
6591                    for (int i=0; i<ris.size(); i++) {
6592                        ActivityInfo ai = ris.get(i).activityInfo;
6593                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
6594                        if (lastDoneReceivers.contains(comp)) {
6595                            ris.remove(i);
6596                            i--;
6597                        }
6598                    }
6599
6600                    for (int i=0; i<ris.size(); i++) {
6601                        ActivityInfo ai = ris.get(i).activityInfo;
6602                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
6603                        doneReceivers.add(comp);
6604                        intent.setComponent(comp);
6605                        IIntentReceiver finisher = null;
6606                        if (i == ris.size()-1) {
6607                            finisher = new IIntentReceiver.Stub() {
6608                                public void performReceive(Intent intent, int resultCode,
6609                                        String data, Bundle extras, boolean ordered,
6610                                        boolean sticky) {
6611                                    // The raw IIntentReceiver interface is called
6612                                    // with the AM lock held, so redispatch to
6613                                    // execute our code without the lock.
6614                                    mHandler.post(new Runnable() {
6615                                        public void run() {
6616                                            synchronized (ActivityManagerService.this) {
6617                                                mDidUpdate = true;
6618                                            }
6619                                            writeLastDonePreBootReceivers(doneReceivers);
6620                                            systemReady(goingCallback);
6621                                        }
6622                                    });
6623                                }
6624                            };
6625                        }
6626                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
6627                        broadcastIntentLocked(null, null, intent, null, finisher,
6628                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
6629                        if (finisher != null) {
6630                            mWaitingUpdate = true;
6631                        }
6632                    }
6633                }
6634                if (mWaitingUpdate) {
6635                    return;
6636                }
6637                mDidUpdate = true;
6638            }
6639
6640            mSystemReady = true;
6641            if (!mStartRunning) {
6642                return;
6643            }
6644        }
6645
6646        ArrayList<ProcessRecord> procsToKill = null;
6647        synchronized(mPidsSelfLocked) {
6648            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6649                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6650                if (!isAllowedWhileBooting(proc.info)){
6651                    if (procsToKill == null) {
6652                        procsToKill = new ArrayList<ProcessRecord>();
6653                    }
6654                    procsToKill.add(proc);
6655                }
6656            }
6657        }
6658
6659        synchronized(this) {
6660            if (procsToKill != null) {
6661                for (int i=procsToKill.size()-1; i>=0; i--) {
6662                    ProcessRecord proc = procsToKill.get(i);
6663                    Slog.i(TAG, "Removing system update proc: " + proc);
6664                    removeProcessLocked(proc, true);
6665                }
6666            }
6667
6668            // Now that we have cleaned up any update processes, we
6669            // are ready to start launching real processes and know that
6670            // we won't trample on them any more.
6671            mProcessesReady = true;
6672        }
6673
6674        Slog.i(TAG, "System now ready");
6675        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
6676            SystemClock.uptimeMillis());
6677
6678        synchronized(this) {
6679            // Make sure we have no pre-ready processes sitting around.
6680
6681            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6682                ResolveInfo ri = mContext.getPackageManager()
6683                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
6684                                STOCK_PM_FLAGS);
6685                CharSequence errorMsg = null;
6686                if (ri != null) {
6687                    ActivityInfo ai = ri.activityInfo;
6688                    ApplicationInfo app = ai.applicationInfo;
6689                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6690                        mTopAction = Intent.ACTION_FACTORY_TEST;
6691                        mTopData = null;
6692                        mTopComponent = new ComponentName(app.packageName,
6693                                ai.name);
6694                    } else {
6695                        errorMsg = mContext.getResources().getText(
6696                                com.android.internal.R.string.factorytest_not_system);
6697                    }
6698                } else {
6699                    errorMsg = mContext.getResources().getText(
6700                            com.android.internal.R.string.factorytest_no_action);
6701                }
6702                if (errorMsg != null) {
6703                    mTopAction = null;
6704                    mTopData = null;
6705                    mTopComponent = null;
6706                    Message msg = Message.obtain();
6707                    msg.what = SHOW_FACTORY_ERROR_MSG;
6708                    msg.getData().putCharSequence("msg", errorMsg);
6709                    mHandler.sendMessage(msg);
6710                }
6711            }
6712        }
6713
6714        retrieveSettings();
6715
6716        if (goingCallback != null) goingCallback.run();
6717
6718        synchronized (this) {
6719            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6720                try {
6721                    List apps = AppGlobals.getPackageManager().
6722                        getPersistentApplications(STOCK_PM_FLAGS);
6723                    if (apps != null) {
6724                        int N = apps.size();
6725                        int i;
6726                        for (i=0; i<N; i++) {
6727                            ApplicationInfo info
6728                                = (ApplicationInfo)apps.get(i);
6729                            if (info != null &&
6730                                    !info.packageName.equals("android")) {
6731                                addAppLocked(info);
6732                            }
6733                        }
6734                    }
6735                } catch (RemoteException ex) {
6736                    // pm is in same process, this will never happen.
6737                }
6738            }
6739
6740            // Start up initial activity.
6741            mBooting = true;
6742
6743            try {
6744                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
6745                    Message msg = Message.obtain();
6746                    msg.what = SHOW_UID_ERROR_MSG;
6747                    mHandler.sendMessage(msg);
6748                }
6749            } catch (RemoteException e) {
6750            }
6751
6752            mMainStack.resumeTopActivityLocked(null);
6753        }
6754    }
6755
6756    private boolean makeAppCrashingLocked(ProcessRecord app,
6757            String shortMsg, String longMsg, String stackTrace) {
6758        app.crashing = true;
6759        app.crashingReport = generateProcessError(app,
6760                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
6761        startAppProblemLocked(app);
6762        app.stopFreezingAllLocked();
6763        return handleAppCrashLocked(app);
6764    }
6765
6766    private void makeAppNotRespondingLocked(ProcessRecord app,
6767            String activity, String shortMsg, String longMsg) {
6768        app.notResponding = true;
6769        app.notRespondingReport = generateProcessError(app,
6770                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6771                activity, shortMsg, longMsg, null);
6772        startAppProblemLocked(app);
6773        app.stopFreezingAllLocked();
6774    }
6775
6776    /**
6777     * Generate a process error record, suitable for attachment to a ProcessRecord.
6778     *
6779     * @param app The ProcessRecord in which the error occurred.
6780     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
6781     *                      ActivityManager.AppErrorStateInfo
6782     * @param activity The activity associated with the crash, if known.
6783     * @param shortMsg Short message describing the crash.
6784     * @param longMsg Long message describing the crash.
6785     * @param stackTrace Full crash stack trace, may be null.
6786     *
6787     * @return Returns a fully-formed AppErrorStateInfo record.
6788     */
6789    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
6790            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
6791        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
6792
6793        report.condition = condition;
6794        report.processName = app.processName;
6795        report.pid = app.pid;
6796        report.uid = app.info.uid;
6797        report.tag = activity;
6798        report.shortMsg = shortMsg;
6799        report.longMsg = longMsg;
6800        report.stackTrace = stackTrace;
6801
6802        return report;
6803    }
6804
6805    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
6806        synchronized (this) {
6807            app.crashing = false;
6808            app.crashingReport = null;
6809            app.notResponding = false;
6810            app.notRespondingReport = null;
6811            if (app.anrDialog == fromDialog) {
6812                app.anrDialog = null;
6813            }
6814            if (app.waitDialog == fromDialog) {
6815                app.waitDialog = null;
6816            }
6817            if (app.pid > 0 && app.pid != MY_PID) {
6818                handleAppCrashLocked(app);
6819                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
6820                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6821                        app.processName, app.setAdj, "user's request after error");
6822                Process.killProcessQuiet(app.pid);
6823            }
6824        }
6825    }
6826
6827    private boolean handleAppCrashLocked(ProcessRecord app) {
6828        long now = SystemClock.uptimeMillis();
6829
6830        Long crashTime = mProcessCrashTimes.get(app.info.processName,
6831                app.info.uid);
6832        if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
6833            // This process loses!
6834            Slog.w(TAG, "Process " + app.info.processName
6835                    + " has crashed too many times: killing!");
6836            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
6837                    app.info.processName, app.info.uid);
6838            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6839                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6840                if (r.app == app) {
6841                    Slog.w(TAG, "  Force finishing activity "
6842                        + r.intent.getComponent().flattenToShortString());
6843                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
6844                }
6845            }
6846            if (!app.persistent) {
6847                // Don't let services in this process be restarted and potentially
6848                // annoy the user repeatedly.  Unless it is persistent, since those
6849                // processes run critical code.
6850                killServicesLocked(app, false);
6851                // We don't want to start this process again until the user
6852                // explicitly does so...  but for persistent process, we really
6853                // need to keep it running.  If a persistent process is actually
6854                // repeatedly crashing, then badness for everyone.
6855                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
6856                        app.info.processName);
6857                mBadProcesses.put(app.info.processName, app.info.uid, now);
6858                app.bad = true;
6859                mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6860                app.removed = true;
6861                removeProcessLocked(app, false);
6862                mMainStack.resumeTopActivityLocked(null);
6863                return false;
6864            }
6865            mMainStack.resumeTopActivityLocked(null);
6866        } else {
6867            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
6868            if (r.app == app) {
6869                // If the top running activity is from this crashing
6870                // process, then terminate it to avoid getting in a loop.
6871                Slog.w(TAG, "  Force finishing activity "
6872                        + r.intent.getComponent().flattenToShortString());
6873                int index = mMainStack.indexOfTokenLocked(r);
6874                r.stack.finishActivityLocked(r, index,
6875                        Activity.RESULT_CANCELED, null, "crashed");
6876                // Also terminate any activities below it that aren't yet
6877                // stopped, to avoid a situation where one will get
6878                // re-start our crashing activity once it gets resumed again.
6879                index--;
6880                if (index >= 0) {
6881                    r = (ActivityRecord)mMainStack.mHistory.get(index);
6882                    if (r.state == ActivityState.RESUMED
6883                            || r.state == ActivityState.PAUSING
6884                            || r.state == ActivityState.PAUSED) {
6885                        if (!r.isHomeActivity || mHomeProcess != r.app) {
6886                            Slog.w(TAG, "  Force finishing activity "
6887                                    + r.intent.getComponent().flattenToShortString());
6888                            r.stack.finishActivityLocked(r, index,
6889                                    Activity.RESULT_CANCELED, null, "crashed");
6890                        }
6891                    }
6892                }
6893            }
6894        }
6895
6896        // Bump up the crash count of any services currently running in the proc.
6897        if (app.services.size() != 0) {
6898            // Any services running in the application need to be placed
6899            // back in the pending list.
6900            Iterator<ServiceRecord> it = app.services.iterator();
6901            while (it.hasNext()) {
6902                ServiceRecord sr = it.next();
6903                sr.crashCount++;
6904            }
6905        }
6906
6907        // If the crashing process is what we consider to be the "home process" and it has been
6908        // replaced by a third-party app, clear the package preferred activities from packages
6909        // with a home activity running in the process to prevent a repeatedly crashing app
6910        // from blocking the user to manually clear the list.
6911        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6912                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6913            Iterator it = mHomeProcess.activities.iterator();
6914            while (it.hasNext()) {
6915                ActivityRecord r = (ActivityRecord)it.next();
6916                if (r.isHomeActivity) {
6917                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6918                    try {
6919                        ActivityThread.getPackageManager()
6920                                .clearPackagePreferredActivities(r.packageName);
6921                    } catch (RemoteException c) {
6922                        // pm is in same process, this will never happen.
6923                    }
6924                }
6925            }
6926        }
6927
6928        mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6929        return true;
6930    }
6931
6932    void startAppProblemLocked(ProcessRecord app) {
6933        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6934                mContext, app.info.packageName, app.info.flags);
6935        skipCurrentReceiverLocked(app);
6936    }
6937
6938    void skipCurrentReceiverLocked(ProcessRecord app) {
6939        boolean reschedule = false;
6940        BroadcastRecord r = app.curReceiver;
6941        if (r != null) {
6942            // The current broadcast is waiting for this app's receiver
6943            // to be finished.  Looks like that's not going to happen, so
6944            // let the broadcast continue.
6945            logBroadcastReceiverDiscardLocked(r);
6946            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6947                    r.resultExtras, r.resultAbort, true);
6948            reschedule = true;
6949        }
6950        r = mPendingBroadcast;
6951        if (r != null && r.curApp == app) {
6952            if (DEBUG_BROADCAST) Slog.v(TAG,
6953                    "skip & discard pending app " + r);
6954            logBroadcastReceiverDiscardLocked(r);
6955            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6956                    r.resultExtras, r.resultAbort, true);
6957            reschedule = true;
6958        }
6959        if (reschedule) {
6960            scheduleBroadcastsLocked();
6961        }
6962    }
6963
6964    /**
6965     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6966     * The application process will exit immediately after this call returns.
6967     * @param app object of the crashing app, null for the system server
6968     * @param crashInfo describing the exception
6969     */
6970    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
6971        ProcessRecord r = findAppProcess(app, "Crash");
6972
6973        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6974                app == null ? "system" : (r == null ? "unknown" : r.processName),
6975                r == null ? -1 : r.info.flags,
6976                crashInfo.exceptionClassName,
6977                crashInfo.exceptionMessage,
6978                crashInfo.throwFileName,
6979                crashInfo.throwLineNumber);
6980
6981        addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
6982
6983        crashApplication(r, crashInfo);
6984    }
6985
6986    public void handleApplicationStrictModeViolation(
6987            IBinder app,
6988            int violationMask,
6989            StrictMode.ViolationInfo info) {
6990        ProcessRecord r = findAppProcess(app, "StrictMode");
6991        if (r == null) {
6992            return;
6993        }
6994
6995        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
6996            Integer stackFingerprint = info.hashCode();
6997            boolean logIt = true;
6998            synchronized (mAlreadyLoggedViolatedStacks) {
6999                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7000                    logIt = false;
7001                    // TODO: sub-sample into EventLog for these, with
7002                    // the info.durationMillis?  Then we'd get
7003                    // the relative pain numbers, without logging all
7004                    // the stack traces repeatedly.  We'd want to do
7005                    // likewise in the client code, which also does
7006                    // dup suppression, before the Binder call.
7007                } else {
7008                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7009                        mAlreadyLoggedViolatedStacks.clear();
7010                    }
7011                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7012                }
7013            }
7014            if (logIt) {
7015                logStrictModeViolationToDropBox(r, info);
7016            }
7017        }
7018
7019        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7020            AppErrorResult result = new AppErrorResult();
7021            synchronized (this) {
7022                final long origId = Binder.clearCallingIdentity();
7023
7024                Message msg = Message.obtain();
7025                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7026                HashMap<String, Object> data = new HashMap<String, Object>();
7027                data.put("result", result);
7028                data.put("app", r);
7029                data.put("violationMask", violationMask);
7030                data.put("info", info);
7031                msg.obj = data;
7032                mHandler.sendMessage(msg);
7033
7034                Binder.restoreCallingIdentity(origId);
7035            }
7036            int res = result.get();
7037            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7038        }
7039    }
7040
7041    // Depending on the policy in effect, there could be a bunch of
7042    // these in quick succession so we try to batch these together to
7043    // minimize disk writes, number of dropbox entries, and maximize
7044    // compression, by having more fewer, larger records.
7045    private void logStrictModeViolationToDropBox(
7046            ProcessRecord process,
7047            StrictMode.ViolationInfo info) {
7048        if (info == null) {
7049            return;
7050        }
7051        final boolean isSystemApp = process == null ||
7052                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7053                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7054        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7055        final DropBoxManager dbox = (DropBoxManager)
7056                mContext.getSystemService(Context.DROPBOX_SERVICE);
7057
7058        // Exit early if the dropbox isn't configured to accept this report type.
7059        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7060
7061        boolean bufferWasEmpty;
7062        boolean needsFlush;
7063        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7064        synchronized (sb) {
7065            bufferWasEmpty = sb.length() == 0;
7066            appendDropBoxProcessHeaders(process, sb);
7067            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7068            sb.append("System-App: ").append(isSystemApp).append("\n");
7069            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7070            if (info.violationNumThisLoop != 0) {
7071                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7072            }
7073            if (info.numAnimationsRunning != 0) {
7074                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7075            }
7076            if (info.broadcastIntentAction != null) {
7077                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7078            }
7079            if (info.durationMillis != -1) {
7080                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
7081            }
7082            if (info.numInstances != -1) {
7083                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7084            }
7085            if (info.tags != null) {
7086                for (String tag : info.tags) {
7087                    sb.append("Span-Tag: ").append(tag).append("\n");
7088                }
7089            }
7090            sb.append("\n");
7091            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7092                sb.append(info.crashInfo.stackTrace);
7093            }
7094            sb.append("\n");
7095
7096            // Only buffer up to ~64k.  Various logging bits truncate
7097            // things at 128k.
7098            needsFlush = (sb.length() > 64 * 1024);
7099        }
7100
7101        // Flush immediately if the buffer's grown too large, or this
7102        // is a non-system app.  Non-system apps are isolated with a
7103        // different tag & policy and not batched.
7104        //
7105        // Batching is useful during internal testing with
7106        // StrictMode settings turned up high.  Without batching,
7107        // thousands of separate files could be created on boot.
7108        if (!isSystemApp || needsFlush) {
7109            new Thread("Error dump: " + dropboxTag) {
7110                @Override
7111                public void run() {
7112                    String report;
7113                    synchronized (sb) {
7114                        report = sb.toString();
7115                        sb.delete(0, sb.length());
7116                        sb.trimToSize();
7117                    }
7118                    if (report.length() != 0) {
7119                        dbox.addText(dropboxTag, report);
7120                    }
7121                }
7122            }.start();
7123            return;
7124        }
7125
7126        // System app batching:
7127        if (!bufferWasEmpty) {
7128            // An existing dropbox-writing thread is outstanding, so
7129            // we don't need to start it up.  The existing thread will
7130            // catch the buffer appends we just did.
7131            return;
7132        }
7133
7134        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7135        // (After this point, we shouldn't access AMS internal data structures.)
7136        new Thread("Error dump: " + dropboxTag) {
7137            @Override
7138            public void run() {
7139                // 5 second sleep to let stacks arrive and be batched together
7140                try {
7141                    Thread.sleep(5000);  // 5 seconds
7142                } catch (InterruptedException e) {}
7143
7144                String errorReport;
7145                synchronized (mStrictModeBuffer) {
7146                    errorReport = mStrictModeBuffer.toString();
7147                    if (errorReport.length() == 0) {
7148                        return;
7149                    }
7150                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7151                    mStrictModeBuffer.trimToSize();
7152                }
7153                dbox.addText(dropboxTag, errorReport);
7154            }
7155        }.start();
7156    }
7157
7158    /**
7159     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7160     * @param app object of the crashing app, null for the system server
7161     * @param tag reported by the caller
7162     * @param crashInfo describing the context of the error
7163     * @return true if the process should exit immediately (WTF is fatal)
7164     */
7165    public boolean handleApplicationWtf(IBinder app, String tag,
7166            ApplicationErrorReport.CrashInfo crashInfo) {
7167        ProcessRecord r = findAppProcess(app, "WTF");
7168
7169        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7170                app == null ? "system" : (r == null ? "unknown" : r.processName),
7171                r == null ? -1 : r.info.flags,
7172                tag, crashInfo.exceptionMessage);
7173
7174        addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
7175
7176        if (r != null && r.pid != Process.myPid() &&
7177                Settings.Secure.getInt(mContext.getContentResolver(),
7178                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
7179            crashApplication(r, crashInfo);
7180            return true;
7181        } else {
7182            return false;
7183        }
7184    }
7185
7186    /**
7187     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7188     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7189     */
7190    private ProcessRecord findAppProcess(IBinder app, String reason) {
7191        if (app == null) {
7192            return null;
7193        }
7194
7195        synchronized (this) {
7196            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7197                final int NA = apps.size();
7198                for (int ia=0; ia<NA; ia++) {
7199                    ProcessRecord p = apps.valueAt(ia);
7200                    if (p.thread != null && p.thread.asBinder() == app) {
7201                        return p;
7202                    }
7203                }
7204            }
7205
7206            Slog.w(TAG, "Can't find mystery application for " + reason
7207                    + " from pid=" + Binder.getCallingPid()
7208                    + " uid=" + Binder.getCallingUid() + ": " + app);
7209            return null;
7210        }
7211    }
7212
7213    /**
7214     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7215     * to append various headers to the dropbox log text.
7216     */
7217    private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
7218        // Watchdog thread ends up invoking this function (with
7219        // a null ProcessRecord) to add the stack file to dropbox.
7220        // Do not acquire a lock on this (am) in such cases, as it
7221        // could cause a potential deadlock, if and when watchdog
7222        // is invoked due to unavailability of lock on am and it
7223        // would prevent watchdog from killing system_server.
7224        if (process == null) {
7225            sb.append("Process: system_server\n");
7226            return;
7227        }
7228        // Note: ProcessRecord 'process' is guarded by the service
7229        // instance.  (notably process.pkgList, which could otherwise change
7230        // concurrently during execution of this method)
7231        synchronized (this) {
7232            if (process.pid == MY_PID) {
7233                sb.append("Process: system_server\n");
7234            } else {
7235                sb.append("Process: ").append(process.processName).append("\n");
7236            }
7237            int flags = process.info.flags;
7238            IPackageManager pm = AppGlobals.getPackageManager();
7239            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7240            for (String pkg : process.pkgList) {
7241                sb.append("Package: ").append(pkg);
7242                try {
7243                    PackageInfo pi = pm.getPackageInfo(pkg, 0);
7244                    if (pi != null) {
7245                        sb.append(" v").append(pi.versionCode);
7246                        if (pi.versionName != null) {
7247                            sb.append(" (").append(pi.versionName).append(")");
7248                        }
7249                    }
7250                } catch (RemoteException e) {
7251                    Slog.e(TAG, "Error getting package info: " + pkg, e);
7252                }
7253                sb.append("\n");
7254            }
7255        }
7256    }
7257
7258    private static String processClass(ProcessRecord process) {
7259        if (process == null || process.pid == MY_PID) {
7260            return "system_server";
7261        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7262            return "system_app";
7263        } else {
7264            return "data_app";
7265        }
7266    }
7267
7268    /**
7269     * Write a description of an error (crash, WTF, ANR) to the drop box.
7270     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7271     * @param process which caused the error, null means the system server
7272     * @param activity which triggered the error, null if unknown
7273     * @param parent activity related to the error, null if unknown
7274     * @param subject line related to the error, null if absent
7275     * @param report in long form describing the error, null if absent
7276     * @param logFile to include in the report, null if none
7277     * @param crashInfo giving an application stack trace, null if absent
7278     */
7279    public void addErrorToDropBox(String eventType,
7280            ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7281            final String report, final File logFile,
7282            final ApplicationErrorReport.CrashInfo crashInfo) {
7283        // NOTE -- this must never acquire the ActivityManagerService lock,
7284        // otherwise the watchdog may be prevented from resetting the system.
7285
7286        final String dropboxTag = processClass(process) + "_" + eventType;
7287        final DropBoxManager dbox = (DropBoxManager)
7288                mContext.getSystemService(Context.DROPBOX_SERVICE);
7289
7290        // Exit early if the dropbox isn't configured to accept this report type.
7291        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7292
7293        final StringBuilder sb = new StringBuilder(1024);
7294        appendDropBoxProcessHeaders(process, sb);
7295        if (activity != null) {
7296            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7297        }
7298        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7299            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7300        }
7301        if (parent != null && parent != activity) {
7302            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7303        }
7304        if (subject != null) {
7305            sb.append("Subject: ").append(subject).append("\n");
7306        }
7307        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7308        if (Debug.isDebuggerConnected()) {
7309            sb.append("Debugger: Connected\n");
7310        }
7311        sb.append("\n");
7312
7313        // Do the rest in a worker thread to avoid blocking the caller on I/O
7314        // (After this point, we shouldn't access AMS internal data structures.)
7315        Thread worker = new Thread("Error dump: " + dropboxTag) {
7316            @Override
7317            public void run() {
7318                if (report != null) {
7319                    sb.append(report);
7320                }
7321                if (logFile != null) {
7322                    try {
7323                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7324                    } catch (IOException e) {
7325                        Slog.e(TAG, "Error reading " + logFile, e);
7326                    }
7327                }
7328                if (crashInfo != null && crashInfo.stackTrace != null) {
7329                    sb.append(crashInfo.stackTrace);
7330                }
7331
7332                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7333                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7334                if (lines > 0) {
7335                    sb.append("\n");
7336
7337                    // Merge several logcat streams, and take the last N lines
7338                    InputStreamReader input = null;
7339                    try {
7340                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7341                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7342                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7343
7344                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
7345                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
7346                        input = new InputStreamReader(logcat.getInputStream());
7347
7348                        int num;
7349                        char[] buf = new char[8192];
7350                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7351                    } catch (IOException e) {
7352                        Slog.e(TAG, "Error running logcat", e);
7353                    } finally {
7354                        if (input != null) try { input.close(); } catch (IOException e) {}
7355                    }
7356                }
7357
7358                dbox.addText(dropboxTag, sb.toString());
7359            }
7360        };
7361
7362        if (process == null || process.pid == MY_PID) {
7363            worker.run();  // We may be about to die -- need to run this synchronously
7364        } else {
7365            worker.start();
7366        }
7367    }
7368
7369    /**
7370     * Bring up the "unexpected error" dialog box for a crashing app.
7371     * Deal with edge cases (intercepts from instrumented applications,
7372     * ActivityController, error intent receivers, that sort of thing).
7373     * @param r the application crashing
7374     * @param crashInfo describing the failure
7375     */
7376    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
7377        long timeMillis = System.currentTimeMillis();
7378        String shortMsg = crashInfo.exceptionClassName;
7379        String longMsg = crashInfo.exceptionMessage;
7380        String stackTrace = crashInfo.stackTrace;
7381        if (shortMsg != null && longMsg != null) {
7382            longMsg = shortMsg + ": " + longMsg;
7383        } else if (shortMsg != null) {
7384            longMsg = shortMsg;
7385        }
7386
7387        AppErrorResult result = new AppErrorResult();
7388        synchronized (this) {
7389            if (mController != null) {
7390                try {
7391                    String name = r != null ? r.processName : null;
7392                    int pid = r != null ? r.pid : Binder.getCallingPid();
7393                    if (!mController.appCrashed(name, pid,
7394                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
7395                        Slog.w(TAG, "Force-killing crashed app " + name
7396                                + " at watcher's request");
7397                        Process.killProcess(pid);
7398                        return;
7399                    }
7400                } catch (RemoteException e) {
7401                    mController = null;
7402                }
7403            }
7404
7405            final long origId = Binder.clearCallingIdentity();
7406
7407            // If this process is running instrumentation, finish it.
7408            if (r != null && r.instrumentationClass != null) {
7409                Slog.w(TAG, "Error in app " + r.processName
7410                      + " running instrumentation " + r.instrumentationClass + ":");
7411                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
7412                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
7413                Bundle info = new Bundle();
7414                info.putString("shortMsg", shortMsg);
7415                info.putString("longMsg", longMsg);
7416                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7417                Binder.restoreCallingIdentity(origId);
7418                return;
7419            }
7420
7421            // If we can't identify the process or it's already exceeded its crash quota,
7422            // quit right away without showing a crash dialog.
7423            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
7424                Binder.restoreCallingIdentity(origId);
7425                return;
7426            }
7427
7428            Message msg = Message.obtain();
7429            msg.what = SHOW_ERROR_MSG;
7430            HashMap data = new HashMap();
7431            data.put("result", result);
7432            data.put("app", r);
7433            msg.obj = data;
7434            mHandler.sendMessage(msg);
7435
7436            Binder.restoreCallingIdentity(origId);
7437        }
7438
7439        int res = result.get();
7440
7441        Intent appErrorIntent = null;
7442        synchronized (this) {
7443            if (r != null) {
7444                mProcessCrashTimes.put(r.info.processName, r.info.uid,
7445                        SystemClock.uptimeMillis());
7446            }
7447            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
7448                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
7449            }
7450        }
7451
7452        if (appErrorIntent != null) {
7453            try {
7454                mContext.startActivity(appErrorIntent);
7455            } catch (ActivityNotFoundException e) {
7456                Slog.w(TAG, "bug report receiver dissappeared", e);
7457            }
7458        }
7459    }
7460
7461    Intent createAppErrorIntentLocked(ProcessRecord r,
7462            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7463        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
7464        if (report == null) {
7465            return null;
7466        }
7467        Intent result = new Intent(Intent.ACTION_APP_ERROR);
7468        result.setComponent(r.errorReportReceiver);
7469        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7470        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7471        return result;
7472    }
7473
7474    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7475            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7476        if (r.errorReportReceiver == null) {
7477            return null;
7478        }
7479
7480        if (!r.crashing && !r.notResponding) {
7481            return null;
7482        }
7483
7484        ApplicationErrorReport report = new ApplicationErrorReport();
7485        report.packageName = r.info.packageName;
7486        report.installerPackageName = r.errorReportReceiver.getPackageName();
7487        report.processName = r.processName;
7488        report.time = timeMillis;
7489        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
7490
7491        if (r.crashing) {
7492            report.type = ApplicationErrorReport.TYPE_CRASH;
7493            report.crashInfo = crashInfo;
7494        } else if (r.notResponding) {
7495            report.type = ApplicationErrorReport.TYPE_ANR;
7496            report.anrInfo = new ApplicationErrorReport.AnrInfo();
7497
7498            report.anrInfo.activity = r.notRespondingReport.tag;
7499            report.anrInfo.cause = r.notRespondingReport.shortMsg;
7500            report.anrInfo.info = r.notRespondingReport.longMsg;
7501        }
7502
7503        return report;
7504    }
7505
7506    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7507        // assume our apps are happy - lazy create the list
7508        List<ActivityManager.ProcessErrorStateInfo> errList = null;
7509
7510        synchronized (this) {
7511
7512            // iterate across all processes
7513            for (int i=mLruProcesses.size()-1; i>=0; i--) {
7514                ProcessRecord app = mLruProcesses.get(i);
7515                if ((app.thread != null) && (app.crashing || app.notResponding)) {
7516                    // This one's in trouble, so we'll generate a report for it
7517                    // crashes are higher priority (in case there's a crash *and* an anr)
7518                    ActivityManager.ProcessErrorStateInfo report = null;
7519                    if (app.crashing) {
7520                        report = app.crashingReport;
7521                    } else if (app.notResponding) {
7522                        report = app.notRespondingReport;
7523                    }
7524
7525                    if (report != null) {
7526                        if (errList == null) {
7527                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7528                        }
7529                        errList.add(report);
7530                    } else {
7531                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
7532                                " crashing = " + app.crashing +
7533                                " notResponding = " + app.notResponding);
7534                    }
7535                }
7536            }
7537        }
7538
7539        return errList;
7540    }
7541
7542    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7543        // Lazy instantiation of list
7544        List<ActivityManager.RunningAppProcessInfo> runList = null;
7545        synchronized (this) {
7546            // Iterate across all processes
7547            for (int i=mLruProcesses.size()-1; i>=0; i--) {
7548                ProcessRecord app = mLruProcesses.get(i);
7549                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7550                    // Generate process state info for running application
7551                    ActivityManager.RunningAppProcessInfo currApp =
7552                        new ActivityManager.RunningAppProcessInfo(app.processName,
7553                                app.pid, app.getPackageList());
7554                    currApp.uid = app.info.uid;
7555                    if (mHeavyWeightProcess == app) {
7556                        currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
7557                    }
7558                    if (app.persistent) {
7559                        currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7560                    }
7561                    int adj = app.curAdj;
7562                    if (adj >= EMPTY_APP_ADJ) {
7563                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7564                    } else if (adj >= HIDDEN_APP_MIN_ADJ) {
7565                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7566                        currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
7567                    } else if (adj >= HOME_APP_ADJ) {
7568                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7569                        currApp.lru = 0;
7570                    } else if (adj >= SECONDARY_SERVER_ADJ) {
7571                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7572                    } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
7573                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7574                    } else if (adj >= PERCEPTIBLE_APP_ADJ) {
7575                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7576                    } else if (adj >= VISIBLE_APP_ADJ) {
7577                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7578                    } else {
7579                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7580                    }
7581                    currApp.importanceReasonCode = app.adjTypeCode;
7582                    if (app.adjSource instanceof ProcessRecord) {
7583                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
7584                    } else if (app.adjSource instanceof ActivityRecord) {
7585                        ActivityRecord r = (ActivityRecord)app.adjSource;
7586                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7587                    }
7588                    if (app.adjTarget instanceof ComponentName) {
7589                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7590                    }
7591                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
7592                    //        + " lru=" + currApp.lru);
7593                    if (runList == null) {
7594                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7595                    }
7596                    runList.add(currApp);
7597                }
7598            }
7599        }
7600        return runList;
7601    }
7602
7603    public List<ApplicationInfo> getRunningExternalApplications() {
7604        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7605        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7606        if (runningApps != null && runningApps.size() > 0) {
7607            Set<String> extList = new HashSet<String>();
7608            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7609                if (app.pkgList != null) {
7610                    for (String pkg : app.pkgList) {
7611                        extList.add(pkg);
7612                    }
7613                }
7614            }
7615            IPackageManager pm = AppGlobals.getPackageManager();
7616            for (String pkg : extList) {
7617                try {
7618                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7619                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7620                        retList.add(info);
7621                    }
7622                } catch (RemoteException e) {
7623                }
7624            }
7625        }
7626        return retList;
7627    }
7628
7629    @Override
7630    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
7631        if (checkCallingPermission(android.Manifest.permission.DUMP)
7632                != PackageManager.PERMISSION_GRANTED) {
7633            pw.println("Permission Denial: can't dump ActivityManager from from pid="
7634                    + Binder.getCallingPid()
7635                    + ", uid=" + Binder.getCallingUid()
7636                    + " without permission "
7637                    + android.Manifest.permission.DUMP);
7638            return;
7639        }
7640
7641        boolean dumpAll = false;
7642        boolean dumpClient = false;
7643
7644        int opti = 0;
7645        while (opti < args.length) {
7646            String opt = args[opti];
7647            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7648                break;
7649            }
7650            opti++;
7651            if ("-a".equals(opt)) {
7652                dumpAll = true;
7653            } else if ("-c".equals(opt)) {
7654                dumpClient = true;
7655            } else if ("-h".equals(opt)) {
7656                pw.println("Activity manager dump options:");
7657                pw.println("  [-a] [-c] [-h] [cmd] ...");
7658                pw.println("  cmd may be one of:");
7659                pw.println("    a[ctivities]: activity stack state");
7660                pw.println("    b[roadcasts]: broadcast state");
7661                pw.println("    i[ntents]: pending intent state");
7662                pw.println("    p[rocesses]: process state");
7663                pw.println("    o[om]: out of memory management");
7664                pw.println("    prov[iders]: content provider state");
7665                pw.println("    s[ervices]: service state");
7666                pw.println("    service [COMP_SPEC]: service client-side state");
7667                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
7668                pw.println("  COMP_SPEC may also be a component name (com.foo/.myApp),");
7669                pw.println("    a partial substring in a component name, an");
7670                pw.println("    ActivityRecord hex object identifier, or");
7671                pw.println("    \"all\" for all objects");
7672                pw.println("  -a: include all available server state.");
7673                pw.println("  -c: include client state.");
7674                return;
7675            } else {
7676                pw.println("Unknown argument: " + opt + "; use -h for help");
7677            }
7678        }
7679
7680        // Is the caller requesting to dump a particular piece of data?
7681        if (opti < args.length) {
7682            String cmd = args[opti];
7683            opti++;
7684            if ("activities".equals(cmd) || "a".equals(cmd)) {
7685                synchronized (this) {
7686                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
7687                }
7688                return;
7689            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7690                synchronized (this) {
7691                    dumpBroadcastsLocked(fd, pw, args, opti, true);
7692                }
7693                return;
7694            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7695                synchronized (this) {
7696                    dumpPendingIntentsLocked(fd, pw, args, opti, true);
7697                }
7698                return;
7699            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7700                synchronized (this) {
7701                    dumpProcessesLocked(fd, pw, args, opti, true);
7702                }
7703                return;
7704            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7705                synchronized (this) {
7706                    dumpOomLocked(fd, pw, args, opti, true);
7707                }
7708                return;
7709            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7710                synchronized (this) {
7711                    dumpProvidersLocked(fd, pw, args, opti, true);
7712                }
7713                return;
7714            } else if ("service".equals(cmd)) {
7715                String[] newArgs;
7716                String name;
7717                if (opti >= args.length) {
7718                    name = null;
7719                    newArgs = EMPTY_STRING_ARRAY;
7720                } else {
7721                    name = args[opti];
7722                    opti++;
7723                    newArgs = new String[args.length - opti];
7724                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7725                }
7726                if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7727                    pw.println("No services match: " + name);
7728                    pw.println("Use -h for help.");
7729                }
7730                return;
7731            } else if ("services".equals(cmd) || "s".equals(cmd)) {
7732                synchronized (this) {
7733                    dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
7734                }
7735                return;
7736            } else {
7737                // Dumping a single activity?
7738                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7739                    pw.println("Bad activity command, or no activities match: " + cmd);
7740                    pw.println("Use -h for help.");
7741                }
7742                return;
7743            }
7744        }
7745
7746        // No piece of data specified, dump everything.
7747        synchronized (this) {
7748            boolean needSep;
7749            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
7750            if (needSep) {
7751                pw.println(" ");
7752            }
7753            if (dumpAll) {
7754                pw.println("-------------------------------------------------------------------------------");
7755            }
7756            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7757            if (needSep) {
7758                pw.println(" ");
7759            }
7760            if (dumpAll) {
7761                pw.println("-------------------------------------------------------------------------------");
7762            }
7763            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
7764            if (needSep) {
7765                pw.println(" ");
7766            }
7767            if (dumpAll) {
7768                pw.println("-------------------------------------------------------------------------------");
7769            }
7770            needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
7771            if (needSep) {
7772                pw.println(" ");
7773            }
7774            if (dumpAll) {
7775                pw.println("-------------------------------------------------------------------------------");
7776            }
7777            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
7778            if (needSep) {
7779                pw.println(" ");
7780            }
7781            if (dumpAll) {
7782                pw.println("-------------------------------------------------------------------------------");
7783            }
7784            dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7785        }
7786    }
7787
7788    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7789            int opti, boolean dumpAll, boolean dumpClient) {
7790        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7791        pw.println("  Main stack:");
7792        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient);
7793        pw.println(" ");
7794        pw.println("  Running activities (most recent first):");
7795        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false);
7796        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
7797            pw.println(" ");
7798            pw.println("  Activities waiting for another to become visible:");
7799            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
7800                    !dumpAll, false);
7801        }
7802        if (mMainStack.mStoppingActivities.size() > 0) {
7803            pw.println(" ");
7804            pw.println("  Activities waiting to stop:");
7805            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
7806                    !dumpAll, false);
7807        }
7808        if (mMainStack.mGoingToSleepActivities.size() > 0) {
7809            pw.println(" ");
7810            pw.println("  Activities waiting to sleep:");
7811            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
7812                    !dumpAll, false);
7813        }
7814        if (mMainStack.mFinishingActivities.size() > 0) {
7815            pw.println(" ");
7816            pw.println("  Activities waiting to finish:");
7817            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
7818                    !dumpAll, false);
7819        }
7820
7821        pw.println(" ");
7822        if (mMainStack.mPausingActivity != null) {
7823            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
7824        }
7825        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
7826        pw.println("  mFocusedActivity: " + mFocusedActivity);
7827        if (dumpAll) {
7828            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7829            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
7830        }
7831
7832        if (mRecentTasks.size() > 0) {
7833            pw.println();
7834            pw.println("  Recent tasks:");
7835
7836            final int N = mRecentTasks.size();
7837            for (int i=0; i<N; i++) {
7838                TaskRecord tr = mRecentTasks.get(i);
7839                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
7840                        pw.println(tr);
7841                if (dumpAll) {
7842                    mRecentTasks.get(i).dump(pw, "    ");
7843                }
7844            }
7845        }
7846
7847        if (dumpAll) {
7848            pw.println(" ");
7849            pw.println("  mCurTask: " + mCurTask);
7850        }
7851
7852        return true;
7853    }
7854
7855    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7856            int opti, boolean dumpAll) {
7857        boolean needSep = false;
7858        int numPers = 0;
7859
7860        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7861
7862        if (dumpAll) {
7863            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7864                final int NA = procs.size();
7865                for (int ia=0; ia<NA; ia++) {
7866                    if (!needSep) {
7867                        pw.println("  All known processes:");
7868                        needSep = true;
7869                    }
7870                    ProcessRecord r = procs.valueAt(ia);
7871                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
7872                        pw.print(" UID "); pw.print(procs.keyAt(ia));
7873                        pw.print(" "); pw.println(r);
7874                    r.dump(pw, "    ");
7875                    if (r.persistent) {
7876                        numPers++;
7877                    }
7878                }
7879            }
7880        }
7881
7882        if (mLruProcesses.size() > 0) {
7883            if (needSep) pw.println(" ");
7884            needSep = true;
7885            pw.println("  Process LRU list (most recent first):");
7886            dumpProcessOomList(pw, this, mLruProcesses, "    ",
7887                    "Proc", "PERS", false);
7888            needSep = true;
7889        }
7890
7891        if (dumpAll) {
7892            synchronized (mPidsSelfLocked) {
7893                if (mPidsSelfLocked.size() > 0) {
7894                    if (needSep) pw.println(" ");
7895                    needSep = true;
7896                    pw.println("  PID mappings:");
7897                    for (int i=0; i<mPidsSelfLocked.size(); i++) {
7898                        pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7899                            pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7900                    }
7901                }
7902            }
7903        }
7904
7905        if (mForegroundProcesses.size() > 0) {
7906            if (needSep) pw.println(" ");
7907            needSep = true;
7908            pw.println("  Foreground Processes:");
7909            for (int i=0; i<mForegroundProcesses.size(); i++) {
7910                pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
7911                        pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
7912            }
7913        }
7914
7915        if (mPersistentStartingProcesses.size() > 0) {
7916            if (needSep) pw.println(" ");
7917            needSep = true;
7918            pw.println("  Persisent processes that are starting:");
7919            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
7920                    "Starting Norm", "Restarting PERS");
7921        }
7922
7923        if (mStartingProcesses.size() > 0) {
7924            if (needSep) pw.println(" ");
7925            needSep = true;
7926            pw.println("  Processes that are starting:");
7927            dumpProcessList(pw, this, mStartingProcesses, "    ",
7928                    "Starting Norm", "Starting PERS");
7929        }
7930
7931        if (mRemovedProcesses.size() > 0) {
7932            if (needSep) pw.println(" ");
7933            needSep = true;
7934            pw.println("  Processes that are being removed:");
7935            dumpProcessList(pw, this, mRemovedProcesses, "    ",
7936                    "Removed Norm", "Removed PERS");
7937        }
7938
7939        if (mProcessesOnHold.size() > 0) {
7940            if (needSep) pw.println(" ");
7941            needSep = true;
7942            pw.println("  Processes that are on old until the system is ready:");
7943            dumpProcessList(pw, this, mProcessesOnHold, "    ",
7944                    "OnHold Norm", "OnHold PERS");
7945        }
7946
7947        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
7948
7949        if (mProcessCrashTimes.getMap().size() > 0) {
7950            if (needSep) pw.println(" ");
7951            needSep = true;
7952            pw.println("  Time since processes crashed:");
7953            long now = SystemClock.uptimeMillis();
7954            for (Map.Entry<String, SparseArray<Long>> procs
7955                    : mProcessCrashTimes.getMap().entrySet()) {
7956                SparseArray<Long> uids = procs.getValue();
7957                final int N = uids.size();
7958                for (int i=0; i<N; i++) {
7959                    pw.print("    Process "); pw.print(procs.getKey());
7960                            pw.print(" uid "); pw.print(uids.keyAt(i));
7961                            pw.print(": last crashed ");
7962                            pw.print((now-uids.valueAt(i)));
7963                            pw.println(" ms ago");
7964                }
7965            }
7966        }
7967
7968        if (mBadProcesses.getMap().size() > 0) {
7969            if (needSep) pw.println(" ");
7970            needSep = true;
7971            pw.println("  Bad processes:");
7972            for (Map.Entry<String, SparseArray<Long>> procs
7973                    : mBadProcesses.getMap().entrySet()) {
7974                SparseArray<Long> uids = procs.getValue();
7975                final int N = uids.size();
7976                for (int i=0; i<N; i++) {
7977                    pw.print("    Bad process "); pw.print(procs.getKey());
7978                            pw.print(" uid "); pw.print(uids.keyAt(i));
7979                            pw.print(": crashed at time ");
7980                            pw.println(uids.valueAt(i));
7981                }
7982            }
7983        }
7984
7985        pw.println();
7986        pw.println("  mHomeProcess: " + mHomeProcess);
7987        if (mHeavyWeightProcess != null) {
7988            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
7989        }
7990        pw.println("  mConfiguration: " + mConfiguration);
7991        if (dumpAll) {
7992            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
7993            if (mCompatModePackages.getPackages().size() > 0) {
7994                pw.println("  mScreenCompatPackages:");
7995                for (Map.Entry<String, Integer> entry
7996                        : mCompatModePackages.getPackages().entrySet()) {
7997                    String pkg = entry.getKey();
7998                    int mode = entry.getValue();
7999                    pw.print("    "); pw.print(pkg); pw.print(": ");
8000                            pw.print(mode); pw.println();
8001                }
8002            }
8003        }
8004        pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8005        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8006                || mOrigWaitForDebugger) {
8007            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8008                    + " mDebugTransient=" + mDebugTransient
8009                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8010        }
8011        if (mAlwaysFinishActivities || mController != null) {
8012            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
8013                    + " mController=" + mController);
8014        }
8015        if (dumpAll) {
8016            pw.println("  Total persistent processes: " + numPers);
8017            pw.println("  mStartRunning=" + mStartRunning
8018                    + " mProcessesReady=" + mProcessesReady
8019                    + " mSystemReady=" + mSystemReady);
8020            pw.println("  mBooting=" + mBooting
8021                    + " mBooted=" + mBooted
8022                    + " mFactoryTest=" + mFactoryTest);
8023            pw.print("  mLastPowerCheckRealtime=");
8024                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8025                    pw.println("");
8026            pw.print("  mLastPowerCheckUptime=");
8027                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8028                    pw.println("");
8029            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
8030            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
8031            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
8032        }
8033
8034        return true;
8035    }
8036
8037    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8038            int opti, boolean needSep, boolean dumpAll) {
8039        if (mProcessesToGc.size() > 0) {
8040            if (needSep) pw.println(" ");
8041            needSep = true;
8042            pw.println("  Processes that are waiting to GC:");
8043            long now = SystemClock.uptimeMillis();
8044            for (int i=0; i<mProcessesToGc.size(); i++) {
8045                ProcessRecord proc = mProcessesToGc.get(i);
8046                pw.print("    Process "); pw.println(proc);
8047                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
8048                        pw.print(", last gced=");
8049                        pw.print(now-proc.lastRequestedGc);
8050                        pw.print(" ms ago, last lowMem=");
8051                        pw.print(now-proc.lastLowMemory);
8052                        pw.println(" ms ago");
8053
8054            }
8055        }
8056        return needSep;
8057    }
8058
8059    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8060            int opti, boolean dumpAll) {
8061        boolean needSep = false;
8062
8063        if (mLruProcesses.size() > 0) {
8064            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
8065
8066            Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
8067                @Override
8068                public int compare(ProcessRecord object1, ProcessRecord object2) {
8069                    if (object1.setAdj != object2.setAdj) {
8070                        return object1.setAdj > object2.setAdj ? -1 : 1;
8071                    }
8072                    if (object1.setSchedGroup != object2.setSchedGroup) {
8073                        return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
8074                    }
8075                    if (object1.keeping != object2.keeping) {
8076                        return object1.keeping ? -1 : 1;
8077                    }
8078                    if (object1.pid != object2.pid) {
8079                        return object1.pid > object2.pid ? -1 : 1;
8080                    }
8081                    return 0;
8082                }
8083            };
8084
8085            Collections.sort(procs, comparator);
8086
8087            if (needSep) pw.println(" ");
8088            needSep = true;
8089            pw.println("  Process OOM control:");
8090            dumpProcessOomList(pw, this, procs, "    ",
8091                    "Proc", "PERS", true);
8092            needSep = true;
8093        }
8094
8095        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8096
8097        pw.println();
8098        pw.println("  mHomeProcess: " + mHomeProcess);
8099        if (mHeavyWeightProcess != null) {
8100            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
8101        }
8102
8103        return true;
8104    }
8105
8106    /**
8107     * There are three ways to call this:
8108     *  - no service specified: dump all the services
8109     *  - a flattened component name that matched an existing service was specified as the
8110     *    first arg: dump that one service
8111     *  - the first arg isn't the flattened component name of an existing service:
8112     *    dump all services whose component contains the first arg as a substring
8113     */
8114    protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8115            int opti, boolean dumpAll) {
8116        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
8117
8118        if ("all".equals(name)) {
8119            synchronized (this) {
8120                for (ServiceRecord r1 : mServices.values()) {
8121                    services.add(r1);
8122                }
8123            }
8124        } else {
8125            ComponentName componentName = name != null
8126                    ? ComponentName.unflattenFromString(name) : null;
8127            int objectId = 0;
8128            if (componentName == null) {
8129                // Not a '/' separated full component name; maybe an object ID?
8130                try {
8131                    objectId = Integer.parseInt(name, 16);
8132                    name = null;
8133                    componentName = null;
8134                } catch (RuntimeException e) {
8135                }
8136            }
8137
8138            synchronized (this) {
8139                for (ServiceRecord r1 : mServices.values()) {
8140                    if (componentName != null) {
8141                        if (r1.name.equals(componentName)) {
8142                            services.add(r1);
8143                        }
8144                    } else if (name != null) {
8145                        if (r1.name.flattenToString().contains(name)) {
8146                            services.add(r1);
8147                        }
8148                    } else if (System.identityHashCode(r1) == objectId) {
8149                        services.add(r1);
8150                    }
8151                }
8152            }
8153        }
8154
8155        if (services.size() <= 0) {
8156            return false;
8157        }
8158
8159        boolean needSep = false;
8160        for (int i=0; i<services.size(); i++) {
8161            if (needSep) {
8162                pw.println();
8163            }
8164            needSep = true;
8165            dumpService("", fd, pw, services.get(i), args, dumpAll);
8166        }
8167        return true;
8168    }
8169
8170    /**
8171     * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8172     * there is a thread associated with the service.
8173     */
8174    private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8175            final ServiceRecord r, String[] args, boolean dumpAll) {
8176        String innerPrefix = prefix + "  ";
8177        synchronized (this) {
8178            pw.print(prefix); pw.print("SERVICE ");
8179                    pw.print(r.shortName); pw.print(" ");
8180                    pw.print(Integer.toHexString(System.identityHashCode(r)));
8181                    pw.print(" pid=");
8182                    if (r.app != null) pw.println(r.app.pid);
8183                    else pw.println("(not running)");
8184            if (dumpAll) {
8185                r.dump(pw, innerPrefix);
8186            }
8187        }
8188        if (r.app != null && r.app.thread != null) {
8189            pw.print(prefix); pw.println("  Client:");
8190            pw.flush();
8191            try {
8192                TransferPipe tp = new TransferPipe();
8193                try {
8194                    r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8195                    tp.setBufferPrefix(prefix + "    ");
8196                    tp.go(fd);
8197                } finally {
8198                    tp.kill();
8199                }
8200            } catch (IOException e) {
8201                pw.println(prefix + "    Failure while dumping the service: " + e);
8202            } catch (RemoteException e) {
8203                pw.println(prefix + "    Got a RemoteException while dumping the service");
8204            }
8205        }
8206    }
8207
8208    /**
8209     * There are three things that cmd can be:
8210     *  - a flattened component name that matched an existing activity
8211     *  - the cmd arg isn't the flattened component name of an existing activity:
8212     *    dump all activity whose component contains the cmd as a substring
8213     *  - A hex number of the ActivityRecord object instance.
8214     */
8215    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8216            int opti, boolean dumpAll) {
8217        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
8218
8219        if ("all".equals(name)) {
8220            synchronized (this) {
8221                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8222                    activities.add(r1);
8223                }
8224            }
8225        } else {
8226            ComponentName componentName = ComponentName.unflattenFromString(name);
8227            int objectId = 0;
8228            if (componentName == null) {
8229                // Not a '/' separated full component name; maybe an object ID?
8230                try {
8231                    objectId = Integer.parseInt(name, 16);
8232                    name = null;
8233                    componentName = null;
8234                } catch (RuntimeException e) {
8235                }
8236            }
8237
8238            synchronized (this) {
8239                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8240                    if (componentName != null) {
8241                        if (r1.intent.getComponent().equals(componentName)) {
8242                            activities.add(r1);
8243                        }
8244                    } else if (name != null) {
8245                        if (r1.intent.getComponent().flattenToString().contains(name)) {
8246                            activities.add(r1);
8247                        }
8248                    } else if (System.identityHashCode(r1) == objectId) {
8249                        activities.add(r1);
8250                    }
8251                }
8252            }
8253        }
8254
8255        if (activities.size() <= 0) {
8256            return false;
8257        }
8258
8259        String[] newArgs = new String[args.length - opti];
8260        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8261
8262        TaskRecord lastTask = null;
8263        boolean needSep = false;
8264        for (int i=activities.size()-1; i>=0; i--) {
8265            ActivityRecord r = (ActivityRecord)activities.get(i);
8266            if (needSep) {
8267                pw.println();
8268            }
8269            needSep = true;
8270            synchronized (this) {
8271                if (lastTask != r.task) {
8272                    lastTask = r.task;
8273                    pw.print("TASK "); pw.print(lastTask.affinity);
8274                            pw.print(" id="); pw.println(lastTask.taskId);
8275                    if (dumpAll) {
8276                        lastTask.dump(pw, "  ");
8277                    }
8278                }
8279            }
8280            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
8281        }
8282        return true;
8283    }
8284
8285    /**
8286     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8287     * there is a thread associated with the activity.
8288     */
8289    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
8290            final ActivityRecord r, String[] args, boolean dumpAll) {
8291        String innerPrefix = prefix + "  ";
8292        synchronized (this) {
8293            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8294                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8295                    pw.print(" pid=");
8296                    if (r.app != null) pw.println(r.app.pid);
8297                    else pw.println("(not running)");
8298            if (dumpAll) {
8299                r.dump(pw, innerPrefix);
8300            }
8301        }
8302        if (r.app != null && r.app.thread != null) {
8303            // flush anything that is already in the PrintWriter since the thread is going
8304            // to write to the file descriptor directly
8305            pw.flush();
8306            try {
8307                TransferPipe tp = new TransferPipe();
8308                try {
8309                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8310                            innerPrefix, args);
8311                    tp.go(fd);
8312                } finally {
8313                    tp.kill();
8314                }
8315            } catch (IOException e) {
8316                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8317            } catch (RemoteException e) {
8318                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8319            }
8320        }
8321    }
8322
8323    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8324            int opti, boolean dumpAll) {
8325        boolean needSep = false;
8326
8327        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
8328        if (dumpAll) {
8329            if (mRegisteredReceivers.size() > 0) {
8330                pw.println("  Registered Receivers:");
8331                Iterator it = mRegisteredReceivers.values().iterator();
8332                while (it.hasNext()) {
8333                    ReceiverList r = (ReceiverList)it.next();
8334                    pw.print("  * "); pw.println(r);
8335                    r.dump(pw, "    ");
8336                }
8337            }
8338
8339            pw.println();
8340            pw.println("  Receiver Resolver Table:");
8341            mReceiverResolver.dump(pw, null, "    ", null, false);
8342            needSep = true;
8343        }
8344
8345        if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8346                || mPendingBroadcast != null) {
8347            if (mParallelBroadcasts.size() > 0) {
8348                pw.println();
8349                pw.println("  Active broadcasts:");
8350            }
8351            for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8352                pw.println("  Broadcast #" + i + ":");
8353                mParallelBroadcasts.get(i).dump(pw, "    ");
8354            }
8355            if (mOrderedBroadcasts.size() > 0) {
8356                pw.println();
8357                pw.println("  Active ordered broadcasts:");
8358            }
8359            for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8360                pw.println("  Serialized Broadcast #" + i + ":");
8361                mOrderedBroadcasts.get(i).dump(pw, "    ");
8362            }
8363            pw.println();
8364            pw.println("  Pending broadcast:");
8365            if (mPendingBroadcast != null) {
8366                mPendingBroadcast.dump(pw, "    ");
8367            } else {
8368                pw.println("    (null)");
8369            }
8370            needSep = true;
8371        }
8372
8373        if (needSep) {
8374            pw.println();
8375        }
8376        pw.println("  Historical broadcasts:");
8377        for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8378            BroadcastRecord r = mBroadcastHistory[i];
8379            if (r == null) {
8380                break;
8381            }
8382            if (dumpAll) {
8383                pw.print("  Historical Broadcast #"); pw.print(i); pw.println(":");
8384                r.dump(pw, "    ");
8385            } else {
8386                if (i >= 50) {
8387                    pw.println("  ...");
8388                    break;
8389                }
8390                pw.print("  #"); pw.print(i); pw.print(": "); pw.println(r);
8391            }
8392        }
8393        needSep = true;
8394
8395        if (mStickyBroadcasts != null) {
8396            pw.println();
8397            pw.println("  Sticky broadcasts:");
8398            StringBuilder sb = new StringBuilder(128);
8399            for (Map.Entry<String, ArrayList<Intent>> ent
8400                    : mStickyBroadcasts.entrySet()) {
8401                pw.print("  * Sticky action "); pw.print(ent.getKey());
8402                if (dumpAll) {
8403                    pw.println(":");
8404                    ArrayList<Intent> intents = ent.getValue();
8405                    final int N = intents.size();
8406                    for (int i=0; i<N; i++) {
8407                        sb.setLength(0);
8408                        sb.append("    Intent: ");
8409                        intents.get(i).toShortString(sb, true, false);
8410                        pw.println(sb.toString());
8411                        Bundle bundle = intents.get(i).getExtras();
8412                        if (bundle != null) {
8413                            pw.print("      ");
8414                            pw.println(bundle.toString());
8415                        }
8416                    }
8417                } else {
8418                    pw.println("");
8419                }
8420            }
8421            needSep = true;
8422        }
8423
8424        if (dumpAll) {
8425            pw.println();
8426            pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
8427            pw.println("  mHandler:");
8428            mHandler.dump(new PrintWriterPrinter(pw), "    ");
8429            needSep = true;
8430        }
8431
8432        return needSep;
8433    }
8434
8435    boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8436            int opti, boolean dumpAll, boolean dumpClient) {
8437        boolean needSep = false;
8438
8439        pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8440        if (mServices.size() > 0) {
8441            pw.println("  Active services:");
8442            long nowReal = SystemClock.elapsedRealtime();
8443            Iterator<ServiceRecord> it = mServices.values().iterator();
8444            needSep = false;
8445            while (it.hasNext()) {
8446                ServiceRecord r = it.next();
8447                if (needSep) {
8448                    pw.println();
8449                }
8450                pw.print("  * "); pw.println(r);
8451                if (dumpAll) {
8452                    r.dump(pw, "    ");
8453                    needSep = true;
8454                } else {
8455                    pw.print("    app="); pw.println(r.app);
8456                    pw.print("    created=");
8457                        TimeUtils.formatDuration(r.createTime, nowReal, pw);
8458                        pw.print(" started="); pw.print(r.startRequested);
8459                        pw.print(" connections="); pw.println(r.connections.size());
8460                }
8461                if (dumpClient && r.app != null && r.app.thread != null) {
8462                    pw.println("    Client:");
8463                    pw.flush();
8464                    try {
8465                        TransferPipe tp = new TransferPipe();
8466                        try {
8467                            r.app.thread.dumpService(
8468                                    tp.getWriteFd().getFileDescriptor(), r, args);
8469                            tp.setBufferPrefix("      ");
8470                            // Short timeout, since blocking here can
8471                            // deadlock with the application.
8472                            tp.go(fd, 2000);
8473                        } finally {
8474                            tp.kill();
8475                        }
8476                    } catch (IOException e) {
8477                        pw.println("      Failure while dumping the service: " + e);
8478                    } catch (RemoteException e) {
8479                        pw.println("      Got a RemoteException while dumping the service");
8480                    }
8481                    needSep = true;
8482                }
8483            }
8484            needSep = true;
8485        }
8486
8487        if (mPendingServices.size() > 0) {
8488            if (needSep) pw.println(" ");
8489            pw.println("  Pending services:");
8490            for (int i=0; i<mPendingServices.size(); i++) {
8491                ServiceRecord r = mPendingServices.get(i);
8492                pw.print("  * Pending "); pw.println(r);
8493                r.dump(pw, "    ");
8494            }
8495            needSep = true;
8496        }
8497
8498        if (mRestartingServices.size() > 0) {
8499            if (needSep) pw.println(" ");
8500            pw.println("  Restarting services:");
8501            for (int i=0; i<mRestartingServices.size(); i++) {
8502                ServiceRecord r = mRestartingServices.get(i);
8503                pw.print("  * Restarting "); pw.println(r);
8504                r.dump(pw, "    ");
8505            }
8506            needSep = true;
8507        }
8508
8509        if (mStoppingServices.size() > 0) {
8510            if (needSep) pw.println(" ");
8511            pw.println("  Stopping services:");
8512            for (int i=0; i<mStoppingServices.size(); i++) {
8513                ServiceRecord r = mStoppingServices.get(i);
8514                pw.print("  * Stopping "); pw.println(r);
8515                r.dump(pw, "    ");
8516            }
8517            needSep = true;
8518        }
8519
8520        if (dumpAll) {
8521            if (mServiceConnections.size() > 0) {
8522                if (needSep) pw.println(" ");
8523                pw.println("  Connection bindings to services:");
8524                Iterator<ArrayList<ConnectionRecord>> it
8525                        = mServiceConnections.values().iterator();
8526                while (it.hasNext()) {
8527                    ArrayList<ConnectionRecord> r = it.next();
8528                    for (int i=0; i<r.size(); i++) {
8529                        pw.print("  * "); pw.println(r.get(i));
8530                        r.get(i).dump(pw, "    ");
8531                    }
8532                }
8533                needSep = true;
8534            }
8535        }
8536
8537        return needSep;
8538    }
8539
8540    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8541            int opti, boolean dumpAll) {
8542        boolean needSep = false;
8543
8544        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8545        if (mProvidersByClass.size() > 0) {
8546            if (needSep) pw.println(" ");
8547            pw.println("  Published content providers (by class):");
8548            Iterator<Map.Entry<String, ContentProviderRecord>> it
8549                    = mProvidersByClass.entrySet().iterator();
8550            while (it.hasNext()) {
8551                Map.Entry<String, ContentProviderRecord> e = it.next();
8552                ContentProviderRecord r = e.getValue();
8553                if (dumpAll) {
8554                    pw.print("  * "); pw.println(r);
8555                    r.dump(pw, "    ");
8556                } else {
8557                    pw.print("  * "); pw.print(r.name.toShortString());
8558                    if (r.app != null) {
8559                        pw.println(":");
8560                        pw.print("      "); pw.println(r.app);
8561                    } else {
8562                        pw.println();
8563                    }
8564                }
8565            }
8566            needSep = true;
8567        }
8568
8569        if (dumpAll) {
8570            if (mProvidersByName.size() > 0) {
8571                pw.println(" ");
8572                pw.println("  Authority to provider mappings:");
8573                Iterator<Map.Entry<String, ContentProviderRecord>> it
8574                        = mProvidersByName.entrySet().iterator();
8575                while (it.hasNext()) {
8576                    Map.Entry<String, ContentProviderRecord> e = it.next();
8577                    ContentProviderRecord r = e.getValue();
8578                    pw.print("  "); pw.print(e.getKey()); pw.print(": ");
8579                            pw.println(r);
8580                }
8581                needSep = true;
8582            }
8583        }
8584
8585        if (mLaunchingProviders.size() > 0) {
8586            if (needSep) pw.println(" ");
8587            pw.println("  Launching content providers:");
8588            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8589                pw.print("  Launching #"); pw.print(i); pw.print(": ");
8590                        pw.println(mLaunchingProviders.get(i));
8591            }
8592            needSep = true;
8593        }
8594
8595        if (mGrantedUriPermissions.size() > 0) {
8596            pw.println();
8597            pw.println("Granted Uri Permissions:");
8598            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8599                int uid = mGrantedUriPermissions.keyAt(i);
8600                HashMap<Uri, UriPermission> perms
8601                        = mGrantedUriPermissions.valueAt(i);
8602                pw.print("  * UID "); pw.print(uid);
8603                        pw.println(" holds:");
8604                for (UriPermission perm : perms.values()) {
8605                    pw.print("    "); pw.println(perm);
8606                    if (dumpAll) {
8607                        perm.dump(pw, "      ");
8608                    }
8609                }
8610            }
8611            needSep = true;
8612        }
8613
8614        return needSep;
8615    }
8616
8617    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8618            int opti, boolean dumpAll) {
8619        boolean needSep = false;
8620
8621        if (this.mIntentSenderRecords.size() > 0) {
8622            pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8623            Iterator<WeakReference<PendingIntentRecord>> it
8624                    = mIntentSenderRecords.values().iterator();
8625            while (it.hasNext()) {
8626                WeakReference<PendingIntentRecord> ref = it.next();
8627                PendingIntentRecord rec = ref != null ? ref.get(): null;
8628                needSep = true;
8629                if (rec != null) {
8630                    pw.print("  * "); pw.println(rec);
8631                    if (dumpAll) {
8632                        rec.dump(pw, "    ");
8633                    }
8634                } else {
8635                    pw.print("  * "); pw.println(ref);
8636                }
8637            }
8638        }
8639
8640        return needSep;
8641    }
8642
8643    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8644            String prefix, String label, boolean complete, boolean brief, boolean client) {
8645        TaskRecord lastTask = null;
8646        boolean needNL = false;
8647        final String innerPrefix = prefix + "      ";
8648        final String[] args = new String[0];
8649        for (int i=list.size()-1; i>=0; i--) {
8650            final ActivityRecord r = (ActivityRecord)list.get(i);
8651            final boolean full = !brief && (complete || !r.isInHistory());
8652            if (needNL) {
8653                pw.println(" ");
8654                needNL = false;
8655            }
8656            if (lastTask != r.task) {
8657                lastTask = r.task;
8658                pw.print(prefix);
8659                pw.print(full ? "* " : "  ");
8660                pw.println(lastTask);
8661                if (full) {
8662                    lastTask.dump(pw, prefix + "  ");
8663                } else if (complete) {
8664                    // Complete + brief == give a summary.  Isn't that obvious?!?
8665                    if (lastTask.intent != null) {
8666                        pw.print(prefix); pw.print("  "); pw.println(lastTask.intent);
8667                    }
8668                }
8669            }
8670            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
8671            pw.print(" #"); pw.print(i); pw.print(": ");
8672            pw.println(r);
8673            if (full) {
8674                r.dump(pw, innerPrefix);
8675            } else if (complete) {
8676                // Complete + brief == give a summary.  Isn't that obvious?!?
8677                pw.print(innerPrefix); pw.println(r.intent);
8678                if (r.app != null) {
8679                    pw.print(innerPrefix); pw.println(r.app);
8680                }
8681            }
8682            if (client && r.app != null && r.app.thread != null) {
8683                // flush anything that is already in the PrintWriter since the thread is going
8684                // to write to the file descriptor directly
8685                pw.flush();
8686                try {
8687                    TransferPipe tp = new TransferPipe();
8688                    try {
8689                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8690                                innerPrefix, args);
8691                        // Short timeout, since blocking here can
8692                        // deadlock with the application.
8693                        tp.go(fd, 2000);
8694                    } finally {
8695                        tp.kill();
8696                    }
8697                } catch (IOException e) {
8698                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8699                } catch (RemoteException e) {
8700                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8701                }
8702                needNL = true;
8703            }
8704        }
8705    }
8706
8707    private static String buildOomTag(String prefix, String space, int val, int base) {
8708        if (val == base) {
8709            if (space == null) return prefix;
8710            return prefix + "  ";
8711        }
8712        return prefix + "+" + Integer.toString(val-base);
8713    }
8714
8715    private static final int dumpProcessList(PrintWriter pw,
8716            ActivityManagerService service, List list,
8717            String prefix, String normalLabel, String persistentLabel) {
8718        int numPers = 0;
8719        final int N = list.size()-1;
8720        for (int i=N; i>=0; i--) {
8721            ProcessRecord r = (ProcessRecord)list.get(i);
8722            pw.println(String.format("%s%s #%2d: %s",
8723                    prefix, (r.persistent ? persistentLabel : normalLabel),
8724                    i, r.toString()));
8725            if (r.persistent) {
8726                numPers++;
8727            }
8728        }
8729        return numPers;
8730    }
8731
8732    private static final void dumpProcessOomList(PrintWriter pw,
8733            ActivityManagerService service, List<ProcessRecord> list,
8734            String prefix, String normalLabel, String persistentLabel,
8735            boolean inclDetails) {
8736
8737        final long curRealtime = SystemClock.elapsedRealtime();
8738        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8739        final long curUptime = SystemClock.uptimeMillis();
8740        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8741
8742        final int N = list.size()-1;
8743        for (int i=N; i>=0; i--) {
8744            ProcessRecord r = list.get(i);
8745            String oomAdj;
8746            if (r.setAdj >= EMPTY_APP_ADJ) {
8747                oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
8748            } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
8749                oomAdj = buildOomTag("bak", "  ", r.setAdj, HIDDEN_APP_MIN_ADJ);
8750            } else if (r.setAdj >= HOME_APP_ADJ) {
8751                oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
8752            } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
8753                oomAdj = buildOomTag("svc", "  ", r.setAdj, SECONDARY_SERVER_ADJ);
8754            } else if (r.setAdj >= BACKUP_APP_ADJ) {
8755                oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
8756            } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
8757                oomAdj = buildOomTag("hvy  ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
8758            } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
8759                oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
8760            } else if (r.setAdj >= VISIBLE_APP_ADJ) {
8761                oomAdj = buildOomTag("vis  ", null, r.setAdj, VISIBLE_APP_ADJ);
8762            } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
8763                oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
8764            } else if (r.setAdj >= CORE_SERVER_ADJ) {
8765                oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
8766            } else if (r.setAdj >= SYSTEM_ADJ) {
8767                oomAdj = buildOomTag("sys  ", null, r.setAdj, SYSTEM_ADJ);
8768            } else {
8769                oomAdj = Integer.toString(r.setAdj);
8770            }
8771            String schedGroup;
8772            switch (r.setSchedGroup) {
8773                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8774                    schedGroup = "B";
8775                    break;
8776                case Process.THREAD_GROUP_DEFAULT:
8777                    schedGroup = "F";
8778                    break;
8779                default:
8780                    schedGroup = Integer.toString(r.setSchedGroup);
8781                    break;
8782            }
8783            String foreground;
8784            if (r.foregroundActivities) {
8785                foreground = "A";
8786            } else if (r.foregroundServices) {
8787                foreground = "S";
8788            } else {
8789                foreground = " ";
8790            }
8791            pw.println(String.format("%s%s #%2d: adj=%s/%s%s %s (%s)",
8792                    prefix, (r.persistent ? persistentLabel : normalLabel),
8793                    N-i, oomAdj, schedGroup, foreground, r.toShortString(), r.adjType));
8794            if (r.adjSource != null || r.adjTarget != null) {
8795                pw.print(prefix);
8796                pw.print("    ");
8797                if (r.adjTarget instanceof ComponentName) {
8798                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8799                } else if (r.adjTarget != null) {
8800                    pw.print(r.adjTarget.toString());
8801                } else {
8802                    pw.print("{null}");
8803                }
8804                pw.print("<=");
8805                if (r.adjSource instanceof ProcessRecord) {
8806                    pw.print("Proc{");
8807                    pw.print(((ProcessRecord)r.adjSource).toShortString());
8808                    pw.println("}");
8809                } else if (r.adjSource != null) {
8810                    pw.println(r.adjSource.toString());
8811                } else {
8812                    pw.println("{null}");
8813                }
8814            }
8815            if (inclDetails) {
8816                pw.print(prefix);
8817                pw.print("    ");
8818                pw.print("oom: max="); pw.print(r.maxAdj);
8819                pw.print(" hidden="); pw.print(r.hiddenAdj);
8820                pw.print(" curRaw="); pw.print(r.curRawAdj);
8821                pw.print(" setRaw="); pw.print(r.setRawAdj);
8822                pw.print(" cur="); pw.print(r.curAdj);
8823                pw.print(" set="); pw.println(r.setAdj);
8824                pw.print(prefix);
8825                pw.print("    ");
8826                pw.print("keeping="); pw.print(r.keeping);
8827                pw.print(" hidden="); pw.print(r.hidden);
8828                pw.print(" empty="); pw.println(r.empty);
8829
8830                if (!r.keeping) {
8831                    if (r.lastWakeTime != 0) {
8832                        long wtime;
8833                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8834                        synchronized (stats) {
8835                            wtime = stats.getProcessWakeTime(r.info.uid,
8836                                    r.pid, curRealtime);
8837                        }
8838                        long timeUsed = wtime - r.lastWakeTime;
8839                        pw.print(prefix);
8840                        pw.print("    ");
8841                        pw.print("keep awake over ");
8842                        TimeUtils.formatDuration(realtimeSince, pw);
8843                        pw.print(" used ");
8844                        TimeUtils.formatDuration(timeUsed, pw);
8845                        pw.print(" (");
8846                        pw.print((timeUsed*100)/realtimeSince);
8847                        pw.println("%)");
8848                    }
8849                    if (r.lastCpuTime != 0) {
8850                        long timeUsed = r.curCpuTime - r.lastCpuTime;
8851                        pw.print(prefix);
8852                        pw.print("    ");
8853                        pw.print("run cpu over ");
8854                        TimeUtils.formatDuration(uptimeSince, pw);
8855                        pw.print(" used ");
8856                        TimeUtils.formatDuration(timeUsed, pw);
8857                        pw.print(" (");
8858                        pw.print((timeUsed*100)/uptimeSince);
8859                        pw.println("%)");
8860                    }
8861                }
8862            }
8863        }
8864    }
8865
8866    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, String[] args) {
8867        ArrayList<ProcessRecord> procs;
8868        synchronized (this) {
8869            if (args != null && args.length > 0
8870                    && args[0].charAt(0) != '-') {
8871                procs = new ArrayList<ProcessRecord>();
8872                int pid = -1;
8873                try {
8874                    pid = Integer.parseInt(args[0]);
8875                } catch (NumberFormatException e) {
8876
8877                }
8878                for (int i=mLruProcesses.size()-1; i>=0; i--) {
8879                    ProcessRecord proc = mLruProcesses.get(i);
8880                    if (proc.pid == pid) {
8881                        procs.add(proc);
8882                    } else if (proc.processName.equals(args[0])) {
8883                        procs.add(proc);
8884                    }
8885                }
8886                if (procs.size() <= 0) {
8887                    pw.println("No process found for: " + args[0]);
8888                    return null;
8889                }
8890            } else {
8891                procs = new ArrayList<ProcessRecord>(mLruProcesses);
8892            }
8893        }
8894        return procs;
8895    }
8896
8897    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
8898            PrintWriter pw, String[] args) {
8899        ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
8900        if (procs == null) {
8901            return;
8902        }
8903
8904        long uptime = SystemClock.uptimeMillis();
8905        long realtime = SystemClock.elapsedRealtime();
8906        pw.println("Applications Graphics Acceleration Info:");
8907        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8908
8909        String callArgs[] = {"graphics"};
8910        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8911            ProcessRecord r = procs.get(i);
8912            if (r.thread != null) {
8913                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
8914                pw.flush();
8915                try {
8916                    TransferPipe.goDump(r.thread.asBinder(), fd, callArgs);
8917                } catch (IOException e) {
8918                    pw.println("Failure: " + e);
8919                    pw.flush();
8920                } catch (RemoteException e) {
8921                    pw.println("Got RemoteException!");
8922                    pw.flush();
8923                }
8924            }
8925        }
8926    }
8927
8928    final void dumpApplicationMemoryUsage(FileDescriptor fd,
8929            PrintWriter pw, String prefix, String[] args) {
8930        ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
8931        if (procs == null) {
8932            return;
8933        }
8934
8935        final boolean isCheckinRequest = scanArgs(args, "--checkin");
8936        long uptime = SystemClock.uptimeMillis();
8937        long realtime = SystemClock.elapsedRealtime();
8938
8939        if (isCheckinRequest) {
8940            // short checkin version
8941            pw.println(uptime + "," + realtime);
8942            pw.flush();
8943        } else {
8944            pw.println("Applications Memory Usage (kB):");
8945            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8946        }
8947        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8948            ProcessRecord r = procs.get(i);
8949            if (r.thread != null) {
8950                if (!isCheckinRequest) {
8951                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
8952                    pw.flush();
8953                }
8954                try {
8955                    TransferPipe.goDump(r.thread.asBinder(), fd, args);
8956                } catch (IOException e) {
8957                    pw.println("Failure: " + e);
8958                    pw.flush();
8959                } catch (RemoteException e) {
8960                    if (!isCheckinRequest) {
8961                        pw.println("Got RemoteException!");
8962                        pw.flush();
8963                    }
8964                }
8965            }
8966        }
8967    }
8968
8969    /**
8970     * Searches array of arguments for the specified string
8971     * @param args array of argument strings
8972     * @param value value to search for
8973     * @return true if the value is contained in the array
8974     */
8975    private static boolean scanArgs(String[] args, String value) {
8976        if (args != null) {
8977            for (String arg : args) {
8978                if (value.equals(arg)) {
8979                    return true;
8980                }
8981            }
8982        }
8983        return false;
8984    }
8985
8986    private final void killServicesLocked(ProcessRecord app,
8987            boolean allowRestart) {
8988        // Report disconnected services.
8989        if (false) {
8990            // XXX we are letting the client link to the service for
8991            // death notifications.
8992            if (app.services.size() > 0) {
8993                Iterator<ServiceRecord> it = app.services.iterator();
8994                while (it.hasNext()) {
8995                    ServiceRecord r = it.next();
8996                    if (r.connections.size() > 0) {
8997                        Iterator<ArrayList<ConnectionRecord>> jt
8998                                = r.connections.values().iterator();
8999                        while (jt.hasNext()) {
9000                            ArrayList<ConnectionRecord> cl = jt.next();
9001                            for (int i=0; i<cl.size(); i++) {
9002                                ConnectionRecord c = cl.get(i);
9003                                if (c.binding.client != app) {
9004                                    try {
9005                                        //c.conn.connected(r.className, null);
9006                                    } catch (Exception e) {
9007                                        // todo: this should be asynchronous!
9008                                        Slog.w(TAG, "Exception thrown disconnected servce "
9009                                              + r.shortName
9010                                              + " from app " + app.processName, e);
9011                                    }
9012                                }
9013                            }
9014                        }
9015                    }
9016                }
9017            }
9018        }
9019
9020        // Clean up any connections this application has to other services.
9021        if (app.connections.size() > 0) {
9022            Iterator<ConnectionRecord> it = app.connections.iterator();
9023            while (it.hasNext()) {
9024                ConnectionRecord r = it.next();
9025                removeConnectionLocked(r, app, null);
9026            }
9027        }
9028        app.connections.clear();
9029
9030        if (app.services.size() != 0) {
9031            // Any services running in the application need to be placed
9032            // back in the pending list.
9033            Iterator<ServiceRecord> it = app.services.iterator();
9034            while (it.hasNext()) {
9035                ServiceRecord sr = it.next();
9036                synchronized (sr.stats.getBatteryStats()) {
9037                    sr.stats.stopLaunchedLocked();
9038                }
9039                sr.app = null;
9040                sr.executeNesting = 0;
9041                if (mStoppingServices.remove(sr)) {
9042                    if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9043                }
9044
9045                boolean hasClients = sr.bindings.size() > 0;
9046                if (hasClients) {
9047                    Iterator<IntentBindRecord> bindings
9048                            = sr.bindings.values().iterator();
9049                    while (bindings.hasNext()) {
9050                        IntentBindRecord b = bindings.next();
9051                        if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
9052                                + ": shouldUnbind=" + b.hasBound);
9053                        b.binder = null;
9054                        b.requested = b.received = b.hasBound = false;
9055                    }
9056                }
9057
9058                if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9059                        &ApplicationInfo.FLAG_PERSISTENT) == 0) {
9060                    Slog.w(TAG, "Service crashed " + sr.crashCount
9061                            + " times, stopping: " + sr);
9062                    EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
9063                            sr.crashCount, sr.shortName, app.pid);
9064                    bringDownServiceLocked(sr, true);
9065                } else if (!allowRestart) {
9066                    bringDownServiceLocked(sr, true);
9067                } else {
9068                    boolean canceled = scheduleServiceRestartLocked(sr, true);
9069
9070                    // Should the service remain running?  Note that in the
9071                    // extreme case of so many attempts to deliver a command
9072                    // that it failed, that we also will stop it here.
9073                    if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9074                        if (sr.pendingStarts.size() == 0) {
9075                            sr.startRequested = false;
9076                            if (!hasClients) {
9077                                // Whoops, no reason to restart!
9078                                bringDownServiceLocked(sr, true);
9079                            }
9080                        }
9081                    }
9082                }
9083            }
9084
9085            if (!allowRestart) {
9086                app.services.clear();
9087            }
9088        }
9089
9090        // Make sure we have no more records on the stopping list.
9091        int i = mStoppingServices.size();
9092        while (i > 0) {
9093            i--;
9094            ServiceRecord sr = mStoppingServices.get(i);
9095            if (sr.app == app) {
9096                mStoppingServices.remove(i);
9097                if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9098            }
9099        }
9100
9101        app.executingServices.clear();
9102    }
9103
9104    private final void removeDyingProviderLocked(ProcessRecord proc,
9105            ContentProviderRecord cpr) {
9106        synchronized (cpr) {
9107            cpr.launchingApp = null;
9108            cpr.notifyAll();
9109        }
9110
9111        mProvidersByClass.remove(cpr.info.name);
9112        String names[] = cpr.info.authority.split(";");
9113        for (int j = 0; j < names.length; j++) {
9114            mProvidersByName.remove(names[j]);
9115        }
9116
9117        Iterator<ProcessRecord> cit = cpr.clients.iterator();
9118        while (cit.hasNext()) {
9119            ProcessRecord capp = cit.next();
9120            if (!capp.persistent && capp.thread != null
9121                    && capp.pid != 0
9122                    && capp.pid != MY_PID) {
9123                Slog.i(TAG, "Kill " + capp.processName
9124                        + " (pid " + capp.pid + "): provider " + cpr.info.name
9125                        + " in dying process " + proc.processName);
9126                EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
9127                        capp.processName, capp.setAdj, "dying provider " + proc.processName);
9128                Process.killProcessQuiet(capp.pid);
9129            }
9130        }
9131
9132        mLaunchingProviders.remove(cpr);
9133    }
9134
9135    /**
9136     * Main code for cleaning up a process when it has gone away.  This is
9137     * called both as a result of the process dying, or directly when stopping
9138     * a process when running in single process mode.
9139     */
9140    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
9141            boolean restarting, int index) {
9142        if (index >= 0) {
9143            mLruProcesses.remove(index);
9144        }
9145
9146        mProcessesToGc.remove(app);
9147
9148        // Dismiss any open dialogs.
9149        if (app.crashDialog != null) {
9150            app.crashDialog.dismiss();
9151            app.crashDialog = null;
9152        }
9153        if (app.anrDialog != null) {
9154            app.anrDialog.dismiss();
9155            app.anrDialog = null;
9156        }
9157        if (app.waitDialog != null) {
9158            app.waitDialog.dismiss();
9159            app.waitDialog = null;
9160        }
9161
9162        app.crashing = false;
9163        app.notResponding = false;
9164
9165        app.resetPackageList();
9166        app.thread = null;
9167        app.forcingToForeground = null;
9168        app.foregroundServices = false;
9169        app.foregroundActivities = false;
9170
9171        killServicesLocked(app, true);
9172
9173        boolean restart = false;
9174
9175        int NL = mLaunchingProviders.size();
9176
9177        // Remove published content providers.
9178        if (!app.pubProviders.isEmpty()) {
9179            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
9180            while (it.hasNext()) {
9181                ContentProviderRecord cpr = it.next();
9182                cpr.provider = null;
9183                cpr.app = null;
9184
9185                // See if someone is waiting for this provider...  in which
9186                // case we don't remove it, but just let it restart.
9187                int i = 0;
9188                if (!app.bad) {
9189                    for (; i<NL; i++) {
9190                        if (mLaunchingProviders.get(i) == cpr) {
9191                            restart = true;
9192                            break;
9193                        }
9194                    }
9195                } else {
9196                    i = NL;
9197                }
9198
9199                if (i >= NL) {
9200                    removeDyingProviderLocked(app, cpr);
9201                    NL = mLaunchingProviders.size();
9202                }
9203            }
9204            app.pubProviders.clear();
9205        }
9206
9207        // Take care of any launching providers waiting for this process.
9208        if (checkAppInLaunchingProvidersLocked(app, false)) {
9209            restart = true;
9210        }
9211
9212        // Unregister from connected content providers.
9213        if (!app.conProviders.isEmpty()) {
9214            Iterator it = app.conProviders.keySet().iterator();
9215            while (it.hasNext()) {
9216                ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9217                cpr.clients.remove(app);
9218            }
9219            app.conProviders.clear();
9220        }
9221
9222        // At this point there may be remaining entries in mLaunchingProviders
9223        // where we were the only one waiting, so they are no longer of use.
9224        // Look for these and clean up if found.
9225        // XXX Commented out for now.  Trying to figure out a way to reproduce
9226        // the actual situation to identify what is actually going on.
9227        if (false) {
9228            for (int i=0; i<NL; i++) {
9229                ContentProviderRecord cpr = (ContentProviderRecord)
9230                        mLaunchingProviders.get(i);
9231                if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9232                    synchronized (cpr) {
9233                        cpr.launchingApp = null;
9234                        cpr.notifyAll();
9235                    }
9236                }
9237            }
9238        }
9239
9240        skipCurrentReceiverLocked(app);
9241
9242        // Unregister any receivers.
9243        if (app.receivers.size() > 0) {
9244            Iterator<ReceiverList> it = app.receivers.iterator();
9245            while (it.hasNext()) {
9246                removeReceiverLocked(it.next());
9247            }
9248            app.receivers.clear();
9249        }
9250
9251        // If the app is undergoing backup, tell the backup manager about it
9252        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
9253            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
9254            try {
9255                IBackupManager bm = IBackupManager.Stub.asInterface(
9256                        ServiceManager.getService(Context.BACKUP_SERVICE));
9257                bm.agentDisconnected(app.info.packageName);
9258            } catch (RemoteException e) {
9259                // can't happen; backup manager is local
9260            }
9261        }
9262
9263        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app).sendToTarget();
9264
9265        // If the caller is restarting this app, then leave it in its
9266        // current lists and let the caller take care of it.
9267        if (restarting) {
9268            return;
9269        }
9270
9271        if (!app.persistent) {
9272            if (DEBUG_PROCESSES) Slog.v(TAG,
9273                    "Removing non-persistent process during cleanup: " + app);
9274            mProcessNames.remove(app.processName, app.info.uid);
9275            if (mHeavyWeightProcess == app) {
9276                mHeavyWeightProcess = null;
9277                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9278            }
9279        } else if (!app.removed) {
9280            // This app is persistent, so we need to keep its record around.
9281            // If it is not already on the pending app list, add it there
9282            // and start a new process for it.
9283            app.thread = null;
9284            app.forcingToForeground = null;
9285            app.foregroundServices = false;
9286            if (mPersistentStartingProcesses.indexOf(app) < 0) {
9287                mPersistentStartingProcesses.add(app);
9288                restart = true;
9289            }
9290        }
9291        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9292                "Clean-up removing on hold: " + app);
9293        mProcessesOnHold.remove(app);
9294
9295        if (app == mHomeProcess) {
9296            mHomeProcess = null;
9297        }
9298
9299        if (restart) {
9300            // We have components that still need to be running in the
9301            // process, so re-launch it.
9302            mProcessNames.put(app.processName, app.info.uid, app);
9303            startProcessLocked(app, "restart", app.processName);
9304        } else if (app.pid > 0 && app.pid != MY_PID) {
9305            // Goodbye!
9306            synchronized (mPidsSelfLocked) {
9307                mPidsSelfLocked.remove(app.pid);
9308                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9309            }
9310            app.setPid(0);
9311        }
9312    }
9313
9314    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9315        // Look through the content providers we are waiting to have launched,
9316        // and if any run in this process then either schedule a restart of
9317        // the process or kill the client waiting for it if this process has
9318        // gone bad.
9319        int NL = mLaunchingProviders.size();
9320        boolean restart = false;
9321        for (int i=0; i<NL; i++) {
9322            ContentProviderRecord cpr = mLaunchingProviders.get(i);
9323            if (cpr.launchingApp == app) {
9324                if (!alwaysBad && !app.bad) {
9325                    restart = true;
9326                } else {
9327                    removeDyingProviderLocked(app, cpr);
9328                    NL = mLaunchingProviders.size();
9329                }
9330            }
9331        }
9332        return restart;
9333    }
9334
9335    // =========================================================
9336    // SERVICES
9337    // =========================================================
9338
9339    ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9340        ActivityManager.RunningServiceInfo info =
9341            new ActivityManager.RunningServiceInfo();
9342        info.service = r.name;
9343        if (r.app != null) {
9344            info.pid = r.app.pid;
9345        }
9346        info.uid = r.appInfo.uid;
9347        info.process = r.processName;
9348        info.foreground = r.isForeground;
9349        info.activeSince = r.createTime;
9350        info.started = r.startRequested;
9351        info.clientCount = r.connections.size();
9352        info.crashCount = r.crashCount;
9353        info.lastActivityTime = r.lastActivity;
9354        if (r.isForeground) {
9355            info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9356        }
9357        if (r.startRequested) {
9358            info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9359        }
9360        if (r.app != null && r.app.pid == MY_PID) {
9361            info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9362        }
9363        if (r.app != null && r.app.persistent) {
9364            info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9365        }
9366
9367        for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9368            for (int i=0; i<connl.size(); i++) {
9369                ConnectionRecord conn = connl.get(i);
9370                if (conn.clientLabel != 0) {
9371                    info.clientPackage = conn.binding.client.info.packageName;
9372                    info.clientLabel = conn.clientLabel;
9373                    return info;
9374                }
9375            }
9376        }
9377        return info;
9378    }
9379
9380    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9381            int flags) {
9382        synchronized (this) {
9383            ArrayList<ActivityManager.RunningServiceInfo> res
9384                    = new ArrayList<ActivityManager.RunningServiceInfo>();
9385
9386            if (mServices.size() > 0) {
9387                Iterator<ServiceRecord> it = mServices.values().iterator();
9388                while (it.hasNext() && res.size() < maxNum) {
9389                    res.add(makeRunningServiceInfoLocked(it.next()));
9390                }
9391            }
9392
9393            for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9394                ServiceRecord r = mRestartingServices.get(i);
9395                ActivityManager.RunningServiceInfo info =
9396                        makeRunningServiceInfoLocked(r);
9397                info.restarting = r.nextRestartTime;
9398                res.add(info);
9399            }
9400
9401            return res;
9402        }
9403    }
9404
9405    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9406        synchronized (this) {
9407            ServiceRecord r = mServices.get(name);
9408            if (r != null) {
9409                for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9410                    for (int i=0; i<conn.size(); i++) {
9411                        if (conn.get(i).clientIntent != null) {
9412                            return conn.get(i).clientIntent;
9413                        }
9414                    }
9415                }
9416            }
9417        }
9418        return null;
9419    }
9420
9421    private final ServiceRecord findServiceLocked(ComponentName name,
9422            IBinder token) {
9423        ServiceRecord r = mServices.get(name);
9424        return r == token ? r : null;
9425    }
9426
9427    private final class ServiceLookupResult {
9428        final ServiceRecord record;
9429        final String permission;
9430
9431        ServiceLookupResult(ServiceRecord _record, String _permission) {
9432            record = _record;
9433            permission = _permission;
9434        }
9435    };
9436
9437    private ServiceLookupResult findServiceLocked(Intent service,
9438            String resolvedType) {
9439        ServiceRecord r = null;
9440        if (service.getComponent() != null) {
9441            r = mServices.get(service.getComponent());
9442        }
9443        if (r == null) {
9444            Intent.FilterComparison filter = new Intent.FilterComparison(service);
9445            r = mServicesByIntent.get(filter);
9446        }
9447
9448        if (r == null) {
9449            try {
9450                ResolveInfo rInfo =
9451                    AppGlobals.getPackageManager().resolveService(
9452                            service, resolvedType, 0);
9453                ServiceInfo sInfo =
9454                    rInfo != null ? rInfo.serviceInfo : null;
9455                if (sInfo == null) {
9456                    return null;
9457                }
9458
9459                ComponentName name = new ComponentName(
9460                        sInfo.applicationInfo.packageName, sInfo.name);
9461                r = mServices.get(name);
9462            } catch (RemoteException ex) {
9463                // pm is in same process, this will never happen.
9464            }
9465        }
9466        if (r != null) {
9467            int callingPid = Binder.getCallingPid();
9468            int callingUid = Binder.getCallingUid();
9469            if (checkComponentPermission(r.permission,
9470                    callingPid, callingUid, r.appInfo.uid, r.exported)
9471                    != PackageManager.PERMISSION_GRANTED) {
9472                if (!r.exported) {
9473                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9474                            + " from pid=" + callingPid
9475                            + ", uid=" + callingUid
9476                            + " that is not exported from uid " + r.appInfo.uid);
9477                    return new ServiceLookupResult(null, "not exported from uid "
9478                            + r.appInfo.uid);
9479                }
9480                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9481                        + " from pid=" + callingPid
9482                        + ", uid=" + callingUid
9483                        + " requires " + r.permission);
9484                return new ServiceLookupResult(null, r.permission);
9485            }
9486            return new ServiceLookupResult(r, null);
9487        }
9488        return null;
9489    }
9490
9491    private class ServiceRestarter implements Runnable {
9492        private ServiceRecord mService;
9493
9494        void setService(ServiceRecord service) {
9495            mService = service;
9496        }
9497
9498        public void run() {
9499            synchronized(ActivityManagerService.this) {
9500                performServiceRestartLocked(mService);
9501            }
9502        }
9503    }
9504
9505    private ServiceLookupResult retrieveServiceLocked(Intent service,
9506            String resolvedType, int callingPid, int callingUid) {
9507        ServiceRecord r = null;
9508        if (service.getComponent() != null) {
9509            r = mServices.get(service.getComponent());
9510        }
9511        Intent.FilterComparison filter = new Intent.FilterComparison(service);
9512        r = mServicesByIntent.get(filter);
9513        if (r == null) {
9514            try {
9515                ResolveInfo rInfo =
9516                    AppGlobals.getPackageManager().resolveService(
9517                            service, resolvedType, STOCK_PM_FLAGS);
9518                ServiceInfo sInfo =
9519                    rInfo != null ? rInfo.serviceInfo : null;
9520                if (sInfo == null) {
9521                    Slog.w(TAG, "Unable to start service " + service +
9522                          ": not found");
9523                    return null;
9524                }
9525
9526                ComponentName name = new ComponentName(
9527                        sInfo.applicationInfo.packageName, sInfo.name);
9528                r = mServices.get(name);
9529                if (r == null) {
9530                    filter = new Intent.FilterComparison(service.cloneFilter());
9531                    ServiceRestarter res = new ServiceRestarter();
9532                    BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9533                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9534                    synchronized (stats) {
9535                        ss = stats.getServiceStatsLocked(
9536                                sInfo.applicationInfo.uid, sInfo.packageName,
9537                                sInfo.name);
9538                    }
9539                    r = new ServiceRecord(this, ss, name, filter, sInfo, res);
9540                    res.setService(r);
9541                    mServices.put(name, r);
9542                    mServicesByIntent.put(filter, r);
9543
9544                    // Make sure this component isn't in the pending list.
9545                    int N = mPendingServices.size();
9546                    for (int i=0; i<N; i++) {
9547                        ServiceRecord pr = mPendingServices.get(i);
9548                        if (pr.name.equals(name)) {
9549                            mPendingServices.remove(i);
9550                            i--;
9551                            N--;
9552                        }
9553                    }
9554                }
9555            } catch (RemoteException ex) {
9556                // pm is in same process, this will never happen.
9557            }
9558        }
9559        if (r != null) {
9560            if (checkComponentPermission(r.permission,
9561                    callingPid, callingUid, r.appInfo.uid, r.exported)
9562                    != PackageManager.PERMISSION_GRANTED) {
9563                if (!r.exported) {
9564                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9565                            + " from pid=" + callingPid
9566                            + ", uid=" + callingUid
9567                            + " that is not exported from uid " + r.appInfo.uid);
9568                    return new ServiceLookupResult(null, "not exported from uid "
9569                            + r.appInfo.uid);
9570                }
9571                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9572                        + " from pid=" + callingPid
9573                        + ", uid=" + callingUid
9574                        + " requires " + r.permission);
9575                return new ServiceLookupResult(null, r.permission);
9576            }
9577            return new ServiceLookupResult(r, null);
9578        }
9579        return null;
9580    }
9581
9582    private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9583        if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9584                + why + " of " + r + " in app " + r.app);
9585        else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9586                + why + " of " + r.shortName);
9587        long now = SystemClock.uptimeMillis();
9588        if (r.executeNesting == 0 && r.app != null) {
9589            if (r.app.executingServices.size() == 0) {
9590                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9591                msg.obj = r.app;
9592                mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9593            }
9594            r.app.executingServices.add(r);
9595        }
9596        r.executeNesting++;
9597        r.executingStart = now;
9598    }
9599
9600    private final void sendServiceArgsLocked(ServiceRecord r,
9601            boolean oomAdjusted) {
9602        final int N = r.pendingStarts.size();
9603        if (N == 0) {
9604            return;
9605        }
9606
9607        while (r.pendingStarts.size() > 0) {
9608            try {
9609                ServiceRecord.StartItem si = r.pendingStarts.remove(0);
9610                if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9611                        + r + " " + r.intent + " args=" + si.intent);
9612                if (si.intent == null && N > 1) {
9613                    // If somehow we got a dummy null intent in the middle,
9614                    // then skip it.  DO NOT skip a null intent when it is
9615                    // the only one in the list -- this is to support the
9616                    // onStartCommand(null) case.
9617                    continue;
9618                }
9619                si.deliveredTime = SystemClock.uptimeMillis();
9620                r.deliveredStarts.add(si);
9621                si.deliveryCount++;
9622                if (si.targetPermissionUid >= 0 && si.intent != null) {
9623                    grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
9624                            r.packageName, si.intent, si.getUriPermissionsLocked());
9625                }
9626                bumpServiceExecutingLocked(r, "start");
9627                if (!oomAdjusted) {
9628                    oomAdjusted = true;
9629                    updateOomAdjLocked(r.app);
9630                }
9631                int flags = 0;
9632                if (si.deliveryCount > 0) {
9633                    flags |= Service.START_FLAG_RETRY;
9634                }
9635                if (si.doneExecutingCount > 0) {
9636                    flags |= Service.START_FLAG_REDELIVERY;
9637                }
9638                r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
9639            } catch (RemoteException e) {
9640                // Remote process gone...  we'll let the normal cleanup take
9641                // care of this.
9642                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
9643                break;
9644            } catch (Exception e) {
9645                Slog.w(TAG, "Unexpected exception", e);
9646                break;
9647            }
9648        }
9649    }
9650
9651    private final boolean requestServiceBindingLocked(ServiceRecord r,
9652            IntentBindRecord i, boolean rebind) {
9653        if (r.app == null || r.app.thread == null) {
9654            // If service is not currently running, can't yet bind.
9655            return false;
9656        }
9657        if ((!i.requested || rebind) && i.apps.size() > 0) {
9658            try {
9659                bumpServiceExecutingLocked(r, "bind");
9660                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9661                if (!rebind) {
9662                    i.requested = true;
9663                }
9664                i.hasBound = true;
9665                i.doRebind = false;
9666            } catch (RemoteException e) {
9667                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
9668                return false;
9669            }
9670        }
9671        return true;
9672    }
9673
9674    private final void requestServiceBindingsLocked(ServiceRecord r) {
9675        Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9676        while (bindings.hasNext()) {
9677            IntentBindRecord i = bindings.next();
9678            if (!requestServiceBindingLocked(r, i, false)) {
9679                break;
9680            }
9681        }
9682    }
9683
9684    private final void realStartServiceLocked(ServiceRecord r,
9685            ProcessRecord app) throws RemoteException {
9686        if (app.thread == null) {
9687            throw new RemoteException();
9688        }
9689
9690        r.app = app;
9691        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
9692
9693        app.services.add(r);
9694        bumpServiceExecutingLocked(r, "create");
9695        updateLruProcessLocked(app, true, true);
9696
9697        boolean created = false;
9698        try {
9699            mStringBuilder.setLength(0);
9700            r.intent.getIntent().toShortString(mStringBuilder, false, true);
9701            EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
9702                    System.identityHashCode(r), r.shortName,
9703                    mStringBuilder.toString(), r.app.pid);
9704            synchronized (r.stats.getBatteryStats()) {
9705                r.stats.startLaunchedLocked();
9706            }
9707            ensurePackageDexOpt(r.serviceInfo.packageName);
9708            app.thread.scheduleCreateService(r, r.serviceInfo,
9709                    compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
9710            r.postNotification();
9711            created = true;
9712        } finally {
9713            if (!created) {
9714                app.services.remove(r);
9715                scheduleServiceRestartLocked(r, false);
9716            }
9717        }
9718
9719        requestServiceBindingsLocked(r);
9720
9721        // If the service is in the started state, and there are no
9722        // pending arguments, then fake up one so its onStartCommand() will
9723        // be called.
9724        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
9725            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
9726                    null, -1));
9727        }
9728
9729        sendServiceArgsLocked(r, true);
9730    }
9731
9732    private final boolean scheduleServiceRestartLocked(ServiceRecord r,
9733            boolean allowCancel) {
9734        boolean canceled = false;
9735
9736        final long now = SystemClock.uptimeMillis();
9737        long minDuration = SERVICE_RESTART_DURATION;
9738        long resetTime = SERVICE_RESET_RUN_DURATION;
9739
9740        if ((r.serviceInfo.applicationInfo.flags
9741                &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9742            minDuration /= 4;
9743        }
9744
9745        // Any delivered but not yet finished starts should be put back
9746        // on the pending list.
9747        final int N = r.deliveredStarts.size();
9748        if (N > 0) {
9749            for (int i=N-1; i>=0; i--) {
9750                ServiceRecord.StartItem si = r.deliveredStarts.get(i);
9751                si.removeUriPermissionsLocked();
9752                if (si.intent == null) {
9753                    // We'll generate this again if needed.
9754                } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
9755                        && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
9756                    r.pendingStarts.add(0, si);
9757                    long dur = SystemClock.uptimeMillis() - si.deliveredTime;
9758                    dur *= 2;
9759                    if (minDuration < dur) minDuration = dur;
9760                    if (resetTime < dur) resetTime = dur;
9761                } else {
9762                    Slog.w(TAG, "Canceling start item " + si.intent + " in service "
9763                            + r.name);
9764                    canceled = true;
9765                }
9766            }
9767            r.deliveredStarts.clear();
9768        }
9769
9770        r.totalRestartCount++;
9771        if (r.restartDelay == 0) {
9772            r.restartCount++;
9773            r.restartDelay = minDuration;
9774        } else {
9775            // If it has been a "reasonably long time" since the service
9776            // was started, then reset our restart duration back to
9777            // the beginning, so we don't infinitely increase the duration
9778            // on a service that just occasionally gets killed (which is
9779            // a normal case, due to process being killed to reclaim memory).
9780            if (now > (r.restartTime+resetTime)) {
9781                r.restartCount = 1;
9782                r.restartDelay = minDuration;
9783            } else {
9784                if ((r.serviceInfo.applicationInfo.flags
9785                        &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9786                    // Services in peristent processes will restart much more
9787                    // quickly, since they are pretty important.  (Think SystemUI).
9788                    r.restartDelay += minDuration/2;
9789                } else {
9790                    r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
9791                    if (r.restartDelay < minDuration) {
9792                        r.restartDelay = minDuration;
9793                    }
9794                }
9795            }
9796        }
9797
9798        r.nextRestartTime = now + r.restartDelay;
9799
9800        // Make sure that we don't end up restarting a bunch of services
9801        // all at the same time.
9802        boolean repeat;
9803        do {
9804            repeat = false;
9805            for (int i=mRestartingServices.size()-1; i>=0; i--) {
9806                ServiceRecord r2 = mRestartingServices.get(i);
9807                if (r2 != r && r.nextRestartTime
9808                        >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
9809                        && r.nextRestartTime
9810                        < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
9811                    r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
9812                    r.restartDelay = r.nextRestartTime - now;
9813                    repeat = true;
9814                    break;
9815                }
9816            }
9817        } while (repeat);
9818
9819        if (!mRestartingServices.contains(r)) {
9820            mRestartingServices.add(r);
9821        }
9822
9823        r.cancelNotification();
9824
9825        mHandler.removeCallbacks(r.restarter);
9826        mHandler.postAtTime(r.restarter, r.nextRestartTime);
9827        r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
9828        Slog.w(TAG, "Scheduling restart of crashed service "
9829                + r.shortName + " in " + r.restartDelay + "ms");
9830        EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
9831                r.shortName, r.restartDelay);
9832
9833        return canceled;
9834    }
9835
9836    final void performServiceRestartLocked(ServiceRecord r) {
9837        if (!mRestartingServices.contains(r)) {
9838            return;
9839        }
9840        bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9841    }
9842
9843    private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9844        if (r.restartDelay == 0) {
9845            return false;
9846        }
9847        r.resetRestartCounter();
9848        mRestartingServices.remove(r);
9849        mHandler.removeCallbacks(r.restarter);
9850        return true;
9851    }
9852
9853    private final boolean bringUpServiceLocked(ServiceRecord r,
9854            int intentFlags, boolean whileRestarting) {
9855        //Slog.i(TAG, "Bring up service:");
9856        //r.dump("  ");
9857
9858        if (r.app != null && r.app.thread != null) {
9859            sendServiceArgsLocked(r, false);
9860            return true;
9861        }
9862
9863        if (!whileRestarting && r.restartDelay > 0) {
9864            // If waiting for a restart, then do nothing.
9865            return true;
9866        }
9867
9868        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
9869
9870        // We are now bringing the service up, so no longer in the
9871        // restarting state.
9872        mRestartingServices.remove(r);
9873
9874        // Service is now being launched, its package can't be stopped.
9875        try {
9876            AppGlobals.getPackageManager().setPackageStoppedState(
9877                    r.packageName, false);
9878        } catch (RemoteException e) {
9879        } catch (IllegalArgumentException e) {
9880            Slog.w(TAG, "Failed trying to unstop package "
9881                    + r.packageName + ": " + e);
9882        }
9883
9884        final String appName = r.processName;
9885        ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
9886        if (app != null && app.thread != null) {
9887            try {
9888                realStartServiceLocked(r, app);
9889                return true;
9890            } catch (RemoteException e) {
9891                Slog.w(TAG, "Exception when starting service " + r.shortName, e);
9892            }
9893
9894            // If a dead object exception was thrown -- fall through to
9895            // restart the application.
9896        }
9897
9898        // Not running -- get it started, and enqueue this service record
9899        // to be executed when the app comes up.
9900        if (startProcessLocked(appName, r.appInfo, true, intentFlags,
9901                "service", r.name, false) == null) {
9902            Slog.w(TAG, "Unable to launch app "
9903                    + r.appInfo.packageName + "/"
9904                    + r.appInfo.uid + " for service "
9905                    + r.intent.getIntent() + ": process is bad");
9906            bringDownServiceLocked(r, true);
9907            return false;
9908        }
9909
9910        if (!mPendingServices.contains(r)) {
9911            mPendingServices.add(r);
9912        }
9913
9914        return true;
9915    }
9916
9917    private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
9918        //Slog.i(TAG, "Bring down service:");
9919        //r.dump("  ");
9920
9921        // Does it still need to run?
9922        if (!force && r.startRequested) {
9923            return;
9924        }
9925        if (r.connections.size() > 0) {
9926            if (!force) {
9927                // XXX should probably keep a count of the number of auto-create
9928                // connections directly in the service.
9929                Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
9930                while (it.hasNext()) {
9931                    ArrayList<ConnectionRecord> cr = it.next();
9932                    for (int i=0; i<cr.size(); i++) {
9933                        if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
9934                            return;
9935                        }
9936                    }
9937                }
9938            }
9939
9940            // Report to all of the connections that the service is no longer
9941            // available.
9942            Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
9943            while (it.hasNext()) {
9944                ArrayList<ConnectionRecord> c = it.next();
9945                for (int i=0; i<c.size(); i++) {
9946                    try {
9947                        c.get(i).conn.connected(r.name, null);
9948                    } catch (Exception e) {
9949                        Slog.w(TAG, "Failure disconnecting service " + r.name +
9950                              " to connection " + c.get(i).conn.asBinder() +
9951                              " (in " + c.get(i).binding.client.processName + ")", e);
9952                    }
9953                }
9954            }
9955        }
9956
9957        // Tell the service that it has been unbound.
9958        if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
9959            Iterator<IntentBindRecord> it = r.bindings.values().iterator();
9960            while (it.hasNext()) {
9961                IntentBindRecord ibr = it.next();
9962                if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
9963                        + ": hasBound=" + ibr.hasBound);
9964                if (r.app != null && r.app.thread != null && ibr.hasBound) {
9965                    try {
9966                        bumpServiceExecutingLocked(r, "bring down unbind");
9967                        updateOomAdjLocked(r.app);
9968                        ibr.hasBound = false;
9969                        r.app.thread.scheduleUnbindService(r,
9970                                ibr.intent.getIntent());
9971                    } catch (Exception e) {
9972                        Slog.w(TAG, "Exception when unbinding service "
9973                                + r.shortName, e);
9974                        serviceDoneExecutingLocked(r, true);
9975                    }
9976                }
9977            }
9978        }
9979
9980        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
9981        EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
9982                System.identityHashCode(r), r.shortName,
9983                (r.app != null) ? r.app.pid : -1);
9984
9985        mServices.remove(r.name);
9986        mServicesByIntent.remove(r.intent);
9987        r.totalRestartCount = 0;
9988        unscheduleServiceRestartLocked(r);
9989
9990        // Also make sure it is not on the pending list.
9991        int N = mPendingServices.size();
9992        for (int i=0; i<N; i++) {
9993            if (mPendingServices.get(i) == r) {
9994                mPendingServices.remove(i);
9995                if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
9996                i--;
9997                N--;
9998            }
9999        }
10000
10001        r.cancelNotification();
10002        r.isForeground = false;
10003        r.foregroundId = 0;
10004        r.foregroundNoti = null;
10005
10006        // Clear start entries.
10007        r.clearDeliveredStartsLocked();
10008        r.pendingStarts.clear();
10009
10010        if (r.app != null) {
10011            synchronized (r.stats.getBatteryStats()) {
10012                r.stats.stopLaunchedLocked();
10013            }
10014            r.app.services.remove(r);
10015            if (r.app.thread != null) {
10016                try {
10017                    bumpServiceExecutingLocked(r, "stop");
10018                    mStoppingServices.add(r);
10019                    updateOomAdjLocked(r.app);
10020                    r.app.thread.scheduleStopService(r);
10021                } catch (Exception e) {
10022                    Slog.w(TAG, "Exception when stopping service "
10023                            + r.shortName, e);
10024                    serviceDoneExecutingLocked(r, true);
10025                }
10026                updateServiceForegroundLocked(r.app, false);
10027            } else {
10028                if (DEBUG_SERVICE) Slog.v(
10029                    TAG, "Removed service that has no process: " + r);
10030            }
10031        } else {
10032            if (DEBUG_SERVICE) Slog.v(
10033                TAG, "Removed service that is not running: " + r);
10034        }
10035
10036        if (r.bindings.size() > 0) {
10037            r.bindings.clear();
10038        }
10039
10040        if (r.restarter instanceof ServiceRestarter) {
10041           ((ServiceRestarter)r.restarter).setService(null);
10042        }
10043    }
10044
10045    ComponentName startServiceLocked(IApplicationThread caller,
10046            Intent service, String resolvedType,
10047            int callingPid, int callingUid) {
10048        synchronized(this) {
10049            if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
10050                    + " type=" + resolvedType + " args=" + service.getExtras());
10051
10052            if (caller != null) {
10053                final ProcessRecord callerApp = getRecordForAppLocked(caller);
10054                if (callerApp == null) {
10055                    throw new SecurityException(
10056                            "Unable to find app for caller " + caller
10057                            + " (pid=" + Binder.getCallingPid()
10058                            + ") when starting service " + service);
10059                }
10060            }
10061
10062            ServiceLookupResult res =
10063                retrieveServiceLocked(service, resolvedType,
10064                        callingPid, callingUid);
10065            if (res == null) {
10066                return null;
10067            }
10068            if (res.record == null) {
10069                return new ComponentName("!", res.permission != null
10070                        ? res.permission : "private to package");
10071            }
10072            ServiceRecord r = res.record;
10073            int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10074                    callingUid, r.packageName, service);
10075            if (unscheduleServiceRestartLocked(r)) {
10076                if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
10077            }
10078            r.startRequested = true;
10079            r.callStart = false;
10080            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10081                    service, targetPermissionUid));
10082            r.lastActivity = SystemClock.uptimeMillis();
10083            synchronized (r.stats.getBatteryStats()) {
10084                r.stats.startRunningLocked();
10085            }
10086            if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10087                return new ComponentName("!", "Service process is bad");
10088            }
10089            return r.name;
10090        }
10091    }
10092
10093    public ComponentName startService(IApplicationThread caller, Intent service,
10094            String resolvedType) {
10095        // Refuse possible leaked file descriptors
10096        if (service != null && service.hasFileDescriptors() == true) {
10097            throw new IllegalArgumentException("File descriptors passed in Intent");
10098        }
10099
10100        synchronized(this) {
10101            final int callingPid = Binder.getCallingPid();
10102            final int callingUid = Binder.getCallingUid();
10103            final long origId = Binder.clearCallingIdentity();
10104            ComponentName res = startServiceLocked(caller, service,
10105                    resolvedType, callingPid, callingUid);
10106            Binder.restoreCallingIdentity(origId);
10107            return res;
10108        }
10109    }
10110
10111    ComponentName startServiceInPackage(int uid,
10112            Intent service, String resolvedType) {
10113        synchronized(this) {
10114            final long origId = Binder.clearCallingIdentity();
10115            ComponentName res = startServiceLocked(null, service,
10116                    resolvedType, -1, uid);
10117            Binder.restoreCallingIdentity(origId);
10118            return res;
10119        }
10120    }
10121
10122    private void stopServiceLocked(ServiceRecord service) {
10123        synchronized (service.stats.getBatteryStats()) {
10124            service.stats.stopRunningLocked();
10125        }
10126        service.startRequested = false;
10127        service.callStart = false;
10128        bringDownServiceLocked(service, false);
10129    }
10130
10131    public int stopService(IApplicationThread caller, Intent service,
10132            String resolvedType) {
10133        // Refuse possible leaked file descriptors
10134        if (service != null && service.hasFileDescriptors() == true) {
10135            throw new IllegalArgumentException("File descriptors passed in Intent");
10136        }
10137
10138        synchronized(this) {
10139            if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
10140                    + " type=" + resolvedType);
10141
10142            final ProcessRecord callerApp = getRecordForAppLocked(caller);
10143            if (caller != null && callerApp == null) {
10144                throw new SecurityException(
10145                        "Unable to find app for caller " + caller
10146                        + " (pid=" + Binder.getCallingPid()
10147                        + ") when stopping service " + service);
10148            }
10149
10150            // If this service is active, make sure it is stopped.
10151            ServiceLookupResult r = findServiceLocked(service, resolvedType);
10152            if (r != null) {
10153                if (r.record != null) {
10154                    final long origId = Binder.clearCallingIdentity();
10155                    try {
10156                        stopServiceLocked(r.record);
10157                    } finally {
10158                        Binder.restoreCallingIdentity(origId);
10159                    }
10160                    return 1;
10161                }
10162                return -1;
10163            }
10164        }
10165
10166        return 0;
10167    }
10168
10169    public IBinder peekService(Intent service, String resolvedType) {
10170        // Refuse possible leaked file descriptors
10171        if (service != null && service.hasFileDescriptors() == true) {
10172            throw new IllegalArgumentException("File descriptors passed in Intent");
10173        }
10174
10175        IBinder ret = null;
10176
10177        synchronized(this) {
10178            ServiceLookupResult r = findServiceLocked(service, resolvedType);
10179
10180            if (r != null) {
10181                // r.record is null if findServiceLocked() failed the caller permission check
10182                if (r.record == null) {
10183                    throw new SecurityException(
10184                            "Permission Denial: Accessing service " + r.record.name
10185                            + " from pid=" + Binder.getCallingPid()
10186                            + ", uid=" + Binder.getCallingUid()
10187                            + " requires " + r.permission);
10188                }
10189                IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10190                if (ib != null) {
10191                    ret = ib.binder;
10192                }
10193            }
10194        }
10195
10196        return ret;
10197    }
10198
10199    public boolean stopServiceToken(ComponentName className, IBinder token,
10200            int startId) {
10201        synchronized(this) {
10202            if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
10203                    + " " + token + " startId=" + startId);
10204            ServiceRecord r = findServiceLocked(className, token);
10205            if (r != null) {
10206                if (startId >= 0) {
10207                    // Asked to only stop if done with all work.  Note that
10208                    // to avoid leaks, we will take this as dropping all
10209                    // start items up to and including this one.
10210                    ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10211                    if (si != null) {
10212                        while (r.deliveredStarts.size() > 0) {
10213                            ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10214                            cur.removeUriPermissionsLocked();
10215                            if (cur == si) {
10216                                break;
10217                            }
10218                        }
10219                    }
10220
10221                    if (r.getLastStartId() != startId) {
10222                        return false;
10223                    }
10224
10225                    if (r.deliveredStarts.size() > 0) {
10226                        Slog.w(TAG, "stopServiceToken startId " + startId
10227                                + " is last, but have " + r.deliveredStarts.size()
10228                                + " remaining args");
10229                    }
10230                }
10231
10232                synchronized (r.stats.getBatteryStats()) {
10233                    r.stats.stopRunningLocked();
10234                    r.startRequested = false;
10235                    r.callStart = false;
10236                }
10237                final long origId = Binder.clearCallingIdentity();
10238                bringDownServiceLocked(r, false);
10239                Binder.restoreCallingIdentity(origId);
10240                return true;
10241            }
10242        }
10243        return false;
10244    }
10245
10246    public void setServiceForeground(ComponentName className, IBinder token,
10247            int id, Notification notification, boolean removeNotification) {
10248        final long origId = Binder.clearCallingIdentity();
10249        try {
10250        synchronized(this) {
10251            ServiceRecord r = findServiceLocked(className, token);
10252            if (r != null) {
10253                if (id != 0) {
10254                    if (notification == null) {
10255                        throw new IllegalArgumentException("null notification");
10256                    }
10257                    if (r.foregroundId != id) {
10258                        r.cancelNotification();
10259                        r.foregroundId = id;
10260                    }
10261                    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10262                    r.foregroundNoti = notification;
10263                    r.isForeground = true;
10264                    r.postNotification();
10265                    if (r.app != null) {
10266                        updateServiceForegroundLocked(r.app, true);
10267                    }
10268                } else {
10269                    if (r.isForeground) {
10270                        r.isForeground = false;
10271                        if (r.app != null) {
10272                            updateLruProcessLocked(r.app, false, true);
10273                            updateServiceForegroundLocked(r.app, true);
10274                        }
10275                    }
10276                    if (removeNotification) {
10277                        r.cancelNotification();
10278                        r.foregroundId = 0;
10279                        r.foregroundNoti = null;
10280                    }
10281                }
10282            }
10283        }
10284        } finally {
10285            Binder.restoreCallingIdentity(origId);
10286        }
10287    }
10288
10289    public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10290        boolean anyForeground = false;
10291        for (ServiceRecord sr : proc.services) {
10292            if (sr.isForeground) {
10293                anyForeground = true;
10294                break;
10295            }
10296        }
10297        if (anyForeground != proc.foregroundServices) {
10298            proc.foregroundServices = anyForeground;
10299            if (oomAdj) {
10300                updateOomAdjLocked();
10301            }
10302        }
10303    }
10304
10305    public int bindService(IApplicationThread caller, IBinder token,
10306            Intent service, String resolvedType,
10307            IServiceConnection connection, int flags) {
10308        // Refuse possible leaked file descriptors
10309        if (service != null && service.hasFileDescriptors() == true) {
10310            throw new IllegalArgumentException("File descriptors passed in Intent");
10311        }
10312
10313        synchronized(this) {
10314            if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
10315                    + " type=" + resolvedType + " conn=" + connection.asBinder()
10316                    + " flags=0x" + Integer.toHexString(flags));
10317            final ProcessRecord callerApp = getRecordForAppLocked(caller);
10318            if (callerApp == null) {
10319                throw new SecurityException(
10320                        "Unable to find app for caller " + caller
10321                        + " (pid=" + Binder.getCallingPid()
10322                        + ") when binding service " + service);
10323            }
10324
10325            ActivityRecord activity = null;
10326            if (token != null) {
10327                int aindex = mMainStack.indexOfTokenLocked(token);
10328                if (aindex < 0) {
10329                    Slog.w(TAG, "Binding with unknown activity: " + token);
10330                    return 0;
10331                }
10332                activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
10333            }
10334
10335            int clientLabel = 0;
10336            PendingIntent clientIntent = null;
10337
10338            if (callerApp.info.uid == Process.SYSTEM_UID) {
10339                // Hacky kind of thing -- allow system stuff to tell us
10340                // what they are, so we can report this elsewhere for
10341                // others to know why certain services are running.
10342                try {
10343                    clientIntent = (PendingIntent)service.getParcelableExtra(
10344                            Intent.EXTRA_CLIENT_INTENT);
10345                } catch (RuntimeException e) {
10346                }
10347                if (clientIntent != null) {
10348                    clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10349                    if (clientLabel != 0) {
10350                        // There are no useful extras in the intent, trash them.
10351                        // System code calling with this stuff just needs to know
10352                        // this will happen.
10353                        service = service.cloneFilter();
10354                    }
10355                }
10356            }
10357
10358            ServiceLookupResult res =
10359                retrieveServiceLocked(service, resolvedType,
10360                        Binder.getCallingPid(), Binder.getCallingUid());
10361            if (res == null) {
10362                return 0;
10363            }
10364            if (res.record == null) {
10365                return -1;
10366            }
10367            ServiceRecord s = res.record;
10368
10369            final long origId = Binder.clearCallingIdentity();
10370
10371            if (unscheduleServiceRestartLocked(s)) {
10372                if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
10373                        + s);
10374            }
10375
10376            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10377            ConnectionRecord c = new ConnectionRecord(b, activity,
10378                    connection, flags, clientLabel, clientIntent);
10379
10380            IBinder binder = connection.asBinder();
10381            ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10382            if (clist == null) {
10383                clist = new ArrayList<ConnectionRecord>();
10384                s.connections.put(binder, clist);
10385            }
10386            clist.add(c);
10387            b.connections.add(c);
10388            if (activity != null) {
10389                if (activity.connections == null) {
10390                    activity.connections = new HashSet<ConnectionRecord>();
10391                }
10392                activity.connections.add(c);
10393            }
10394            b.client.connections.add(c);
10395            clist = mServiceConnections.get(binder);
10396            if (clist == null) {
10397                clist = new ArrayList<ConnectionRecord>();
10398                mServiceConnections.put(binder, clist);
10399            }
10400            clist.add(c);
10401
10402            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10403                s.lastActivity = SystemClock.uptimeMillis();
10404                if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10405                    return 0;
10406                }
10407            }
10408
10409            if (s.app != null) {
10410                // This could have made the service more important.
10411                updateOomAdjLocked(s.app);
10412            }
10413
10414            if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
10415                    + ": received=" + b.intent.received
10416                    + " apps=" + b.intent.apps.size()
10417                    + " doRebind=" + b.intent.doRebind);
10418
10419            if (s.app != null && b.intent.received) {
10420                // Service is already running, so we can immediately
10421                // publish the connection.
10422                try {
10423                    c.conn.connected(s.name, b.intent.binder);
10424                } catch (Exception e) {
10425                    Slog.w(TAG, "Failure sending service " + s.shortName
10426                            + " to connection " + c.conn.asBinder()
10427                            + " (in " + c.binding.client.processName + ")", e);
10428                }
10429
10430                // If this is the first app connected back to this binding,
10431                // and the service had previously asked to be told when
10432                // rebound, then do so.
10433                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10434                    requestServiceBindingLocked(s, b.intent, true);
10435                }
10436            } else if (!b.intent.requested) {
10437                requestServiceBindingLocked(s, b.intent, false);
10438            }
10439
10440            Binder.restoreCallingIdentity(origId);
10441        }
10442
10443        return 1;
10444    }
10445
10446    void removeConnectionLocked(
10447        ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
10448        IBinder binder = c.conn.asBinder();
10449        AppBindRecord b = c.binding;
10450        ServiceRecord s = b.service;
10451        ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10452        if (clist != null) {
10453            clist.remove(c);
10454            if (clist.size() == 0) {
10455                s.connections.remove(binder);
10456            }
10457        }
10458        b.connections.remove(c);
10459        if (c.activity != null && c.activity != skipAct) {
10460            if (c.activity.connections != null) {
10461                c.activity.connections.remove(c);
10462            }
10463        }
10464        if (b.client != skipApp) {
10465            b.client.connections.remove(c);
10466        }
10467        clist = mServiceConnections.get(binder);
10468        if (clist != null) {
10469            clist.remove(c);
10470            if (clist.size() == 0) {
10471                mServiceConnections.remove(binder);
10472            }
10473        }
10474
10475        if (b.connections.size() == 0) {
10476            b.intent.apps.remove(b.client);
10477        }
10478
10479        if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
10480                + ": shouldUnbind=" + b.intent.hasBound);
10481        if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10482                && b.intent.hasBound) {
10483            try {
10484                bumpServiceExecutingLocked(s, "unbind");
10485                updateOomAdjLocked(s.app);
10486                b.intent.hasBound = false;
10487                // Assume the client doesn't want to know about a rebind;
10488                // we will deal with that later if it asks for one.
10489                b.intent.doRebind = false;
10490                s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10491            } catch (Exception e) {
10492                Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
10493                serviceDoneExecutingLocked(s, true);
10494            }
10495        }
10496
10497        if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10498            bringDownServiceLocked(s, false);
10499        }
10500    }
10501
10502    public boolean unbindService(IServiceConnection connection) {
10503        synchronized (this) {
10504            IBinder binder = connection.asBinder();
10505            if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
10506            ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10507            if (clist == null) {
10508                Slog.w(TAG, "Unbind failed: could not find connection for "
10509                      + connection.asBinder());
10510                return false;
10511            }
10512
10513            final long origId = Binder.clearCallingIdentity();
10514
10515            while (clist.size() > 0) {
10516                ConnectionRecord r = clist.get(0);
10517                removeConnectionLocked(r, null, null);
10518
10519                if (r.binding.service.app != null) {
10520                    // This could have made the service less important.
10521                    updateOomAdjLocked(r.binding.service.app);
10522                }
10523            }
10524
10525            Binder.restoreCallingIdentity(origId);
10526        }
10527
10528        return true;
10529    }
10530
10531    public void publishService(IBinder token, Intent intent, IBinder service) {
10532        // Refuse possible leaked file descriptors
10533        if (intent != null && intent.hasFileDescriptors() == true) {
10534            throw new IllegalArgumentException("File descriptors passed in Intent");
10535        }
10536
10537        synchronized(this) {
10538            if (!(token instanceof ServiceRecord)) {
10539                throw new IllegalArgumentException("Invalid service token");
10540            }
10541            ServiceRecord r = (ServiceRecord)token;
10542
10543            final long origId = Binder.clearCallingIdentity();
10544
10545            if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
10546                    + " " + intent + ": " + service);
10547            if (r != null) {
10548                Intent.FilterComparison filter
10549                        = new Intent.FilterComparison(intent);
10550                IntentBindRecord b = r.bindings.get(filter);
10551                if (b != null && !b.received) {
10552                    b.binder = service;
10553                    b.requested = true;
10554                    b.received = true;
10555                    if (r.connections.size() > 0) {
10556                        Iterator<ArrayList<ConnectionRecord>> it
10557                                = r.connections.values().iterator();
10558                        while (it.hasNext()) {
10559                            ArrayList<ConnectionRecord> clist = it.next();
10560                            for (int i=0; i<clist.size(); i++) {
10561                                ConnectionRecord c = clist.get(i);
10562                                if (!filter.equals(c.binding.intent.intent)) {
10563                                    if (DEBUG_SERVICE) Slog.v(
10564                                            TAG, "Not publishing to: " + c);
10565                                    if (DEBUG_SERVICE) Slog.v(
10566                                            TAG, "Bound intent: " + c.binding.intent.intent);
10567                                    if (DEBUG_SERVICE) Slog.v(
10568                                            TAG, "Published intent: " + intent);
10569                                    continue;
10570                                }
10571                                if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10572                                try {
10573                                    c.conn.connected(r.name, service);
10574                                } catch (Exception e) {
10575                                    Slog.w(TAG, "Failure sending service " + r.name +
10576                                          " to connection " + c.conn.asBinder() +
10577                                          " (in " + c.binding.client.processName + ")", e);
10578                                }
10579                            }
10580                        }
10581                    }
10582                }
10583
10584                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10585
10586                Binder.restoreCallingIdentity(origId);
10587            }
10588        }
10589    }
10590
10591    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10592        // Refuse possible leaked file descriptors
10593        if (intent != null && intent.hasFileDescriptors() == true) {
10594            throw new IllegalArgumentException("File descriptors passed in Intent");
10595        }
10596
10597        synchronized(this) {
10598            if (!(token instanceof ServiceRecord)) {
10599                throw new IllegalArgumentException("Invalid service token");
10600            }
10601            ServiceRecord r = (ServiceRecord)token;
10602
10603            final long origId = Binder.clearCallingIdentity();
10604
10605            if (r != null) {
10606                Intent.FilterComparison filter
10607                        = new Intent.FilterComparison(intent);
10608                IntentBindRecord b = r.bindings.get(filter);
10609                if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
10610                        + " at " + b + ": apps="
10611                        + (b != null ? b.apps.size() : 0));
10612                if (b != null) {
10613                    if (b.apps.size() > 0) {
10614                        // Applications have already bound since the last
10615                        // unbind, so just rebind right here.
10616                        requestServiceBindingLocked(r, b, true);
10617                    } else {
10618                        // Note to tell the service the next time there is
10619                        // a new client.
10620                        b.doRebind = true;
10621                    }
10622                }
10623
10624                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10625
10626                Binder.restoreCallingIdentity(origId);
10627            }
10628        }
10629    }
10630
10631    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10632        synchronized(this) {
10633            if (!(token instanceof ServiceRecord)) {
10634                throw new IllegalArgumentException("Invalid service token");
10635            }
10636            ServiceRecord r = (ServiceRecord)token;
10637            boolean inStopping = mStoppingServices.contains(token);
10638            if (r != null) {
10639                if (r != token) {
10640                    Slog.w(TAG, "Done executing service " + r.name
10641                          + " with incorrect token: given " + token
10642                          + ", expected " + r);
10643                    return;
10644                }
10645
10646                if (type == 1) {
10647                    // This is a call from a service start...  take care of
10648                    // book-keeping.
10649                    r.callStart = true;
10650                    switch (res) {
10651                        case Service.START_STICKY_COMPATIBILITY:
10652                        case Service.START_STICKY: {
10653                            // We are done with the associated start arguments.
10654                            r.findDeliveredStart(startId, true);
10655                            // Don't stop if killed.
10656                            r.stopIfKilled = false;
10657                            break;
10658                        }
10659                        case Service.START_NOT_STICKY: {
10660                            // We are done with the associated start arguments.
10661                            r.findDeliveredStart(startId, true);
10662                            if (r.getLastStartId() == startId) {
10663                                // There is no more work, and this service
10664                                // doesn't want to hang around if killed.
10665                                r.stopIfKilled = true;
10666                            }
10667                            break;
10668                        }
10669                        case Service.START_REDELIVER_INTENT: {
10670                            // We'll keep this item until they explicitly
10671                            // call stop for it, but keep track of the fact
10672                            // that it was delivered.
10673                            ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10674                            if (si != null) {
10675                                si.deliveryCount = 0;
10676                                si.doneExecutingCount++;
10677                                // Don't stop if killed.
10678                                r.stopIfKilled = true;
10679                            }
10680                            break;
10681                        }
10682                        case Service.START_TASK_REMOVED_COMPLETE: {
10683                            // Special processing for onTaskRemoved().  Don't
10684                            // impact normal onStartCommand() processing.
10685                            r.findDeliveredStart(startId, true);
10686                            break;
10687                        }
10688                        default:
10689                            throw new IllegalArgumentException(
10690                                    "Unknown service start result: " + res);
10691                    }
10692                    if (res == Service.START_STICKY_COMPATIBILITY) {
10693                        r.callStart = false;
10694                    }
10695                }
10696
10697                final long origId = Binder.clearCallingIdentity();
10698                serviceDoneExecutingLocked(r, inStopping);
10699                Binder.restoreCallingIdentity(origId);
10700            } else {
10701                Slog.w(TAG, "Done executing unknown service from pid "
10702                        + Binder.getCallingPid());
10703            }
10704        }
10705    }
10706
10707    public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
10708        if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
10709                + ": nesting=" + r.executeNesting
10710                + ", inStopping=" + inStopping + ", app=" + r.app);
10711        else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
10712        r.executeNesting--;
10713        if (r.executeNesting <= 0 && r.app != null) {
10714            if (DEBUG_SERVICE) Slog.v(TAG,
10715                    "Nesting at 0 of " + r.shortName);
10716            r.app.executingServices.remove(r);
10717            if (r.app.executingServices.size() == 0) {
10718                if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
10719                        "No more executingServices of " + r.shortName);
10720                mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10721            }
10722            if (inStopping) {
10723                if (DEBUG_SERVICE) Slog.v(TAG,
10724                        "doneExecuting remove stopping " + r);
10725                mStoppingServices.remove(r);
10726                r.bindings.clear();
10727            }
10728            updateOomAdjLocked(r.app);
10729        }
10730    }
10731
10732    void serviceTimeout(ProcessRecord proc) {
10733        String anrMessage = null;
10734
10735        synchronized(this) {
10736            if (proc.executingServices.size() == 0 || proc.thread == null) {
10737                return;
10738            }
10739            long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
10740            Iterator<ServiceRecord> it = proc.executingServices.iterator();
10741            ServiceRecord timeout = null;
10742            long nextTime = 0;
10743            while (it.hasNext()) {
10744                ServiceRecord sr = it.next();
10745                if (sr.executingStart < maxTime) {
10746                    timeout = sr;
10747                    break;
10748                }
10749                if (sr.executingStart > nextTime) {
10750                    nextTime = sr.executingStart;
10751                }
10752            }
10753            if (timeout != null && mLruProcesses.contains(proc)) {
10754                Slog.w(TAG, "Timeout executing service: " + timeout);
10755                anrMessage = "Executing service " + timeout.shortName;
10756            } else {
10757                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10758                msg.obj = proc;
10759                mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
10760            }
10761        }
10762
10763        if (anrMessage != null) {
10764            appNotResponding(proc, null, null, anrMessage);
10765        }
10766    }
10767
10768    // =========================================================
10769    // BACKUP AND RESTORE
10770    // =========================================================
10771
10772    // Cause the target app to be launched if necessary and its backup agent
10773    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10774    // activity manager to announce its creation.
10775    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10776        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10777        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10778
10779        synchronized(this) {
10780            // !!! TODO: currently no check here that we're already bound
10781            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10782            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10783            synchronized (stats) {
10784                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10785            }
10786
10787            // Backup agent is now in use, its package can't be stopped.
10788            try {
10789                AppGlobals.getPackageManager().setPackageStoppedState(
10790                        app.packageName, false);
10791            } catch (RemoteException e) {
10792            } catch (IllegalArgumentException e) {
10793                Slog.w(TAG, "Failed trying to unstop package "
10794                        + app.packageName + ": " + e);
10795            }
10796
10797            BackupRecord r = new BackupRecord(ss, app, backupMode);
10798            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10799                    ? new ComponentName(app.packageName, app.backupAgentName)
10800                    : new ComponentName("android", "FullBackupAgent");
10801            // startProcessLocked() returns existing proc's record if it's already running
10802            ProcessRecord proc = startProcessLocked(app.processName, app,
10803                    false, 0, "backup", hostingName, false);
10804            if (proc == null) {
10805                Slog.e(TAG, "Unable to start backup agent process " + r);
10806                return false;
10807            }
10808
10809            r.app = proc;
10810            mBackupTarget = r;
10811            mBackupAppName = app.packageName;
10812
10813            // Try not to kill the process during backup
10814            updateOomAdjLocked(proc);
10815
10816            // If the process is already attached, schedule the creation of the backup agent now.
10817            // If it is not yet live, this will be done when it attaches to the framework.
10818            if (proc.thread != null) {
10819                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
10820                try {
10821                    proc.thread.scheduleCreateBackupAgent(app,
10822                            compatibilityInfoForPackageLocked(app), backupMode);
10823                } catch (RemoteException e) {
10824                    // Will time out on the backup manager side
10825                }
10826            } else {
10827                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
10828            }
10829            // Invariants: at this point, the target app process exists and the application
10830            // is either already running or in the process of coming up.  mBackupTarget and
10831            // mBackupAppName describe the app, so that when it binds back to the AM we
10832            // know that it's scheduled for a backup-agent operation.
10833        }
10834
10835        return true;
10836    }
10837
10838    // A backup agent has just come up
10839    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10840        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
10841                + " = " + agent);
10842
10843        synchronized(this) {
10844            if (!agentPackageName.equals(mBackupAppName)) {
10845                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10846                return;
10847            }
10848        }
10849
10850        long oldIdent = Binder.clearCallingIdentity();
10851        try {
10852            IBackupManager bm = IBackupManager.Stub.asInterface(
10853                    ServiceManager.getService(Context.BACKUP_SERVICE));
10854            bm.agentConnected(agentPackageName, agent);
10855        } catch (RemoteException e) {
10856            // can't happen; the backup manager service is local
10857        } catch (Exception e) {
10858            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10859            e.printStackTrace();
10860        } finally {
10861            Binder.restoreCallingIdentity(oldIdent);
10862        }
10863    }
10864
10865    // done with this agent
10866    public void unbindBackupAgent(ApplicationInfo appInfo) {
10867        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
10868        if (appInfo == null) {
10869            Slog.w(TAG, "unbind backup agent for null app");
10870            return;
10871        }
10872
10873        synchronized(this) {
10874            if (mBackupAppName == null) {
10875                Slog.w(TAG, "Unbinding backup agent with no active backup");
10876                return;
10877            }
10878
10879            if (!mBackupAppName.equals(appInfo.packageName)) {
10880                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
10881                return;
10882            }
10883
10884            ProcessRecord proc = mBackupTarget.app;
10885            mBackupTarget = null;
10886            mBackupAppName = null;
10887
10888            // Not backing this app up any more; reset its OOM adjustment
10889            updateOomAdjLocked(proc);
10890
10891            // If the app crashed during backup, 'thread' will be null here
10892            if (proc.thread != null) {
10893                try {
10894                    proc.thread.scheduleDestroyBackupAgent(appInfo,
10895                            compatibilityInfoForPackageLocked(appInfo));
10896                } catch (Exception e) {
10897                    Slog.e(TAG, "Exception when unbinding backup agent:");
10898                    e.printStackTrace();
10899                }
10900            }
10901        }
10902    }
10903    // =========================================================
10904    // BROADCASTS
10905    // =========================================================
10906
10907    private final List getStickiesLocked(String action, IntentFilter filter,
10908            List cur) {
10909        final ContentResolver resolver = mContext.getContentResolver();
10910        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10911        if (list == null) {
10912            return cur;
10913        }
10914        int N = list.size();
10915        for (int i=0; i<N; i++) {
10916            Intent intent = list.get(i);
10917            if (filter.match(resolver, intent, true, TAG) >= 0) {
10918                if (cur == null) {
10919                    cur = new ArrayList<Intent>();
10920                }
10921                cur.add(intent);
10922            }
10923        }
10924        return cur;
10925    }
10926
10927    private final void scheduleBroadcastsLocked() {
10928        if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
10929                + mBroadcastsScheduled);
10930
10931        if (mBroadcastsScheduled) {
10932            return;
10933        }
10934        mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
10935        mBroadcastsScheduled = true;
10936    }
10937
10938    public Intent registerReceiver(IApplicationThread caller,
10939            IIntentReceiver receiver, IntentFilter filter, String permission) {
10940        synchronized(this) {
10941            ProcessRecord callerApp = null;
10942            if (caller != null) {
10943                callerApp = getRecordForAppLocked(caller);
10944                if (callerApp == null) {
10945                    throw new SecurityException(
10946                            "Unable to find app for caller " + caller
10947                            + " (pid=" + Binder.getCallingPid()
10948                            + ") when registering receiver " + receiver);
10949                }
10950            }
10951
10952            List allSticky = null;
10953
10954            // Look for any matching sticky broadcasts...
10955            Iterator actions = filter.actionsIterator();
10956            if (actions != null) {
10957                while (actions.hasNext()) {
10958                    String action = (String)actions.next();
10959                    allSticky = getStickiesLocked(action, filter, allSticky);
10960                }
10961            } else {
10962                allSticky = getStickiesLocked(null, filter, allSticky);
10963            }
10964
10965            // The first sticky in the list is returned directly back to
10966            // the client.
10967            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10968
10969            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
10970                    + ": " + sticky);
10971
10972            if (receiver == null) {
10973                return sticky;
10974            }
10975
10976            ReceiverList rl
10977                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10978            if (rl == null) {
10979                rl = new ReceiverList(this, callerApp,
10980                        Binder.getCallingPid(),
10981                        Binder.getCallingUid(), receiver);
10982                if (rl.app != null) {
10983                    rl.app.receivers.add(rl);
10984                } else {
10985                    try {
10986                        receiver.asBinder().linkToDeath(rl, 0);
10987                    } catch (RemoteException e) {
10988                        return sticky;
10989                    }
10990                    rl.linkedToDeath = true;
10991                }
10992                mRegisteredReceivers.put(receiver.asBinder(), rl);
10993            }
10994            BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
10995            rl.add(bf);
10996            if (!bf.debugCheck()) {
10997                Slog.w(TAG, "==> For Dynamic broadast");
10998            }
10999            mReceiverResolver.addFilter(bf);
11000
11001            // Enqueue broadcasts for all existing stickies that match
11002            // this filter.
11003            if (allSticky != null) {
11004                ArrayList receivers = new ArrayList();
11005                receivers.add(bf);
11006
11007                int N = allSticky.size();
11008                for (int i=0; i<N; i++) {
11009                    Intent intent = (Intent)allSticky.get(i);
11010                    BroadcastRecord r = new BroadcastRecord(intent, null,
11011                            null, -1, -1, null, receivers, null, 0, null, null,
11012                            false, true, true);
11013                    if (mParallelBroadcasts.size() == 0) {
11014                        scheduleBroadcastsLocked();
11015                    }
11016                    mParallelBroadcasts.add(r);
11017                }
11018            }
11019
11020            return sticky;
11021        }
11022    }
11023
11024    public void unregisterReceiver(IIntentReceiver receiver) {
11025        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11026
11027        boolean doNext = false;
11028
11029        synchronized(this) {
11030            ReceiverList rl
11031                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11032            if (rl != null) {
11033                if (rl.curBroadcast != null) {
11034                    BroadcastRecord r = rl.curBroadcast;
11035                    doNext = finishReceiverLocked(
11036                        receiver.asBinder(), r.resultCode, r.resultData,
11037                        r.resultExtras, r.resultAbort, true);
11038                }
11039
11040                if (rl.app != null) {
11041                    rl.app.receivers.remove(rl);
11042                }
11043                removeReceiverLocked(rl);
11044                if (rl.linkedToDeath) {
11045                    rl.linkedToDeath = false;
11046                    rl.receiver.asBinder().unlinkToDeath(rl, 0);
11047                }
11048            }
11049        }
11050
11051        if (!doNext) {
11052            return;
11053        }
11054
11055        final long origId = Binder.clearCallingIdentity();
11056        processNextBroadcast(false);
11057        trimApplications();
11058        Binder.restoreCallingIdentity(origId);
11059    }
11060
11061    void removeReceiverLocked(ReceiverList rl) {
11062        mRegisteredReceivers.remove(rl.receiver.asBinder());
11063        int N = rl.size();
11064        for (int i=0; i<N; i++) {
11065            mReceiverResolver.removeFilter(rl.get(i));
11066        }
11067    }
11068
11069    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11070        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11071            ProcessRecord r = mLruProcesses.get(i);
11072            if (r.thread != null) {
11073                try {
11074                    r.thread.dispatchPackageBroadcast(cmd, packages);
11075                } catch (RemoteException ex) {
11076                }
11077            }
11078        }
11079    }
11080
11081    private final int broadcastIntentLocked(ProcessRecord callerApp,
11082            String callerPackage, Intent intent, String resolvedType,
11083            IIntentReceiver resultTo, int resultCode, String resultData,
11084            Bundle map, String requiredPermission,
11085            boolean ordered, boolean sticky, int callingPid, int callingUid) {
11086        intent = new Intent(intent);
11087
11088        // By default broadcasts do not go to stopped apps.
11089        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11090
11091        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11092            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11093            + " ordered=" + ordered);
11094        if ((resultTo != null) && !ordered) {
11095            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11096        }
11097
11098        // Handle special intents: if this broadcast is from the package
11099        // manager about a package being removed, we need to remove all of
11100        // its activities from the history stack.
11101        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11102                intent.getAction());
11103        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11104                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11105                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11106                || uidRemoved) {
11107            if (checkComponentPermission(
11108                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11109                    callingPid, callingUid, -1, true)
11110                    == PackageManager.PERMISSION_GRANTED) {
11111                if (uidRemoved) {
11112                    final Bundle intentExtras = intent.getExtras();
11113                    final int uid = intentExtras != null
11114                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11115                    if (uid >= 0) {
11116                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11117                        synchronized (bs) {
11118                            bs.removeUidStatsLocked(uid);
11119                        }
11120                    }
11121                } else {
11122                    // If resources are unvailble just force stop all
11123                    // those packages and flush the attribute cache as well.
11124                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11125                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11126                        if (list != null && (list.length > 0)) {
11127                            for (String pkg : list) {
11128                                forceStopPackageLocked(pkg, -1, false, true, true);
11129                            }
11130                            sendPackageBroadcastLocked(
11131                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
11132                        }
11133                    } else {
11134                        Uri data = intent.getData();
11135                        String ssp;
11136                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11137                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11138                                forceStopPackageLocked(ssp,
11139                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
11140                            }
11141                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11142                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11143                                        new String[] {ssp});
11144                            }
11145                        }
11146                    }
11147                }
11148            } else {
11149                String msg = "Permission Denial: " + intent.getAction()
11150                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11151                        + ", uid=" + callingUid + ")"
11152                        + " requires "
11153                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11154                Slog.w(TAG, msg);
11155                throw new SecurityException(msg);
11156            }
11157
11158        // Special case for adding a package: by default turn on compatibility
11159        // mode.
11160        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11161            if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
11162                Uri data = intent.getData();
11163                String ssp;
11164                if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11165                    mCompatModePackages.setPackageScreenCompatModeLocked(ssp,
11166                            ActivityManager.COMPAT_MODE_ENABLED);
11167                }
11168            }
11169        }
11170
11171        /*
11172         * If this is the time zone changed action, queue up a message that will reset the timezone
11173         * of all currently running processes. This message will get queued up before the broadcast
11174         * happens.
11175         */
11176        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11177            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11178        }
11179
11180        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11181            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11182        }
11183
11184        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11185            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11186            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11187        }
11188
11189        /*
11190         * Prevent non-system code (defined here to be non-persistent
11191         * processes) from sending protected broadcasts.
11192         */
11193        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11194                || callingUid == Process.SHELL_UID || callingUid == 0) {
11195            // Always okay.
11196        } else if (callerApp == null || !callerApp.persistent) {
11197            try {
11198                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11199                        intent.getAction())) {
11200                    String msg = "Permission Denial: not allowed to send broadcast "
11201                            + intent.getAction() + " from pid="
11202                            + callingPid + ", uid=" + callingUid;
11203                    Slog.w(TAG, msg);
11204                    throw new SecurityException(msg);
11205                }
11206            } catch (RemoteException e) {
11207                Slog.w(TAG, "Remote exception", e);
11208                return BROADCAST_SUCCESS;
11209            }
11210        }
11211
11212        // Add to the sticky list if requested.
11213        if (sticky) {
11214            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11215                    callingPid, callingUid)
11216                    != PackageManager.PERMISSION_GRANTED) {
11217                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11218                        + callingPid + ", uid=" + callingUid
11219                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11220                Slog.w(TAG, msg);
11221                throw new SecurityException(msg);
11222            }
11223            if (requiredPermission != null) {
11224                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11225                        + " and enforce permission " + requiredPermission);
11226                return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11227            }
11228            if (intent.getComponent() != null) {
11229                throw new SecurityException(
11230                        "Sticky broadcasts can't target a specific component");
11231            }
11232            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11233            if (list == null) {
11234                list = new ArrayList<Intent>();
11235                mStickyBroadcasts.put(intent.getAction(), list);
11236            }
11237            int N = list.size();
11238            int i;
11239            for (i=0; i<N; i++) {
11240                if (intent.filterEquals(list.get(i))) {
11241                    // This sticky already exists, replace it.
11242                    list.set(i, new Intent(intent));
11243                    break;
11244                }
11245            }
11246            if (i >= N) {
11247                list.add(new Intent(intent));
11248            }
11249        }
11250
11251        // Figure out who all will receive this broadcast.
11252        List receivers = null;
11253        List<BroadcastFilter> registeredReceivers = null;
11254        try {
11255            if (intent.getComponent() != null) {
11256                // Broadcast is going to one specific receiver class...
11257                ActivityInfo ai = AppGlobals.getPackageManager().
11258                    getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
11259                if (ai != null) {
11260                    receivers = new ArrayList();
11261                    ResolveInfo ri = new ResolveInfo();
11262                    ri.activityInfo = ai;
11263                    receivers.add(ri);
11264                }
11265            } else {
11266                // Need to resolve the intent to interested receivers...
11267                if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11268                         == 0) {
11269                    receivers =
11270                        AppGlobals.getPackageManager().queryIntentReceivers(
11271                                intent, resolvedType, STOCK_PM_FLAGS);
11272                }
11273                registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
11274            }
11275        } catch (RemoteException ex) {
11276            // pm is in same process, this will never happen.
11277        }
11278
11279        final boolean replacePending =
11280                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11281
11282        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11283                + " replacePending=" + replacePending);
11284
11285        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11286        if (!ordered && NR > 0) {
11287            // If we are not serializing this broadcast, then send the
11288            // registered receivers separately so they don't wait for the
11289            // components to be launched.
11290            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11291                    callerPackage, callingPid, callingUid, requiredPermission,
11292                    registeredReceivers, resultTo, resultCode, resultData, map,
11293                    ordered, sticky, false);
11294            if (DEBUG_BROADCAST) Slog.v(
11295                    TAG, "Enqueueing parallel broadcast " + r
11296                    + ": prev had " + mParallelBroadcasts.size());
11297            boolean replaced = false;
11298            if (replacePending) {
11299                for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11300                    if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
11301                        if (DEBUG_BROADCAST) Slog.v(TAG,
11302                                "***** DROPPING PARALLEL: " + intent);
11303                        mParallelBroadcasts.set(i, r);
11304                        replaced = true;
11305                        break;
11306                    }
11307                }
11308            }
11309            if (!replaced) {
11310                mParallelBroadcasts.add(r);
11311                scheduleBroadcastsLocked();
11312            }
11313            registeredReceivers = null;
11314            NR = 0;
11315        }
11316
11317        // Merge into one list.
11318        int ir = 0;
11319        if (receivers != null) {
11320            // A special case for PACKAGE_ADDED: do not allow the package
11321            // being added to see this broadcast.  This prevents them from
11322            // using this as a back door to get run as soon as they are
11323            // installed.  Maybe in the future we want to have a special install
11324            // broadcast or such for apps, but we'd like to deliberately make
11325            // this decision.
11326            String skipPackages[] = null;
11327            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11328                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11329                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11330                Uri data = intent.getData();
11331                if (data != null) {
11332                    String pkgName = data.getSchemeSpecificPart();
11333                    if (pkgName != null) {
11334                        skipPackages = new String[] { pkgName };
11335                    }
11336                }
11337            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11338                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11339            }
11340            if (skipPackages != null && (skipPackages.length > 0)) {
11341                for (String skipPackage : skipPackages) {
11342                    if (skipPackage != null) {
11343                        int NT = receivers.size();
11344                        for (int it=0; it<NT; it++) {
11345                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11346                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11347                                receivers.remove(it);
11348                                it--;
11349                                NT--;
11350                            }
11351                        }
11352                    }
11353                }
11354            }
11355
11356            int NT = receivers != null ? receivers.size() : 0;
11357            int it = 0;
11358            ResolveInfo curt = null;
11359            BroadcastFilter curr = null;
11360            while (it < NT && ir < NR) {
11361                if (curt == null) {
11362                    curt = (ResolveInfo)receivers.get(it);
11363                }
11364                if (curr == null) {
11365                    curr = registeredReceivers.get(ir);
11366                }
11367                if (curr.getPriority() >= curt.priority) {
11368                    // Insert this broadcast record into the final list.
11369                    receivers.add(it, curr);
11370                    ir++;
11371                    curr = null;
11372                    it++;
11373                    NT++;
11374                } else {
11375                    // Skip to the next ResolveInfo in the final list.
11376                    it++;
11377                    curt = null;
11378                }
11379            }
11380        }
11381        while (ir < NR) {
11382            if (receivers == null) {
11383                receivers = new ArrayList();
11384            }
11385            receivers.add(registeredReceivers.get(ir));
11386            ir++;
11387        }
11388
11389        if ((receivers != null && receivers.size() > 0)
11390                || resultTo != null) {
11391            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11392                    callerPackage, callingPid, callingUid, requiredPermission,
11393                    receivers, resultTo, resultCode, resultData, map, ordered,
11394                    sticky, false);
11395            if (DEBUG_BROADCAST) Slog.v(
11396                    TAG, "Enqueueing ordered broadcast " + r
11397                    + ": prev had " + mOrderedBroadcasts.size());
11398            if (DEBUG_BROADCAST) {
11399                int seq = r.intent.getIntExtra("seq", -1);
11400                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11401            }
11402            boolean replaced = false;
11403            if (replacePending) {
11404                for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
11405                    if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
11406                        if (DEBUG_BROADCAST) Slog.v(TAG,
11407                                "***** DROPPING ORDERED: " + intent);
11408                        mOrderedBroadcasts.set(i, r);
11409                        replaced = true;
11410                        break;
11411                    }
11412                }
11413            }
11414            if (!replaced) {
11415                mOrderedBroadcasts.add(r);
11416                scheduleBroadcastsLocked();
11417            }
11418        }
11419
11420        return BROADCAST_SUCCESS;
11421    }
11422
11423    final Intent verifyBroadcastLocked(Intent intent) {
11424        // Refuse possible leaked file descriptors
11425        if (intent != null && intent.hasFileDescriptors() == true) {
11426            throw new IllegalArgumentException("File descriptors passed in Intent");
11427        }
11428
11429        int flags = intent.getFlags();
11430
11431        if (!mProcessesReady) {
11432            // if the caller really truly claims to know what they're doing, go
11433            // ahead and allow the broadcast without launching any receivers
11434            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11435                intent = new Intent(intent);
11436                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11437            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11438                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11439                        + " before boot completion");
11440                throw new IllegalStateException("Cannot broadcast before boot completed");
11441            }
11442        }
11443
11444        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11445            throw new IllegalArgumentException(
11446                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11447        }
11448
11449        return intent;
11450    }
11451
11452    public final int broadcastIntent(IApplicationThread caller,
11453            Intent intent, String resolvedType, IIntentReceiver resultTo,
11454            int resultCode, String resultData, Bundle map,
11455            String requiredPermission, boolean serialized, boolean sticky) {
11456        synchronized(this) {
11457            intent = verifyBroadcastLocked(intent);
11458
11459            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11460            final int callingPid = Binder.getCallingPid();
11461            final int callingUid = Binder.getCallingUid();
11462            final long origId = Binder.clearCallingIdentity();
11463            int res = broadcastIntentLocked(callerApp,
11464                    callerApp != null ? callerApp.info.packageName : null,
11465                    intent, resolvedType, resultTo,
11466                    resultCode, resultData, map, requiredPermission, serialized,
11467                    sticky, callingPid, callingUid);
11468            Binder.restoreCallingIdentity(origId);
11469            return res;
11470        }
11471    }
11472
11473    int broadcastIntentInPackage(String packageName, int uid,
11474            Intent intent, String resolvedType, IIntentReceiver resultTo,
11475            int resultCode, String resultData, Bundle map,
11476            String requiredPermission, boolean serialized, boolean sticky) {
11477        synchronized(this) {
11478            intent = verifyBroadcastLocked(intent);
11479
11480            final long origId = Binder.clearCallingIdentity();
11481            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11482                    resultTo, resultCode, resultData, map, requiredPermission,
11483                    serialized, sticky, -1, uid);
11484            Binder.restoreCallingIdentity(origId);
11485            return res;
11486        }
11487    }
11488
11489    public final void unbroadcastIntent(IApplicationThread caller,
11490            Intent intent) {
11491        // Refuse possible leaked file descriptors
11492        if (intent != null && intent.hasFileDescriptors() == true) {
11493            throw new IllegalArgumentException("File descriptors passed in Intent");
11494        }
11495
11496        synchronized(this) {
11497            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11498                    != PackageManager.PERMISSION_GRANTED) {
11499                String msg = "Permission Denial: unbroadcastIntent() from pid="
11500                        + Binder.getCallingPid()
11501                        + ", uid=" + Binder.getCallingUid()
11502                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11503                Slog.w(TAG, msg);
11504                throw new SecurityException(msg);
11505            }
11506            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11507            if (list != null) {
11508                int N = list.size();
11509                int i;
11510                for (i=0; i<N; i++) {
11511                    if (intent.filterEquals(list.get(i))) {
11512                        list.remove(i);
11513                        break;
11514                    }
11515                }
11516            }
11517        }
11518    }
11519
11520    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11521            String resultData, Bundle resultExtras, boolean resultAbort,
11522            boolean explicit) {
11523        if (mOrderedBroadcasts.size() == 0) {
11524            if (explicit) {
11525                Slog.w(TAG, "finishReceiver called but no pending broadcasts");
11526            }
11527            return false;
11528        }
11529        BroadcastRecord r = mOrderedBroadcasts.get(0);
11530        if (r.receiver == null) {
11531            if (explicit) {
11532                Slog.w(TAG, "finishReceiver called but none active");
11533            }
11534            return false;
11535        }
11536        if (r.receiver != receiver) {
11537            Slog.w(TAG, "finishReceiver called but active receiver is different");
11538            return false;
11539        }
11540        int state = r.state;
11541        r.state = r.IDLE;
11542        if (state == r.IDLE) {
11543            if (explicit) {
11544                Slog.w(TAG, "finishReceiver called but state is IDLE");
11545            }
11546        }
11547        r.receiver = null;
11548        r.intent.setComponent(null);
11549        if (r.curApp != null) {
11550            r.curApp.curReceiver = null;
11551        }
11552        if (r.curFilter != null) {
11553            r.curFilter.receiverList.curBroadcast = null;
11554        }
11555        r.curFilter = null;
11556        r.curApp = null;
11557        r.curComponent = null;
11558        r.curReceiver = null;
11559        mPendingBroadcast = null;
11560
11561        r.resultCode = resultCode;
11562        r.resultData = resultData;
11563        r.resultExtras = resultExtras;
11564        r.resultAbort = resultAbort;
11565
11566        // We will process the next receiver right now if this is finishing
11567        // an app receiver (which is always asynchronous) or after we have
11568        // come back from calling a receiver.
11569        return state == BroadcastRecord.APP_RECEIVE
11570                || state == BroadcastRecord.CALL_DONE_RECEIVE;
11571    }
11572
11573    public void finishReceiver(IBinder who, int resultCode, String resultData,
11574            Bundle resultExtras, boolean resultAbort) {
11575        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11576
11577        // Refuse possible leaked file descriptors
11578        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11579            throw new IllegalArgumentException("File descriptors passed in Bundle");
11580        }
11581
11582        boolean doNext;
11583
11584        final long origId = Binder.clearCallingIdentity();
11585
11586        synchronized(this) {
11587            doNext = finishReceiverLocked(
11588                who, resultCode, resultData, resultExtras, resultAbort, true);
11589        }
11590
11591        if (doNext) {
11592            processNextBroadcast(false);
11593        }
11594        trimApplications();
11595
11596        Binder.restoreCallingIdentity(origId);
11597    }
11598
11599    private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
11600        if (r.nextReceiver > 0) {
11601            Object curReceiver = r.receivers.get(r.nextReceiver-1);
11602            if (curReceiver instanceof BroadcastFilter) {
11603                BroadcastFilter bf = (BroadcastFilter) curReceiver;
11604                EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
11605                        System.identityHashCode(r),
11606                        r.intent.getAction(),
11607                        r.nextReceiver - 1,
11608                        System.identityHashCode(bf));
11609            } else {
11610                EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
11611                        System.identityHashCode(r),
11612                        r.intent.getAction(),
11613                        r.nextReceiver - 1,
11614                        ((ResolveInfo)curReceiver).toString());
11615            }
11616        } else {
11617            Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
11618                    + r);
11619            EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
11620                    System.identityHashCode(r),
11621                    r.intent.getAction(),
11622                    r.nextReceiver,
11623                    "NONE");
11624        }
11625    }
11626
11627    private final void setBroadcastTimeoutLocked(long timeoutTime) {
11628        if (! mPendingBroadcastTimeoutMessage) {
11629            Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11630            mHandler.sendMessageAtTime(msg, timeoutTime);
11631            mPendingBroadcastTimeoutMessage = true;
11632        }
11633    }
11634
11635    private final void cancelBroadcastTimeoutLocked() {
11636        if (mPendingBroadcastTimeoutMessage) {
11637            mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11638            mPendingBroadcastTimeoutMessage = false;
11639        }
11640    }
11641
11642    private final void broadcastTimeoutLocked(boolean fromMsg) {
11643        if (fromMsg) {
11644            mPendingBroadcastTimeoutMessage = false;
11645        }
11646
11647        if (mOrderedBroadcasts.size() == 0) {
11648            return;
11649        }
11650
11651        long now = SystemClock.uptimeMillis();
11652        BroadcastRecord r = mOrderedBroadcasts.get(0);
11653        if (fromMsg) {
11654            if (mDidDexOpt) {
11655                // Delay timeouts until dexopt finishes.
11656                mDidDexOpt = false;
11657                long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11658                setBroadcastTimeoutLocked(timeoutTime);
11659                return;
11660            }
11661            if (! mProcessesReady) {
11662                // Only process broadcast timeouts if the system is ready. That way
11663                // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11664                // to do heavy lifting for system up.
11665                return;
11666            }
11667
11668            long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11669            if (timeoutTime > now) {
11670                // We can observe premature timeouts because we do not cancel and reset the
11671                // broadcast timeout message after each receiver finishes.  Instead, we set up
11672                // an initial timeout then kick it down the road a little further as needed
11673                // when it expires.
11674                if (DEBUG_BROADCAST) Slog.v(TAG,
11675                        "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11676                        + timeoutTime);
11677                setBroadcastTimeoutLocked(timeoutTime);
11678                return;
11679            }
11680        }
11681
11682        Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11683                + ", started " + (now - r.receiverTime) + "ms ago");
11684        r.receiverTime = now;
11685        r.anrCount++;
11686
11687        // Current receiver has passed its expiration date.
11688        if (r.nextReceiver <= 0) {
11689            Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11690            return;
11691        }
11692
11693        ProcessRecord app = null;
11694        String anrMessage = null;
11695
11696        Object curReceiver = r.receivers.get(r.nextReceiver-1);
11697        Slog.w(TAG, "Receiver during timeout: " + curReceiver);
11698        logBroadcastReceiverDiscardLocked(r);
11699        if (curReceiver instanceof BroadcastFilter) {
11700            BroadcastFilter bf = (BroadcastFilter)curReceiver;
11701            if (bf.receiverList.pid != 0
11702                    && bf.receiverList.pid != MY_PID) {
11703                synchronized (this.mPidsSelfLocked) {
11704                    app = this.mPidsSelfLocked.get(
11705                            bf.receiverList.pid);
11706                }
11707            }
11708        } else {
11709            app = r.curApp;
11710        }
11711
11712        if (app != null) {
11713            anrMessage = "Broadcast of " + r.intent.toString();
11714        }
11715
11716        if (mPendingBroadcast == r) {
11717            mPendingBroadcast = null;
11718        }
11719
11720        // Move on to the next receiver.
11721        finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11722                r.resultExtras, r.resultAbort, true);
11723        scheduleBroadcastsLocked();
11724
11725        if (anrMessage != null) {
11726            // Post the ANR to the handler since we do not want to process ANRs while
11727            // potentially holding our lock.
11728            mHandler.post(new AppNotResponding(app, anrMessage));
11729        }
11730    }
11731
11732    private final void processCurBroadcastLocked(BroadcastRecord r,
11733            ProcessRecord app) throws RemoteException {
11734        if (DEBUG_BROADCAST)  Slog.v(TAG,
11735                "Process cur broadcast " + r + " for app " + app);
11736        if (app.thread == null) {
11737            throw new RemoteException();
11738        }
11739        r.receiver = app.thread.asBinder();
11740        r.curApp = app;
11741        app.curReceiver = r;
11742        updateLruProcessLocked(app, true, true);
11743
11744        // Tell the application to launch this receiver.
11745        r.intent.setComponent(r.curComponent);
11746
11747        boolean started = false;
11748        try {
11749            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
11750                    "Delivering to component " + r.curComponent
11751                    + ": " + r);
11752            ensurePackageDexOpt(r.intent.getComponent().getPackageName());
11753            app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
11754                    compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
11755                    r.resultCode, r.resultData, r.resultExtras, r.ordered);
11756            if (DEBUG_BROADCAST)  Slog.v(TAG,
11757                    "Process cur broadcast " + r + " DELIVERED for app " + app);
11758            started = true;
11759        } finally {
11760            if (!started) {
11761                if (DEBUG_BROADCAST)  Slog.v(TAG,
11762                        "Process cur broadcast " + r + ": NOT STARTED!");
11763                r.receiver = null;
11764                r.curApp = null;
11765                app.curReceiver = null;
11766            }
11767        }
11768
11769    }
11770
11771    static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
11772            Intent intent, int resultCode, String data, Bundle extras,
11773            boolean ordered, boolean sticky) throws RemoteException {
11774        // Send the intent to the receiver asynchronously using one-way binder calls.
11775        if (app != null && app.thread != null) {
11776            // If we have an app thread, do the call through that so it is
11777            // correctly ordered with other one-way calls.
11778            app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
11779                    data, extras, ordered, sticky);
11780        } else {
11781            receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
11782        }
11783    }
11784
11785    private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
11786            BroadcastFilter filter, boolean ordered) {
11787        boolean skip = false;
11788        if (filter.requiredPermission != null) {
11789            int perm = checkComponentPermission(filter.requiredPermission,
11790                    r.callingPid, r.callingUid, -1, true);
11791            if (perm != PackageManager.PERMISSION_GRANTED) {
11792                Slog.w(TAG, "Permission Denial: broadcasting "
11793                        + r.intent.toString()
11794                        + " from " + r.callerPackage + " (pid="
11795                        + r.callingPid + ", uid=" + r.callingUid + ")"
11796                        + " requires " + filter.requiredPermission
11797                        + " due to registered receiver " + filter);
11798                skip = true;
11799            }
11800        }
11801        if (r.requiredPermission != null) {
11802            int perm = checkComponentPermission(r.requiredPermission,
11803                    filter.receiverList.pid, filter.receiverList.uid, -1, true);
11804            if (perm != PackageManager.PERMISSION_GRANTED) {
11805                Slog.w(TAG, "Permission Denial: receiving "
11806                        + r.intent.toString()
11807                        + " to " + filter.receiverList.app
11808                        + " (pid=" + filter.receiverList.pid
11809                        + ", uid=" + filter.receiverList.uid + ")"
11810                        + " requires " + r.requiredPermission
11811                        + " due to sender " + r.callerPackage
11812                        + " (uid " + r.callingUid + ")");
11813                skip = true;
11814            }
11815        }
11816
11817        if (!skip) {
11818            // If this is not being sent as an ordered broadcast, then we
11819            // don't want to touch the fields that keep track of the current
11820            // state of ordered broadcasts.
11821            if (ordered) {
11822                r.receiver = filter.receiverList.receiver.asBinder();
11823                r.curFilter = filter;
11824                filter.receiverList.curBroadcast = r;
11825                r.state = BroadcastRecord.CALL_IN_RECEIVE;
11826                if (filter.receiverList.app != null) {
11827                    // Bump hosting application to no longer be in background
11828                    // scheduling class.  Note that we can't do that if there
11829                    // isn't an app...  but we can only be in that case for
11830                    // things that directly call the IActivityManager API, which
11831                    // are already core system stuff so don't matter for this.
11832                    r.curApp = filter.receiverList.app;
11833                    filter.receiverList.app.curReceiver = r;
11834                    updateOomAdjLocked();
11835                }
11836            }
11837            try {
11838                if (DEBUG_BROADCAST_LIGHT) {
11839                    int seq = r.intent.getIntExtra("seq", -1);
11840                    Slog.i(TAG, "Delivering to " + filter
11841                            + " (seq=" + seq + "): " + r);
11842                }
11843                performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
11844                    new Intent(r.intent), r.resultCode,
11845                    r.resultData, r.resultExtras, r.ordered, r.initialSticky);
11846                if (ordered) {
11847                    r.state = BroadcastRecord.CALL_DONE_RECEIVE;
11848                }
11849            } catch (RemoteException e) {
11850                Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
11851                if (ordered) {
11852                    r.receiver = null;
11853                    r.curFilter = null;
11854                    filter.receiverList.curBroadcast = null;
11855                    if (filter.receiverList.app != null) {
11856                        filter.receiverList.app.curReceiver = null;
11857                    }
11858                }
11859            }
11860        }
11861    }
11862
11863    private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
11864        if (r.callingUid < 0) {
11865            // This was from a registerReceiver() call; ignore it.
11866            return;
11867        }
11868        System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
11869                MAX_BROADCAST_HISTORY-1);
11870        r.finishTime = SystemClock.uptimeMillis();
11871        mBroadcastHistory[0] = r;
11872    }
11873
11874    private final void processNextBroadcast(boolean fromMsg) {
11875        synchronized(this) {
11876            BroadcastRecord r;
11877
11878            if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
11879                    + mParallelBroadcasts.size() + " broadcasts, "
11880                    + mOrderedBroadcasts.size() + " ordered broadcasts");
11881
11882            updateCpuStats();
11883
11884            if (fromMsg) {
11885                mBroadcastsScheduled = false;
11886            }
11887
11888            // First, deliver any non-serialized broadcasts right away.
11889            while (mParallelBroadcasts.size() > 0) {
11890                r = mParallelBroadcasts.remove(0);
11891                r.dispatchTime = SystemClock.uptimeMillis();
11892                final int N = r.receivers.size();
11893                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
11894                        + r);
11895                for (int i=0; i<N; i++) {
11896                    Object target = r.receivers.get(i);
11897                    if (DEBUG_BROADCAST)  Slog.v(TAG,
11898                            "Delivering non-ordered to registered "
11899                            + target + ": " + r);
11900                    deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
11901                }
11902                addBroadcastToHistoryLocked(r);
11903                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
11904                        + r);
11905            }
11906
11907            // Now take care of the next serialized one...
11908
11909            // If we are waiting for a process to come up to handle the next
11910            // broadcast, then do nothing at this point.  Just in case, we
11911            // check that the process we're waiting for still exists.
11912            if (mPendingBroadcast != null) {
11913                if (DEBUG_BROADCAST_LIGHT) {
11914                    Slog.v(TAG, "processNextBroadcast: waiting for "
11915                            + mPendingBroadcast.curApp);
11916                }
11917
11918                boolean isDead;
11919                synchronized (mPidsSelfLocked) {
11920                    isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
11921                }
11922                if (!isDead) {
11923                    // It's still alive, so keep waiting
11924                    return;
11925                } else {
11926                    Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
11927                            + " died before responding to broadcast");
11928                    mPendingBroadcast.state = BroadcastRecord.IDLE;
11929                    mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
11930                    mPendingBroadcast = null;
11931                }
11932            }
11933
11934            boolean looped = false;
11935
11936            do {
11937                if (mOrderedBroadcasts.size() == 0) {
11938                    // No more broadcasts pending, so all done!
11939                    scheduleAppGcsLocked();
11940                    if (looped) {
11941                        // If we had finished the last ordered broadcast, then
11942                        // make sure all processes have correct oom and sched
11943                        // adjustments.
11944                        updateOomAdjLocked();
11945                    }
11946                    return;
11947                }
11948                r = mOrderedBroadcasts.get(0);
11949                boolean forceReceive = false;
11950
11951                // Ensure that even if something goes awry with the timeout
11952                // detection, we catch "hung" broadcasts here, discard them,
11953                // and continue to make progress.
11954                //
11955                // This is only done if the system is ready so that PRE_BOOT_COMPLETED
11956                // receivers don't get executed with timeouts. They're intended for
11957                // one time heavy lifting after system upgrades and can take
11958                // significant amounts of time.
11959                int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
11960                if (mProcessesReady && r.dispatchTime > 0) {
11961                    long now = SystemClock.uptimeMillis();
11962                    if ((numReceivers > 0) &&
11963                            (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
11964                        Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
11965                                + " now=" + now
11966                                + " dispatchTime=" + r.dispatchTime
11967                                + " startTime=" + r.receiverTime
11968                                + " intent=" + r.intent
11969                                + " numReceivers=" + numReceivers
11970                                + " nextReceiver=" + r.nextReceiver
11971                                + " state=" + r.state);
11972                        broadcastTimeoutLocked(false); // forcibly finish this broadcast
11973                        forceReceive = true;
11974                        r.state = BroadcastRecord.IDLE;
11975                    }
11976                }
11977
11978                if (r.state != BroadcastRecord.IDLE) {
11979                    if (DEBUG_BROADCAST) Slog.d(TAG,
11980                            "processNextBroadcast() called when not idle (state="
11981                            + r.state + ")");
11982                    return;
11983                }
11984
11985                if (r.receivers == null || r.nextReceiver >= numReceivers
11986                        || r.resultAbort || forceReceive) {
11987                    // No more receivers for this broadcast!  Send the final
11988                    // result if requested...
11989                    if (r.resultTo != null) {
11990                        try {
11991                            if (DEBUG_BROADCAST) {
11992                                int seq = r.intent.getIntExtra("seq", -1);
11993                                Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
11994                                        + " seq=" + seq + " app=" + r.callerApp);
11995                            }
11996                            performReceiveLocked(r.callerApp, r.resultTo,
11997                                new Intent(r.intent), r.resultCode,
11998                                r.resultData, r.resultExtras, false, false);
11999                            // Set this to null so that the reference
12000                            // (local and remote) isnt kept in the mBroadcastHistory.
12001                            r.resultTo = null;
12002                        } catch (RemoteException e) {
12003                            Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
12004                        }
12005                    }
12006
12007                    if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
12008                    cancelBroadcastTimeoutLocked();
12009
12010                    if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
12011                            + r);
12012
12013                    // ... and on to the next...
12014                    addBroadcastToHistoryLocked(r);
12015                    mOrderedBroadcasts.remove(0);
12016                    r = null;
12017                    looped = true;
12018                    continue;
12019                }
12020            } while (r == null);
12021
12022            // Get the next receiver...
12023            int recIdx = r.nextReceiver++;
12024
12025            // Keep track of when this receiver started, and make sure there
12026            // is a timeout message pending to kill it if need be.
12027            r.receiverTime = SystemClock.uptimeMillis();
12028            if (recIdx == 0) {
12029                r.dispatchTime = r.receiverTime;
12030
12031                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
12032                        + r);
12033            }
12034            if (! mPendingBroadcastTimeoutMessage) {
12035                long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12036                if (DEBUG_BROADCAST) Slog.v(TAG,
12037                        "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12038                setBroadcastTimeoutLocked(timeoutTime);
12039            }
12040
12041            Object nextReceiver = r.receivers.get(recIdx);
12042            if (nextReceiver instanceof BroadcastFilter) {
12043                // Simple case: this is a registered receiver who gets
12044                // a direct call.
12045                BroadcastFilter filter = (BroadcastFilter)nextReceiver;
12046                if (DEBUG_BROADCAST)  Slog.v(TAG,
12047                        "Delivering ordered to registered "
12048                        + filter + ": " + r);
12049                deliverToRegisteredReceiverLocked(r, filter, r.ordered);
12050                if (r.receiver == null || !r.ordered) {
12051                    // The receiver has already finished, so schedule to
12052                    // process the next one.
12053                    if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12054                            + r.ordered + " receiver=" + r.receiver);
12055                    r.state = BroadcastRecord.IDLE;
12056                    scheduleBroadcastsLocked();
12057                }
12058                return;
12059            }
12060
12061            // Hard case: need to instantiate the receiver, possibly
12062            // starting its application process to host it.
12063
12064            ResolveInfo info =
12065                (ResolveInfo)nextReceiver;
12066
12067            boolean skip = false;
12068            int perm = checkComponentPermission(info.activityInfo.permission,
12069                    r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12070                    info.activityInfo.exported);
12071            if (perm != PackageManager.PERMISSION_GRANTED) {
12072                if (!info.activityInfo.exported) {
12073                    Slog.w(TAG, "Permission Denial: broadcasting "
12074                            + r.intent.toString()
12075                            + " from " + r.callerPackage + " (pid=" + r.callingPid
12076                            + ", uid=" + r.callingUid + ")"
12077                            + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12078                            + " due to receiver " + info.activityInfo.packageName
12079                            + "/" + info.activityInfo.name);
12080                } else {
12081                    Slog.w(TAG, "Permission Denial: broadcasting "
12082                            + r.intent.toString()
12083                            + " from " + r.callerPackage + " (pid=" + r.callingPid
12084                            + ", uid=" + r.callingUid + ")"
12085                            + " requires " + info.activityInfo.permission
12086                            + " due to receiver " + info.activityInfo.packageName
12087                            + "/" + info.activityInfo.name);
12088                }
12089                skip = true;
12090            }
12091            if (r.callingUid != Process.SYSTEM_UID &&
12092                r.requiredPermission != null) {
12093                try {
12094                    perm = AppGlobals.getPackageManager().
12095                            checkPermission(r.requiredPermission,
12096                                    info.activityInfo.applicationInfo.packageName);
12097                } catch (RemoteException e) {
12098                    perm = PackageManager.PERMISSION_DENIED;
12099                }
12100                if (perm != PackageManager.PERMISSION_GRANTED) {
12101                    Slog.w(TAG, "Permission Denial: receiving "
12102                            + r.intent + " to "
12103                            + info.activityInfo.applicationInfo.packageName
12104                            + " requires " + r.requiredPermission
12105                            + " due to sender " + r.callerPackage
12106                            + " (uid " + r.callingUid + ")");
12107                    skip = true;
12108                }
12109            }
12110            if (r.curApp != null && r.curApp.crashing) {
12111                // If the target process is crashing, just skip it.
12112                if (DEBUG_BROADCAST)  Slog.v(TAG,
12113                        "Skipping deliver ordered " + r + " to " + r.curApp
12114                        + ": process crashing");
12115                skip = true;
12116            }
12117
12118            if (skip) {
12119                if (DEBUG_BROADCAST)  Slog.v(TAG,
12120                        "Skipping delivery of ordered " + r + " for whatever reason");
12121                r.receiver = null;
12122                r.curFilter = null;
12123                r.state = BroadcastRecord.IDLE;
12124                scheduleBroadcastsLocked();
12125                return;
12126            }
12127
12128            r.state = BroadcastRecord.APP_RECEIVE;
12129            String targetProcess = info.activityInfo.processName;
12130            r.curComponent = new ComponentName(
12131                    info.activityInfo.applicationInfo.packageName,
12132                    info.activityInfo.name);
12133            r.curReceiver = info.activityInfo;
12134
12135            // Broadcast is being executed, its package can't be stopped.
12136            try {
12137                AppGlobals.getPackageManager().setPackageStoppedState(
12138                        r.curComponent.getPackageName(), false);
12139            } catch (RemoteException e) {
12140            } catch (IllegalArgumentException e) {
12141                Slog.w(TAG, "Failed trying to unstop package "
12142                        + r.curComponent.getPackageName() + ": " + e);
12143            }
12144
12145            // Is this receiver's application already running?
12146            ProcessRecord app = getProcessRecordLocked(targetProcess,
12147                    info.activityInfo.applicationInfo.uid);
12148            if (app != null && app.thread != null) {
12149                try {
12150                    processCurBroadcastLocked(r, app);
12151                    return;
12152                } catch (RemoteException e) {
12153                    Slog.w(TAG, "Exception when sending broadcast to "
12154                          + r.curComponent, e);
12155                }
12156
12157                // If a dead object exception was thrown -- fall through to
12158                // restart the application.
12159            }
12160
12161            // Not running -- get it started, to be executed when the app comes up.
12162            if (DEBUG_BROADCAST)  Slog.v(TAG,
12163                    "Need to start app " + targetProcess + " for broadcast " + r);
12164            if ((r.curApp=startProcessLocked(targetProcess,
12165                    info.activityInfo.applicationInfo, true,
12166                    r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
12167                    "broadcast", r.curComponent,
12168                    (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12169                            == null) {
12170                // Ah, this recipient is unavailable.  Finish it if necessary,
12171                // and mark the broadcast record as ready for the next.
12172                Slog.w(TAG, "Unable to launch app "
12173                        + info.activityInfo.applicationInfo.packageName + "/"
12174                        + info.activityInfo.applicationInfo.uid + " for broadcast "
12175                        + r.intent + ": process is bad");
12176                logBroadcastReceiverDiscardLocked(r);
12177                finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12178                        r.resultExtras, r.resultAbort, true);
12179                scheduleBroadcastsLocked();
12180                r.state = BroadcastRecord.IDLE;
12181                return;
12182            }
12183
12184            mPendingBroadcast = r;
12185            mPendingBroadcastRecvIndex = recIdx;
12186        }
12187    }
12188
12189    // =========================================================
12190    // INSTRUMENTATION
12191    // =========================================================
12192
12193    public boolean startInstrumentation(ComponentName className,
12194            String profileFile, int flags, Bundle arguments,
12195            IInstrumentationWatcher watcher) {
12196        // Refuse possible leaked file descriptors
12197        if (arguments != null && arguments.hasFileDescriptors()) {
12198            throw new IllegalArgumentException("File descriptors passed in Bundle");
12199        }
12200
12201        synchronized(this) {
12202            InstrumentationInfo ii = null;
12203            ApplicationInfo ai = null;
12204            try {
12205                ii = mContext.getPackageManager().getInstrumentationInfo(
12206                    className, STOCK_PM_FLAGS);
12207                ai = mContext.getPackageManager().getApplicationInfo(
12208                    ii.targetPackage, STOCK_PM_FLAGS);
12209            } catch (PackageManager.NameNotFoundException e) {
12210            }
12211            if (ii == null) {
12212                reportStartInstrumentationFailure(watcher, className,
12213                        "Unable to find instrumentation info for: " + className);
12214                return false;
12215            }
12216            if (ai == null) {
12217                reportStartInstrumentationFailure(watcher, className,
12218                        "Unable to find instrumentation target package: " + ii.targetPackage);
12219                return false;
12220            }
12221
12222            int match = mContext.getPackageManager().checkSignatures(
12223                    ii.targetPackage, ii.packageName);
12224            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12225                String msg = "Permission Denial: starting instrumentation "
12226                        + className + " from pid="
12227                        + Binder.getCallingPid()
12228                        + ", uid=" + Binder.getCallingPid()
12229                        + " not allowed because package " + ii.packageName
12230                        + " does not have a signature matching the target "
12231                        + ii.targetPackage;
12232                reportStartInstrumentationFailure(watcher, className, msg);
12233                throw new SecurityException(msg);
12234            }
12235
12236            final long origId = Binder.clearCallingIdentity();
12237            forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
12238            ProcessRecord app = addAppLocked(ai);
12239            app.instrumentationClass = className;
12240            app.instrumentationInfo = ai;
12241            app.instrumentationProfileFile = profileFile;
12242            app.instrumentationArguments = arguments;
12243            app.instrumentationWatcher = watcher;
12244            app.instrumentationResultClass = className;
12245            Binder.restoreCallingIdentity(origId);
12246        }
12247
12248        return true;
12249    }
12250
12251    /**
12252     * Report errors that occur while attempting to start Instrumentation.  Always writes the
12253     * error to the logs, but if somebody is watching, send the report there too.  This enables
12254     * the "am" command to report errors with more information.
12255     *
12256     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12257     * @param cn The component name of the instrumentation.
12258     * @param report The error report.
12259     */
12260    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12261            ComponentName cn, String report) {
12262        Slog.w(TAG, report);
12263        try {
12264            if (watcher != null) {
12265                Bundle results = new Bundle();
12266                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12267                results.putString("Error", report);
12268                watcher.instrumentationStatus(cn, -1, results);
12269            }
12270        } catch (RemoteException e) {
12271            Slog.w(TAG, e);
12272        }
12273    }
12274
12275    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12276        if (app.instrumentationWatcher != null) {
12277            try {
12278                // NOTE:  IInstrumentationWatcher *must* be oneway here
12279                app.instrumentationWatcher.instrumentationFinished(
12280                    app.instrumentationClass,
12281                    resultCode,
12282                    results);
12283            } catch (RemoteException e) {
12284            }
12285        }
12286        app.instrumentationWatcher = null;
12287        app.instrumentationClass = null;
12288        app.instrumentationInfo = null;
12289        app.instrumentationProfileFile = null;
12290        app.instrumentationArguments = null;
12291
12292        forceStopPackageLocked(app.processName, -1, false, false, true);
12293    }
12294
12295    public void finishInstrumentation(IApplicationThread target,
12296            int resultCode, Bundle results) {
12297        // Refuse possible leaked file descriptors
12298        if (results != null && results.hasFileDescriptors()) {
12299            throw new IllegalArgumentException("File descriptors passed in Intent");
12300        }
12301
12302        synchronized(this) {
12303            ProcessRecord app = getRecordForAppLocked(target);
12304            if (app == null) {
12305                Slog.w(TAG, "finishInstrumentation: no app for " + target);
12306                return;
12307            }
12308            final long origId = Binder.clearCallingIdentity();
12309            finishInstrumentationLocked(app, resultCode, results);
12310            Binder.restoreCallingIdentity(origId);
12311        }
12312    }
12313
12314    // =========================================================
12315    // CONFIGURATION
12316    // =========================================================
12317
12318    public ConfigurationInfo getDeviceConfigurationInfo() {
12319        ConfigurationInfo config = new ConfigurationInfo();
12320        synchronized (this) {
12321            config.reqTouchScreen = mConfiguration.touchscreen;
12322            config.reqKeyboardType = mConfiguration.keyboard;
12323            config.reqNavigation = mConfiguration.navigation;
12324            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12325                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12326                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12327            }
12328            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12329                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12330                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12331            }
12332            config.reqGlEsVersion = GL_ES_VERSION;
12333        }
12334        return config;
12335    }
12336
12337    public Configuration getConfiguration() {
12338        Configuration ci;
12339        synchronized(this) {
12340            ci = new Configuration(mConfiguration);
12341        }
12342        return ci;
12343    }
12344
12345    public void updateConfiguration(Configuration values) {
12346        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12347                "updateConfiguration()");
12348
12349        synchronized(this) {
12350            if (values == null && mWindowManager != null) {
12351                // sentinel: fetch the current configuration from the window manager
12352                values = mWindowManager.computeNewConfiguration();
12353            }
12354
12355            final long origId = Binder.clearCallingIdentity();
12356            updateConfigurationLocked(values, null);
12357            Binder.restoreCallingIdentity(origId);
12358        }
12359    }
12360
12361    /**
12362     * Do either or both things: (1) change the current configuration, and (2)
12363     * make sure the given activity is running with the (now) current
12364     * configuration.  Returns true if the activity has been left running, or
12365     * false if <var>starting</var> is being destroyed to match the new
12366     * configuration.
12367     */
12368    public boolean updateConfigurationLocked(Configuration values,
12369            ActivityRecord starting) {
12370        int changes = 0;
12371
12372        boolean kept = true;
12373
12374        if (values != null) {
12375            Configuration newConfig = new Configuration(mConfiguration);
12376            changes = newConfig.updateFrom(values);
12377            if (changes != 0) {
12378                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12379                    Slog.i(TAG, "Updating configuration to: " + values);
12380                }
12381
12382                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12383
12384                if (values.locale != null) {
12385                    saveLocaleLocked(values.locale,
12386                                     !values.locale.equals(mConfiguration.locale),
12387                                     values.userSetLocale);
12388                }
12389
12390                mConfigurationSeq++;
12391                if (mConfigurationSeq <= 0) {
12392                    mConfigurationSeq = 1;
12393                }
12394                newConfig.seq = mConfigurationSeq;
12395                mConfiguration = newConfig;
12396                Slog.i(TAG, "Config changed: " + newConfig);
12397
12398                AttributeCache ac = AttributeCache.instance();
12399                if (ac != null) {
12400                    ac.updateConfiguration(mConfiguration);
12401                }
12402
12403                if (Settings.System.hasInterestingConfigurationChanges(changes)) {
12404                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12405                    msg.obj = new Configuration(mConfiguration);
12406                    mHandler.sendMessage(msg);
12407                }
12408
12409                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12410                    ProcessRecord app = mLruProcesses.get(i);
12411                    try {
12412                        if (app.thread != null) {
12413                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12414                                    + app.processName + " new config " + mConfiguration);
12415                            app.thread.scheduleConfigurationChanged(mConfiguration);
12416                        }
12417                    } catch (Exception e) {
12418                    }
12419                }
12420                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12421                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12422                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
12423                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12424                        null, false, false, MY_PID, Process.SYSTEM_UID);
12425                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12426                    broadcastIntentLocked(null, null,
12427                            new Intent(Intent.ACTION_LOCALE_CHANGED),
12428                            null, null, 0, null, null,
12429                            null, false, false, MY_PID, Process.SYSTEM_UID);
12430                }
12431            }
12432        }
12433
12434        if (changes != 0 && starting == null) {
12435            // If the configuration changed, and the caller is not already
12436            // in the process of starting an activity, then find the top
12437            // activity to check if its configuration needs to change.
12438            starting = mMainStack.topRunningActivityLocked(null);
12439        }
12440
12441        if (starting != null) {
12442            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12443            // And we need to make sure at this point that all other activities
12444            // are made visible with the correct configuration.
12445            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12446        }
12447
12448        if (values != null && mWindowManager != null) {
12449            mWindowManager.setNewConfiguration(mConfiguration);
12450        }
12451
12452        return kept;
12453    }
12454
12455    /**
12456     * Save the locale.  You must be inside a synchronized (this) block.
12457     */
12458    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12459        if(isDiff) {
12460            SystemProperties.set("user.language", l.getLanguage());
12461            SystemProperties.set("user.region", l.getCountry());
12462        }
12463
12464        if(isPersist) {
12465            SystemProperties.set("persist.sys.language", l.getLanguage());
12466            SystemProperties.set("persist.sys.country", l.getCountry());
12467            SystemProperties.set("persist.sys.localevar", l.getVariant());
12468        }
12469    }
12470
12471    // =========================================================
12472    // LIFETIME MANAGEMENT
12473    // =========================================================
12474
12475    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12476            ProcessRecord TOP_APP, boolean recursed) {
12477        if (mAdjSeq == app.adjSeq) {
12478            // This adjustment has already been computed.  If we are calling
12479            // from the top, we may have already computed our adjustment with
12480            // an earlier hidden adjustment that isn't really for us... if
12481            // so, use the new hidden adjustment.
12482            if (!recursed && app.hidden) {
12483                app.curAdj = hiddenAdj;
12484            }
12485            return app.curAdj;
12486        }
12487
12488        if (app.thread == null) {
12489            app.adjSeq = mAdjSeq;
12490            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12491            return (app.curAdj=EMPTY_APP_ADJ);
12492        }
12493
12494        if (app.maxAdj <= FOREGROUND_APP_ADJ) {
12495            // The max adjustment doesn't allow this app to be anything
12496            // below foreground, so it is not worth doing work for it.
12497            app.adjType = "fixed";
12498            app.adjSeq = mAdjSeq;
12499            app.curRawAdj = app.maxAdj;
12500            app.keeping = true;
12501            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12502            return (app.curAdj=app.maxAdj);
12503        }
12504
12505        final boolean hadForegroundActivities = app.foregroundActivities;
12506
12507        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12508        app.adjSource = null;
12509        app.adjTarget = null;
12510        app.keeping = false;
12511        app.empty = false;
12512        app.hidden = false;
12513        app.foregroundActivities = false;
12514
12515        final int activitiesSize = app.activities.size();
12516
12517        // Determine the importance of the process, starting with most
12518        // important to least, and assign an appropriate OOM adjustment.
12519        int adj;
12520        int schedGroup;
12521        if (app == TOP_APP) {
12522            // The last app on the list is the foreground app.
12523            adj = FOREGROUND_APP_ADJ;
12524            schedGroup = Process.THREAD_GROUP_DEFAULT;
12525            app.adjType = "top-activity";
12526            app.foregroundActivities = true;
12527        } else if (app.instrumentationClass != null) {
12528            // Don't want to kill running instrumentation.
12529            adj = FOREGROUND_APP_ADJ;
12530            schedGroup = Process.THREAD_GROUP_DEFAULT;
12531            app.adjType = "instrumentation";
12532        } else if (app.curReceiver != null ||
12533                (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12534            // An app that is currently receiving a broadcast also
12535            // counts as being in the foreground.
12536            adj = FOREGROUND_APP_ADJ;
12537            schedGroup = Process.THREAD_GROUP_DEFAULT;
12538            app.adjType = "broadcast";
12539        } else if (app.executingServices.size() > 0) {
12540            // An app that is currently executing a service callback also
12541            // counts as being in the foreground.
12542            adj = FOREGROUND_APP_ADJ;
12543            schedGroup = Process.THREAD_GROUP_DEFAULT;
12544            app.adjType = "exec-service";
12545        } else if (activitiesSize > 0) {
12546            // This app is in the background with paused activities.
12547            // We inspect activities to potentially upgrade adjustment further below.
12548            adj = hiddenAdj;
12549            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12550            app.hidden = true;
12551            app.adjType = "bg-activities";
12552        } else {
12553            // A very not-needed process.  If this is lower in the lru list,
12554            // we will push it in to the empty bucket.
12555            adj = hiddenAdj;
12556            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12557            app.hidden = true;
12558            app.empty = true;
12559            app.adjType = "bg-empty";
12560        }
12561
12562        // Examine all activities if not already foreground.
12563        if (!app.foregroundActivities && activitiesSize > 0) {
12564            for (int j = 0; j < activitiesSize; j++) {
12565                final ActivityRecord r = app.activities.get(j);
12566                if (r.visible) {
12567                    // App has a visible activity; only upgrade adjustment.
12568                    if (adj > VISIBLE_APP_ADJ) {
12569                        adj = VISIBLE_APP_ADJ;
12570                        app.adjType = "visible";
12571                    }
12572                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12573                    app.hidden = false;
12574                    app.foregroundActivities = true;
12575                    break;
12576                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
12577                        || r.state == ActivityState.STOPPING) {
12578                    // Only upgrade adjustment.
12579                    if (adj > PERCEPTIBLE_APP_ADJ) {
12580                        adj = PERCEPTIBLE_APP_ADJ;
12581                        app.adjType = "stopping";
12582                    }
12583                    app.foregroundActivities = true;
12584                }
12585            }
12586        }
12587
12588        if (adj > PERCEPTIBLE_APP_ADJ) {
12589            if (app.foregroundServices) {
12590                // The user is aware of this app, so make it visible.
12591                adj = PERCEPTIBLE_APP_ADJ;
12592                app.adjType = "foreground-service";
12593                schedGroup = Process.THREAD_GROUP_DEFAULT;
12594            } else if (app.forcingToForeground != null) {
12595                // The user is aware of this app, so make it visible.
12596                adj = PERCEPTIBLE_APP_ADJ;
12597                app.adjType = "force-foreground";
12598                app.adjSource = app.forcingToForeground;
12599                schedGroup = Process.THREAD_GROUP_DEFAULT;
12600            }
12601        }
12602
12603        if (adj > HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12604            // We don't want to kill the current heavy-weight process.
12605            adj = HEAVY_WEIGHT_APP_ADJ;
12606            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12607            app.adjType = "heavy";
12608        }
12609
12610        if (adj > HOME_APP_ADJ && app == mHomeProcess) {
12611            // This process is hosting what we currently consider to be the
12612            // home app, so we don't want to let it go into the background.
12613            adj = HOME_APP_ADJ;
12614            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12615            app.adjType = "home";
12616        }
12617
12618        //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
12619
12620        // By default, we use the computed adjustment.  It may be changed if
12621        // there are applications dependent on our services or providers, but
12622        // this gives us a baseline and makes sure we don't get into an
12623        // infinite recursion.
12624        app.adjSeq = mAdjSeq;
12625        app.curRawAdj = adj;
12626
12627        if (mBackupTarget != null && app == mBackupTarget.app) {
12628            // If possible we want to avoid killing apps while they're being backed up
12629            if (adj > BACKUP_APP_ADJ) {
12630                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12631                adj = BACKUP_APP_ADJ;
12632                app.adjType = "backup";
12633                app.hidden = false;
12634            }
12635        }
12636
12637        if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
12638                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12639            final long now = SystemClock.uptimeMillis();
12640            // This process is more important if the top activity is
12641            // bound to the service.
12642            Iterator<ServiceRecord> jt = app.services.iterator();
12643            while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
12644                ServiceRecord s = jt.next();
12645                if (s.startRequested) {
12646                    if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12647                        // This service has seen some activity within
12648                        // recent memory, so we will keep its process ahead
12649                        // of the background processes.
12650                        if (adj > SECONDARY_SERVER_ADJ) {
12651                            adj = SECONDARY_SERVER_ADJ;
12652                            app.adjType = "started-services";
12653                            app.hidden = false;
12654                        }
12655                    }
12656                    // If we have let the service slide into the background
12657                    // state, still have some text describing what it is doing
12658                    // even though the service no longer has an impact.
12659                    if (adj > SECONDARY_SERVER_ADJ) {
12660                        app.adjType = "started-bg-services";
12661                    }
12662                    // Don't kill this process because it is doing work; it
12663                    // has said it is doing work.
12664                    app.keeping = true;
12665                }
12666                if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
12667                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12668                    Iterator<ArrayList<ConnectionRecord>> kt
12669                            = s.connections.values().iterator();
12670                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
12671                        ArrayList<ConnectionRecord> clist = kt.next();
12672                        for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
12673                            // XXX should compute this based on the max of
12674                            // all connected clients.
12675                            ConnectionRecord cr = clist.get(i);
12676                            if (cr.binding.client == app) {
12677                                // Binding to ourself is not interesting.
12678                                continue;
12679                            }
12680                            if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12681                                ProcessRecord client = cr.binding.client;
12682                                int myHiddenAdj = hiddenAdj;
12683                                if (myHiddenAdj > client.hiddenAdj) {
12684                                    if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
12685                                        myHiddenAdj = client.hiddenAdj;
12686                                    } else {
12687                                        myHiddenAdj = VISIBLE_APP_ADJ;
12688                                    }
12689                                }
12690                                int clientAdj = computeOomAdjLocked(
12691                                    client, myHiddenAdj, TOP_APP, true);
12692                                if (adj > clientAdj) {
12693                                    adj = clientAdj >= VISIBLE_APP_ADJ
12694                                            ? clientAdj : VISIBLE_APP_ADJ;
12695                                    if (!client.hidden) {
12696                                        app.hidden = false;
12697                                    }
12698                                    if (client.keeping) {
12699                                        app.keeping = true;
12700                                    }
12701                                    app.adjType = "service";
12702                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12703                                            .REASON_SERVICE_IN_USE;
12704                                    app.adjSource = cr.binding.client;
12705                                    app.adjTarget = s.name;
12706                                }
12707                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12708                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12709                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12710                                    }
12711                                }
12712                            }
12713                            ActivityRecord a = cr.activity;
12714                            //if (a != null) {
12715                            //    Slog.i(TAG, "Connection to " + a ": state=" + a.state);
12716                            //}
12717                            if (a != null && adj > FOREGROUND_APP_ADJ &&
12718                                    (a.state == ActivityState.RESUMED
12719                                     || a.state == ActivityState.PAUSING)) {
12720                                adj = FOREGROUND_APP_ADJ;
12721                                schedGroup = Process.THREAD_GROUP_DEFAULT;
12722                                app.hidden = false;
12723                                app.adjType = "service";
12724                                app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12725                                        .REASON_SERVICE_IN_USE;
12726                                app.adjSource = a;
12727                                app.adjTarget = s.name;
12728                            }
12729                        }
12730                    }
12731                }
12732            }
12733
12734            // Finally, if this process has active services running in it, we
12735            // would like to avoid killing it unless it would prevent the current
12736            // application from running.  By default we put the process in
12737            // with the rest of the background processes; as we scan through
12738            // its services we may bump it up from there.
12739            if (adj > hiddenAdj) {
12740                adj = hiddenAdj;
12741                app.hidden = false;
12742                app.adjType = "bg-services";
12743            }
12744        }
12745
12746        if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
12747                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12748            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12749            while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
12750                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12751                ContentProviderRecord cpr = jt.next();
12752                if (cpr.clients.size() != 0) {
12753                    Iterator<ProcessRecord> kt = cpr.clients.iterator();
12754                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
12755                        ProcessRecord client = kt.next();
12756                        if (client == app) {
12757                            // Being our own client is not interesting.
12758                            continue;
12759                        }
12760                        int myHiddenAdj = hiddenAdj;
12761                        if (myHiddenAdj > client.hiddenAdj) {
12762                            if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
12763                                myHiddenAdj = client.hiddenAdj;
12764                            } else {
12765                                myHiddenAdj = FOREGROUND_APP_ADJ;
12766                            }
12767                        }
12768                        int clientAdj = computeOomAdjLocked(
12769                            client, myHiddenAdj, TOP_APP, true);
12770                        if (adj > clientAdj) {
12771                            adj = clientAdj > FOREGROUND_APP_ADJ
12772                                    ? clientAdj : FOREGROUND_APP_ADJ;
12773                            if (!client.hidden) {
12774                                app.hidden = false;
12775                            }
12776                            if (client.keeping) {
12777                                app.keeping = true;
12778                            }
12779                            app.adjType = "provider";
12780                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12781                                    .REASON_PROVIDER_IN_USE;
12782                            app.adjSource = client;
12783                            app.adjTarget = cpr.name;
12784                        }
12785                        if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12786                            schedGroup = Process.THREAD_GROUP_DEFAULT;
12787                        }
12788                    }
12789                }
12790                // If the provider has external (non-framework) process
12791                // dependencies, ensure that its adjustment is at least
12792                // FOREGROUND_APP_ADJ.
12793                if (cpr.externals != 0) {
12794                    if (adj > FOREGROUND_APP_ADJ) {
12795                        adj = FOREGROUND_APP_ADJ;
12796                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12797                        app.hidden = false;
12798                        app.keeping = true;
12799                        app.adjType = "provider";
12800                        app.adjTarget = cpr.name;
12801                    }
12802                }
12803            }
12804        }
12805
12806        app.curRawAdj = adj;
12807
12808        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12809        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12810        if (adj > app.maxAdj) {
12811            adj = app.maxAdj;
12812            if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
12813                schedGroup = Process.THREAD_GROUP_DEFAULT;
12814            }
12815        }
12816        if (adj < HIDDEN_APP_MIN_ADJ) {
12817            app.keeping = true;
12818        }
12819
12820        app.curAdj = adj;
12821        app.curSchedGroup = schedGroup;
12822
12823        if (hadForegroundActivities != app.foregroundActivities) {
12824            mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED,
12825                    app.foregroundActivities ? 1 : 0, 0, app).sendToTarget();
12826        }
12827
12828        return adj;
12829    }
12830
12831    /**
12832     * Ask a given process to GC right now.
12833     */
12834    final void performAppGcLocked(ProcessRecord app) {
12835        try {
12836            app.lastRequestedGc = SystemClock.uptimeMillis();
12837            if (app.thread != null) {
12838                if (app.reportLowMemory) {
12839                    app.reportLowMemory = false;
12840                    app.thread.scheduleLowMemory();
12841                } else {
12842                    app.thread.processInBackground();
12843                }
12844            }
12845        } catch (Exception e) {
12846            // whatever.
12847        }
12848    }
12849
12850    /**
12851     * Returns true if things are idle enough to perform GCs.
12852     */
12853    private final boolean canGcNowLocked() {
12854        return mParallelBroadcasts.size() == 0
12855                && mOrderedBroadcasts.size() == 0
12856                && (mSleeping || (mMainStack.mResumedActivity != null &&
12857                        mMainStack.mResumedActivity.idle));
12858    }
12859
12860    /**
12861     * Perform GCs on all processes that are waiting for it, but only
12862     * if things are idle.
12863     */
12864    final void performAppGcsLocked() {
12865        final int N = mProcessesToGc.size();
12866        if (N <= 0) {
12867            return;
12868        }
12869        if (canGcNowLocked()) {
12870            while (mProcessesToGc.size() > 0) {
12871                ProcessRecord proc = mProcessesToGc.remove(0);
12872                if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
12873                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12874                            <= SystemClock.uptimeMillis()) {
12875                        // To avoid spamming the system, we will GC processes one
12876                        // at a time, waiting a few seconds between each.
12877                        performAppGcLocked(proc);
12878                        scheduleAppGcsLocked();
12879                        return;
12880                    } else {
12881                        // It hasn't been long enough since we last GCed this
12882                        // process...  put it in the list to wait for its time.
12883                        addProcessToGcListLocked(proc);
12884                        break;
12885                    }
12886                }
12887            }
12888
12889            scheduleAppGcsLocked();
12890        }
12891    }
12892
12893    /**
12894     * If all looks good, perform GCs on all processes waiting for them.
12895     */
12896    final void performAppGcsIfAppropriateLocked() {
12897        if (canGcNowLocked()) {
12898            performAppGcsLocked();
12899            return;
12900        }
12901        // Still not idle, wait some more.
12902        scheduleAppGcsLocked();
12903    }
12904
12905    /**
12906     * Schedule the execution of all pending app GCs.
12907     */
12908    final void scheduleAppGcsLocked() {
12909        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
12910
12911        if (mProcessesToGc.size() > 0) {
12912            // Schedule a GC for the time to the next process.
12913            ProcessRecord proc = mProcessesToGc.get(0);
12914            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12915
12916            long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
12917            long now = SystemClock.uptimeMillis();
12918            if (when < (now+GC_TIMEOUT)) {
12919                when = now + GC_TIMEOUT;
12920            }
12921            mHandler.sendMessageAtTime(msg, when);
12922        }
12923    }
12924
12925    /**
12926     * Add a process to the array of processes waiting to be GCed.  Keeps the
12927     * list in sorted order by the last GC time.  The process can't already be
12928     * on the list.
12929     */
12930    final void addProcessToGcListLocked(ProcessRecord proc) {
12931        boolean added = false;
12932        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12933            if (mProcessesToGc.get(i).lastRequestedGc <
12934                    proc.lastRequestedGc) {
12935                added = true;
12936                mProcessesToGc.add(i+1, proc);
12937                break;
12938            }
12939        }
12940        if (!added) {
12941            mProcessesToGc.add(0, proc);
12942        }
12943    }
12944
12945    /**
12946     * Set up to ask a process to GC itself.  This will either do it
12947     * immediately, or put it on the list of processes to gc the next
12948     * time things are idle.
12949     */
12950    final void scheduleAppGcLocked(ProcessRecord app) {
12951        long now = SystemClock.uptimeMillis();
12952        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
12953            return;
12954        }
12955        if (!mProcessesToGc.contains(app)) {
12956            addProcessToGcListLocked(app);
12957            scheduleAppGcsLocked();
12958        }
12959    }
12960
12961    final void checkExcessivePowerUsageLocked(boolean doKills) {
12962        updateCpuStatsNow();
12963
12964        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12965        boolean doWakeKills = doKills;
12966        boolean doCpuKills = doKills;
12967        if (mLastPowerCheckRealtime == 0) {
12968            doWakeKills = false;
12969        }
12970        if (mLastPowerCheckUptime == 0) {
12971            doCpuKills = false;
12972        }
12973        if (stats.isScreenOn()) {
12974            doWakeKills = false;
12975        }
12976        final long curRealtime = SystemClock.elapsedRealtime();
12977        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12978        final long curUptime = SystemClock.uptimeMillis();
12979        final long uptimeSince = curUptime - mLastPowerCheckUptime;
12980        mLastPowerCheckRealtime = curRealtime;
12981        mLastPowerCheckUptime = curUptime;
12982        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12983            doWakeKills = false;
12984        }
12985        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12986            doCpuKills = false;
12987        }
12988        int i = mLruProcesses.size();
12989        while (i > 0) {
12990            i--;
12991            ProcessRecord app = mLruProcesses.get(i);
12992            if (!app.keeping) {
12993                long wtime;
12994                synchronized (stats) {
12995                    wtime = stats.getProcessWakeTime(app.info.uid,
12996                            app.pid, curRealtime);
12997                }
12998                long wtimeUsed = wtime - app.lastWakeTime;
12999                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13000                if (DEBUG_POWER) {
13001                    StringBuilder sb = new StringBuilder(128);
13002                    sb.append("Wake for ");
13003                    app.toShortString(sb);
13004                    sb.append(": over ");
13005                    TimeUtils.formatDuration(realtimeSince, sb);
13006                    sb.append(" used ");
13007                    TimeUtils.formatDuration(wtimeUsed, sb);
13008                    sb.append(" (");
13009                    sb.append((wtimeUsed*100)/realtimeSince);
13010                    sb.append("%)");
13011                    Slog.i(TAG, sb.toString());
13012                    sb.setLength(0);
13013                    sb.append("CPU for ");
13014                    app.toShortString(sb);
13015                    sb.append(": over ");
13016                    TimeUtils.formatDuration(uptimeSince, sb);
13017                    sb.append(" used ");
13018                    TimeUtils.formatDuration(cputimeUsed, sb);
13019                    sb.append(" (");
13020                    sb.append((cputimeUsed*100)/uptimeSince);
13021                    sb.append("%)");
13022                    Slog.i(TAG, sb.toString());
13023                }
13024                // If a process has held a wake lock for more
13025                // than 50% of the time during this period,
13026                // that sounds pad.  Kill!
13027                if (doWakeKills && realtimeSince > 0
13028                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13029                    synchronized (stats) {
13030                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13031                                realtimeSince, wtimeUsed);
13032                    }
13033                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13034                            + " (pid " + app.pid + "): held " + wtimeUsed
13035                            + " during " + realtimeSince);
13036                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13037                            app.processName, app.setAdj, "excessive wake lock");
13038                    Process.killProcessQuiet(app.pid);
13039                } else if (doCpuKills && uptimeSince > 0
13040                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13041                    synchronized (stats) {
13042                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13043                                uptimeSince, cputimeUsed);
13044                    }
13045                    Slog.w(TAG, "Excessive CPU in " + app.processName
13046                            + " (pid " + app.pid + "): used " + cputimeUsed
13047                            + " during " + uptimeSince);
13048                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13049                            app.processName, app.setAdj, "excessive cpu");
13050                    Process.killProcessQuiet(app.pid);
13051                } else {
13052                    app.lastWakeTime = wtime;
13053                    app.lastCpuTime = app.curCpuTime;
13054                }
13055            }
13056        }
13057    }
13058
13059    private final boolean updateOomAdjLocked(
13060            ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
13061        app.hiddenAdj = hiddenAdj;
13062
13063        if (app.thread == null) {
13064            return true;
13065        }
13066
13067        boolean success = true;
13068
13069        final boolean wasKeeping = app.keeping;
13070
13071        int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
13072
13073        if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
13074            if (app.curRawAdj != app.setRawAdj) {
13075                if (app.curRawAdj > FOREGROUND_APP_ADJ
13076                        && app.setRawAdj <= FOREGROUND_APP_ADJ) {
13077                    // If this app is transitioning from foreground to
13078                    // non-foreground, have it do a gc.
13079                    scheduleAppGcLocked(app);
13080                } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
13081                        && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
13082                    // Likewise do a gc when an app is moving in to the
13083                    // background (such as a service stopping).
13084                    scheduleAppGcLocked(app);
13085                }
13086
13087                if (wasKeeping && !app.keeping) {
13088                    // This app is no longer something we want to keep.  Note
13089                    // its current wake lock time to later know to kill it if
13090                    // it is not behaving well.
13091                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13092                    synchronized (stats) {
13093                        app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13094                                app.pid, SystemClock.elapsedRealtime());
13095                    }
13096                    app.lastCpuTime = app.curCpuTime;
13097                }
13098
13099                app.setRawAdj = app.curRawAdj;
13100            }
13101            if (adj != app.setAdj) {
13102                if (Process.setOomAdj(app.pid, adj)) {
13103                    if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13104                        TAG, "Set app " + app.processName +
13105                        " oom adj to " + adj);
13106                    app.setAdj = adj;
13107                } else {
13108                    success = false;
13109                }
13110            }
13111            if (app.setSchedGroup != app.curSchedGroup) {
13112                app.setSchedGroup = app.curSchedGroup;
13113                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13114                        "Setting process group of " + app.processName
13115                        + " to " + app.curSchedGroup);
13116                if (app.waitingToKill != null &&
13117                        app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13118                    Slog.i(TAG, "Killing " + app + ": " + app.waitingToKill);
13119                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13120                            app.processName, app.setAdj, app.waitingToKill);
13121                    Process.killProcessQuiet(app.pid);
13122                } else {
13123                    if (true) {
13124                        long oldId = Binder.clearCallingIdentity();
13125                        try {
13126                            Process.setProcessGroup(app.pid, app.curSchedGroup);
13127                        } catch (Exception e) {
13128                            Slog.w(TAG, "Failed setting process group of " + app.pid
13129                                    + " to " + app.curSchedGroup);
13130                            e.printStackTrace();
13131                        } finally {
13132                            Binder.restoreCallingIdentity(oldId);
13133                        }
13134                    }
13135                    if (false) {
13136                        if (app.thread != null) {
13137                            try {
13138                                app.thread.setSchedulingGroup(app.curSchedGroup);
13139                            } catch (RemoteException e) {
13140                            }
13141                        }
13142                    }
13143                }
13144            }
13145        }
13146
13147        return success;
13148    }
13149
13150    private final ActivityRecord resumedAppLocked() {
13151        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13152        if (resumedActivity == null || resumedActivity.app == null) {
13153            resumedActivity = mMainStack.mPausingActivity;
13154            if (resumedActivity == null || resumedActivity.app == null) {
13155                resumedActivity = mMainStack.topRunningActivityLocked(null);
13156            }
13157        }
13158        return resumedActivity;
13159    }
13160
13161    private final boolean updateOomAdjLocked(ProcessRecord app) {
13162        final ActivityRecord TOP_ACT = resumedAppLocked();
13163        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13164        int curAdj = app.curAdj;
13165        final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13166            && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13167
13168        mAdjSeq++;
13169
13170        final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
13171        if (res) {
13172            final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13173                && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13174            if (nowHidden != wasHidden) {
13175                // Changed to/from hidden state, so apps after it in the LRU
13176                // list may also be changed.
13177                updateOomAdjLocked();
13178            }
13179        }
13180        return res;
13181    }
13182
13183    final boolean updateOomAdjLocked() {
13184        boolean didOomAdj = true;
13185        final ActivityRecord TOP_ACT = resumedAppLocked();
13186        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13187
13188        if (false) {
13189            RuntimeException e = new RuntimeException();
13190            e.fillInStackTrace();
13191            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13192        }
13193
13194        mAdjSeq++;
13195
13196        // Let's determine how many processes we have running vs.
13197        // how many slots we have for background processes; we may want
13198        // to put multiple processes in a slot of there are enough of
13199        // them.
13200        int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
13201        int factor = (mLruProcesses.size()-4)/numSlots;
13202        if (factor < 1) factor = 1;
13203        int step = 0;
13204        int numHidden = 0;
13205
13206        // First try updating the OOM adjustment for each of the
13207        // application processes based on their current state.
13208        int i = mLruProcesses.size();
13209        int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
13210        while (i > 0) {
13211            i--;
13212            ProcessRecord app = mLruProcesses.get(i);
13213            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13214            if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
13215                if (curHiddenAdj < EMPTY_APP_ADJ
13216                    && app.curAdj == curHiddenAdj) {
13217                    step++;
13218                    if (step >= factor) {
13219                        step = 0;
13220                        curHiddenAdj++;
13221                    }
13222                }
13223                if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
13224                    if (!app.killedBackground) {
13225                        numHidden++;
13226                        if (numHidden > MAX_HIDDEN_APPS) {
13227                            Slog.i(TAG, "No longer want " + app.processName
13228                                    + " (pid " + app.pid + "): hidden #" + numHidden);
13229                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13230                                    app.processName, app.setAdj, "too many background");
13231                            app.killedBackground = true;
13232                            Process.killProcessQuiet(app.pid);
13233                        }
13234                    }
13235                }
13236            } else {
13237                didOomAdj = false;
13238            }
13239        }
13240
13241        // If we return false, we will fall back on killing processes to
13242        // have a fixed limit.  Do this if a limit has been requested; else
13243        // only return false if one of the adjustments failed.
13244        return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
13245    }
13246
13247    final void trimApplications() {
13248        synchronized (this) {
13249            int i;
13250
13251            // First remove any unused application processes whose package
13252            // has been removed.
13253            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13254                final ProcessRecord app = mRemovedProcesses.get(i);
13255                if (app.activities.size() == 0
13256                        && app.curReceiver == null && app.services.size() == 0) {
13257                    Slog.i(
13258                        TAG, "Exiting empty application process "
13259                        + app.processName + " ("
13260                        + (app.thread != null ? app.thread.asBinder() : null)
13261                        + ")\n");
13262                    if (app.pid > 0 && app.pid != MY_PID) {
13263                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13264                                app.processName, app.setAdj, "empty");
13265                        Process.killProcessQuiet(app.pid);
13266                    } else {
13267                        try {
13268                            app.thread.scheduleExit();
13269                        } catch (Exception e) {
13270                            // Ignore exceptions.
13271                        }
13272                    }
13273                    cleanUpApplicationRecordLocked(app, false, -1);
13274                    mRemovedProcesses.remove(i);
13275
13276                    if (app.persistent) {
13277                        if (app.persistent) {
13278                            addAppLocked(app.info);
13279                        }
13280                    }
13281                }
13282            }
13283
13284            // Now try updating the OOM adjustment for each of the
13285            // application processes based on their current state.
13286            // If the setOomAdj() API is not supported, then go with our
13287            // back-up plan...
13288            if (!updateOomAdjLocked()) {
13289
13290                // Count how many processes are running services.
13291                int numServiceProcs = 0;
13292                for (i=mLruProcesses.size()-1; i>=0; i--) {
13293                    final ProcessRecord app = mLruProcesses.get(i);
13294
13295                    if (app.persistent || app.services.size() != 0
13296                            || app.curReceiver != null) {
13297                        // Don't count processes holding services against our
13298                        // maximum process count.
13299                        if (localLOGV) Slog.v(
13300                            TAG, "Not trimming app " + app + " with services: "
13301                            + app.services);
13302                        numServiceProcs++;
13303                    }
13304                }
13305
13306                int curMaxProcs = mProcessLimit;
13307                if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
13308                if (mAlwaysFinishActivities) {
13309                    curMaxProcs = 1;
13310                }
13311                curMaxProcs += numServiceProcs;
13312
13313                // Quit as many processes as we can to get down to the desired
13314                // process count.  First remove any processes that no longer
13315                // have activites running in them.
13316                for (   i=0;
13317                        i<mLruProcesses.size()
13318                            && mLruProcesses.size() > curMaxProcs;
13319                        i++) {
13320                    final ProcessRecord app = mLruProcesses.get(i);
13321                    // Quit an application only if it is not currently
13322                    // running any activities.
13323                    if (!app.persistent && app.activities.size() == 0
13324                            && app.curReceiver == null && app.services.size() == 0) {
13325                        Slog.i(
13326                            TAG, "Exiting empty application process "
13327                            + app.processName + " ("
13328                            + (app.thread != null ? app.thread.asBinder() : null)
13329                            + ")\n");
13330                        if (app.pid > 0 && app.pid != MY_PID) {
13331                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13332                                    app.processName, app.setAdj, "empty");
13333                            Process.killProcessQuiet(app.pid);
13334                        } else {
13335                            try {
13336                                app.thread.scheduleExit();
13337                            } catch (Exception e) {
13338                                // Ignore exceptions.
13339                            }
13340                        }
13341                        // todo: For now we assume the application is not buggy
13342                        // or evil, and will quit as a result of our request.
13343                        // Eventually we need to drive this off of the death
13344                        // notification, and kill the process if it takes too long.
13345                        cleanUpApplicationRecordLocked(app, false, i);
13346                        i--;
13347                    }
13348                }
13349
13350                // If we still have too many processes, now from the least
13351                // recently used process we start finishing activities.
13352                if (false) Slog.v(
13353                    TAG, "*** NOW HAVE " + mLruProcesses.size() +
13354                    " of " + curMaxProcs + " processes");
13355                for (   i=0;
13356                        i<mLruProcesses.size()
13357                            && mLruProcesses.size() > curMaxProcs;
13358                        i++) {
13359                    final ProcessRecord app = mLruProcesses.get(i);
13360                    // Quit the application only if we have a state saved for
13361                    // all of its activities.
13362                    boolean canQuit = !app.persistent && app.curReceiver == null
13363                        && app.services.size() == 0;
13364                    int NUMA = app.activities.size();
13365                    int j;
13366                    if (false) Slog.v(
13367                        TAG, "Looking to quit " + app.processName);
13368                    for (j=0; j<NUMA && canQuit; j++) {
13369                        ActivityRecord r = app.activities.get(j);
13370                        if (false) Slog.v(
13371                            TAG, "  " + r.intent.getComponent().flattenToShortString()
13372                            + ": frozen=" + r.haveState + ", visible=" + r.visible);
13373                        canQuit = (r.haveState || !r.stateNotNeeded)
13374                                && !r.visible && r.stopped;
13375                    }
13376                    if (canQuit) {
13377                        // Finish all of the activities, and then the app itself.
13378                        for (j=0; j<NUMA; j++) {
13379                            ActivityRecord r = app.activities.get(j);
13380                            if (!r.finishing) {
13381                                r.stack.destroyActivityLocked(r, false);
13382                            }
13383                            r.resultTo = null;
13384                        }
13385                        Slog.i(TAG, "Exiting application process "
13386                              + app.processName + " ("
13387                              + (app.thread != null ? app.thread.asBinder() : null)
13388                              + ")\n");
13389                        if (app.pid > 0 && app.pid != MY_PID) {
13390                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13391                                    app.processName, app.setAdj, "old background");
13392                            Process.killProcessQuiet(app.pid);
13393                        } else {
13394                            try {
13395                                app.thread.scheduleExit();
13396                            } catch (Exception e) {
13397                                // Ignore exceptions.
13398                            }
13399                        }
13400                        // todo: For now we assume the application is not buggy
13401                        // or evil, and will quit as a result of our request.
13402                        // Eventually we need to drive this off of the death
13403                        // notification, and kill the process if it takes too long.
13404                        cleanUpApplicationRecordLocked(app, false, i);
13405                        i--;
13406                        //dump();
13407                    }
13408                }
13409
13410            }
13411
13412            int curMaxActivities = MAX_ACTIVITIES;
13413            if (mAlwaysFinishActivities) {
13414                curMaxActivities = 1;
13415            }
13416
13417            // Finally, if there are too many activities now running, try to
13418            // finish as many as we can to get back down to the limit.
13419            for (   i=0;
13420                    i<mMainStack.mLRUActivities.size()
13421                        && mMainStack.mLRUActivities.size() > curMaxActivities;
13422                    i++) {
13423                final ActivityRecord r
13424                    = (ActivityRecord)mMainStack.mLRUActivities.get(i);
13425
13426                // We can finish this one if we have its icicle saved and
13427                // it is not persistent.
13428                if ((r.haveState || !r.stateNotNeeded) && !r.visible
13429                        && r.stopped && !r.finishing) {
13430                    final int origSize = mMainStack.mLRUActivities.size();
13431                    r.stack.destroyActivityLocked(r, true);
13432
13433                    // This will remove it from the LRU list, so keep
13434                    // our index at the same value.  Note that this check to
13435                    // see if the size changes is just paranoia -- if
13436                    // something unexpected happens, we don't want to end up
13437                    // in an infinite loop.
13438                    if (origSize > mMainStack.mLRUActivities.size()) {
13439                        i--;
13440                    }
13441                }
13442            }
13443        }
13444    }
13445
13446    /** This method sends the specified signal to each of the persistent apps */
13447    public void signalPersistentProcesses(int sig) throws RemoteException {
13448        if (sig != Process.SIGNAL_USR1) {
13449            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13450        }
13451
13452        synchronized (this) {
13453            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13454                    != PackageManager.PERMISSION_GRANTED) {
13455                throw new SecurityException("Requires permission "
13456                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13457            }
13458
13459            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13460                ProcessRecord r = mLruProcesses.get(i);
13461                if (r.thread != null && r.persistent) {
13462                    Process.sendSignal(r.pid, sig);
13463                }
13464            }
13465        }
13466    }
13467
13468    public boolean profileControl(String process, boolean start,
13469            String path, ParcelFileDescriptor fd) throws RemoteException {
13470
13471        try {
13472            synchronized (this) {
13473                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13474                // its own permission.
13475                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13476                        != PackageManager.PERMISSION_GRANTED) {
13477                    throw new SecurityException("Requires permission "
13478                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13479                }
13480
13481                if (start && fd == null) {
13482                    throw new IllegalArgumentException("null fd");
13483                }
13484
13485                ProcessRecord proc = null;
13486                try {
13487                    int pid = Integer.parseInt(process);
13488                    synchronized (mPidsSelfLocked) {
13489                        proc = mPidsSelfLocked.get(pid);
13490                    }
13491                } catch (NumberFormatException e) {
13492                }
13493
13494                if (proc == null) {
13495                    HashMap<String, SparseArray<ProcessRecord>> all
13496                            = mProcessNames.getMap();
13497                    SparseArray<ProcessRecord> procs = all.get(process);
13498                    if (procs != null && procs.size() > 0) {
13499                        proc = procs.valueAt(0);
13500                    }
13501                }
13502
13503                if (proc == null || proc.thread == null) {
13504                    throw new IllegalArgumentException("Unknown process: " + process);
13505                }
13506
13507                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13508                if (!isDebuggable) {
13509                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13510                        throw new SecurityException("Process not debuggable: " + proc);
13511                    }
13512                }
13513
13514                proc.thread.profilerControl(start, path, fd);
13515                fd = null;
13516                return true;
13517            }
13518        } catch (RemoteException e) {
13519            throw new IllegalStateException("Process disappeared");
13520        } finally {
13521            if (fd != null) {
13522                try {
13523                    fd.close();
13524                } catch (IOException e) {
13525                }
13526            }
13527        }
13528    }
13529
13530    public boolean dumpHeap(String process, boolean managed,
13531            String path, ParcelFileDescriptor fd) throws RemoteException {
13532
13533        try {
13534            synchronized (this) {
13535                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13536                // its own permission (same as profileControl).
13537                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13538                        != PackageManager.PERMISSION_GRANTED) {
13539                    throw new SecurityException("Requires permission "
13540                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13541                }
13542
13543                if (fd == null) {
13544                    throw new IllegalArgumentException("null fd");
13545                }
13546
13547                ProcessRecord proc = null;
13548                try {
13549                    int pid = Integer.parseInt(process);
13550                    synchronized (mPidsSelfLocked) {
13551                        proc = mPidsSelfLocked.get(pid);
13552                    }
13553                } catch (NumberFormatException e) {
13554                }
13555
13556                if (proc == null) {
13557                    HashMap<String, SparseArray<ProcessRecord>> all
13558                            = mProcessNames.getMap();
13559                    SparseArray<ProcessRecord> procs = all.get(process);
13560                    if (procs != null && procs.size() > 0) {
13561                        proc = procs.valueAt(0);
13562                    }
13563                }
13564
13565                if (proc == null || proc.thread == null) {
13566                    throw new IllegalArgumentException("Unknown process: " + process);
13567                }
13568
13569                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13570                if (!isDebuggable) {
13571                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13572                        throw new SecurityException("Process not debuggable: " + proc);
13573                    }
13574                }
13575
13576                proc.thread.dumpHeap(managed, path, fd);
13577                fd = null;
13578                return true;
13579            }
13580        } catch (RemoteException e) {
13581            throw new IllegalStateException("Process disappeared");
13582        } finally {
13583            if (fd != null) {
13584                try {
13585                    fd.close();
13586                } catch (IOException e) {
13587                }
13588            }
13589        }
13590    }
13591
13592    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13593    public void monitor() {
13594        synchronized (this) { }
13595    }
13596
13597    public void onCoreSettingsChange(Bundle settings) {
13598        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13599            ProcessRecord processRecord = mLruProcesses.get(i);
13600            try {
13601                if (processRecord.thread != null) {
13602                    processRecord.thread.setCoreSettings(settings);
13603                }
13604            } catch (RemoteException re) {
13605                /* ignore */
13606            }
13607        }
13608    }
13609
13610    // Multi-user methods
13611
13612    public boolean switchUser(int userid) {
13613        // TODO
13614        return true;
13615    }
13616}
13617