ActivityManagerService.java revision e1dfcb7ab01fb991079ec1f70f75281a0ca9073e
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.wm.WindowManagerService;
29
30import dalvik.system.Zygote;
31
32import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityManagerNative;
35import android.app.ActivityThread;
36import android.app.AlertDialog;
37import android.app.AppGlobals;
38import android.app.ApplicationErrorReport;
39import android.app.Dialog;
40import android.app.IActivityController;
41import android.app.IActivityWatcher;
42import android.app.IApplicationThread;
43import android.app.IInstrumentationWatcher;
44import android.app.INotificationManager;
45import android.app.IProcessObserver;
46import android.app.IServiceConnection;
47import android.app.IThumbnailReceiver;
48import android.app.IThumbnailRetriever;
49import android.app.Instrumentation;
50import android.app.Notification;
51import android.app.NotificationManager;
52import android.app.PendingIntent;
53import android.app.Service;
54import android.app.backup.IBackupManager;
55import android.content.ActivityNotFoundException;
56import android.content.BroadcastReceiver;
57import android.content.ComponentName;
58import android.content.ContentResolver;
59import android.content.Context;
60import android.content.DialogInterface;
61import android.content.Intent;
62import android.content.IntentFilter;
63import android.content.IIntentReceiver;
64import android.content.IIntentSender;
65import android.content.IntentSender;
66import android.content.pm.ActivityInfo;
67import android.content.pm.ApplicationInfo;
68import android.content.pm.ConfigurationInfo;
69import android.content.pm.IPackageDataObserver;
70import android.content.pm.IPackageManager;
71import android.content.pm.InstrumentationInfo;
72import android.content.pm.PackageInfo;
73import android.content.pm.PackageManager;
74import android.content.pm.PathPermission;
75import android.content.pm.ProviderInfo;
76import android.content.pm.ResolveInfo;
77import android.content.pm.ServiceInfo;
78import android.content.pm.PackageManager.NameNotFoundException;
79import android.content.res.CompatibilityInfo;
80import android.content.res.Configuration;
81import android.graphics.Bitmap;
82import android.net.Proxy;
83import android.net.ProxyProperties;
84import android.net.Uri;
85import android.os.Binder;
86import android.os.Build;
87import android.os.Bundle;
88import android.os.Debug;
89import android.os.DropBoxManager;
90import android.os.Environment;
91import android.os.FileObserver;
92import android.os.FileUtils;
93import android.os.Handler;
94import android.os.IBinder;
95import android.os.IPermissionController;
96import android.os.Looper;
97import android.os.Message;
98import android.os.Parcel;
99import android.os.ParcelFileDescriptor;
100import android.os.Process;
101import android.os.RemoteCallbackList;
102import android.os.RemoteException;
103import android.os.ServiceManager;
104import android.os.StrictMode;
105import android.os.SystemClock;
106import android.os.SystemProperties;
107import android.provider.Settings;
108import android.util.EventLog;
109import android.util.Slog;
110import android.util.Log;
111import android.util.PrintWriterPrinter;
112import android.util.SparseArray;
113import android.util.TimeUtils;
114import android.view.Gravity;
115import android.view.LayoutInflater;
116import android.view.View;
117import android.view.WindowManager;
118import android.view.WindowManagerPolicy;
119
120import java.io.BufferedInputStream;
121import java.io.BufferedOutputStream;
122import java.io.DataInputStream;
123import java.io.DataOutputStream;
124import java.io.File;
125import java.io.FileDescriptor;
126import java.io.FileInputStream;
127import java.io.FileNotFoundException;
128import java.io.FileOutputStream;
129import java.io.IOException;
130import java.io.InputStreamReader;
131import java.io.PrintWriter;
132import java.lang.IllegalStateException;
133import java.lang.ref.WeakReference;
134import java.util.ArrayList;
135import java.util.Collections;
136import java.util.Comparator;
137import java.util.HashMap;
138import java.util.HashSet;
139import java.util.Iterator;
140import java.util.List;
141import java.util.Locale;
142import java.util.Map;
143import java.util.Set;
144import java.util.concurrent.atomic.AtomicBoolean;
145import java.util.concurrent.atomic.AtomicLong;
146
147public final class ActivityManagerService extends ActivityManagerNative
148        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
149    static final String TAG = "ActivityManager";
150    static final boolean DEBUG = false;
151    static final boolean localLOGV = DEBUG;
152    static final boolean DEBUG_SWITCH = localLOGV || false;
153    static final boolean DEBUG_TASKS = localLOGV || false;
154    static final boolean DEBUG_PAUSE = localLOGV || false;
155    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
156    static final boolean DEBUG_TRANSITION = localLOGV || false;
157    static final boolean DEBUG_BROADCAST = localLOGV || false;
158    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
159    static final boolean DEBUG_SERVICE = localLOGV || false;
160    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
161    static final boolean DEBUG_VISBILITY = localLOGV || false;
162    static final boolean DEBUG_PROCESSES = localLOGV || false;
163    static final boolean DEBUG_PROVIDER = localLOGV || false;
164    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
165    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
166    static final boolean DEBUG_RESULTS = localLOGV || false;
167    static final boolean DEBUG_BACKUP = localLOGV || true;
168    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
169    static final boolean DEBUG_POWER = localLOGV || false;
170    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
171    static final boolean VALIDATE_TOKENS = false;
172    static final boolean SHOW_ACTIVITY_START_TIME = true;
173
174    // Control over CPU and battery monitoring.
175    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
176    static final boolean MONITOR_CPU_USAGE = true;
177    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
178    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
179    static final boolean MONITOR_THREAD_CPU_USAGE = false;
180
181    // The flags that are set for all calls we make to the package manager.
182    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
183
184    private static final String SYSTEM_SECURE = "ro.secure";
185    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
186
187    // This is the maximum number of application processes we would like
188    // to have running.  Due to the asynchronous nature of things, we can
189    // temporarily go beyond this limit.
190    static final int MAX_PROCESSES = 2;
191
192    // Set to false to leave processes running indefinitely, relying on
193    // the kernel killing them as resources are required.
194    static final boolean ENFORCE_PROCESS_LIMIT = false;
195
196    // This is the maximum number of activities that we would like to have
197    // running at a given time.
198    static final int MAX_ACTIVITIES = 20;
199
200    // Maximum number of recent tasks that we can remember.
201    static final int MAX_RECENT_TASKS = 20;
202
203    // Amount of time after a call to stopAppSwitches() during which we will
204    // prevent further untrusted switches from happening.
205    static final long APP_SWITCH_DELAY_TIME = 5*1000;
206
207    // How long we wait for a launched process to attach to the activity manager
208    // before we decide it's never going to come up for real.
209    static final int PROC_START_TIMEOUT = 10*1000;
210
211    // How long to wait after going idle before forcing apps to GC.
212    static final int GC_TIMEOUT = 5*1000;
213
214    // The minimum amount of time between successive GC requests for a process.
215    static final int GC_MIN_INTERVAL = 60*1000;
216
217    // The rate at which we check for apps using excessive power -- 15 mins.
218    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
219
220    // The minimum sample duration we will allow before deciding we have
221    // enough data on wake locks to start killing things.
222    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
223
224    // The minimum sample duration we will allow before deciding we have
225    // enough data on CPU usage to start killing things.
226    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
227
228    // How long we allow a receiver to run before giving up on it.
229    static final int BROADCAST_TIMEOUT = 10*1000;
230
231    // How long we wait for a service to finish executing.
232    static final int SERVICE_TIMEOUT = 20*1000;
233
234    // How long a service needs to be running until restarting its process
235    // is no longer considered to be a relaunch of the service.
236    static final int SERVICE_RESTART_DURATION = 5*1000;
237
238    // How long a service needs to be running until it will start back at
239    // SERVICE_RESTART_DURATION after being killed.
240    static final int SERVICE_RESET_RUN_DURATION = 60*1000;
241
242    // Multiplying factor to increase restart duration time by, for each time
243    // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
244    static final int SERVICE_RESTART_DURATION_FACTOR = 4;
245
246    // The minimum amount of time between restarting services that we allow.
247    // That is, when multiple services are restarting, we won't allow each
248    // to restart less than this amount of time from the last one.
249    static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
250
251    // Maximum amount of time for there to be no activity on a service before
252    // we consider it non-essential and allow its process to go on the
253    // LRU background list.
254    static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
255
256    // How long we wait until we timeout on key dispatching.
257    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
258
259    // The minimum time we allow between crashes, for us to consider this
260    // application to be bad and stop and its services and reject broadcasts.
261    static final int MIN_CRASH_INTERVAL = 60*1000;
262
263    // How long we wait until we timeout on key dispatching during instrumentation.
264    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
265
266    // OOM adjustments for processes in various states:
267
268    // This is a process without anything currently running in it.  Definitely
269    // the first to go! Value set in system/rootdir/init.rc on startup.
270    // This value is initalized in the constructor, careful when refering to
271    // this static variable externally.
272    static final int EMPTY_APP_ADJ;
273
274    // This is a process only hosting activities that are not visible,
275    // so it can be killed without any disruption. Value set in
276    // system/rootdir/init.rc on startup.
277    static final int HIDDEN_APP_MAX_ADJ;
278    static int HIDDEN_APP_MIN_ADJ;
279
280    // This is a process holding the home application -- we want to try
281    // avoiding killing it, even if it would normally be in the background,
282    // because the user interacts with it so much.
283    static final int HOME_APP_ADJ;
284
285    // This is a process currently hosting a backup operation.  Killing it
286    // is not entirely fatal but is generally a bad idea.
287    static final int BACKUP_APP_ADJ;
288
289    // This is a process holding a secondary server -- killing it will not
290    // have much of an impact as far as the user is concerned. Value set in
291    // system/rootdir/init.rc on startup.
292    static final int SECONDARY_SERVER_ADJ;
293
294    // This is a process with a heavy-weight application.  It is in the
295    // background, but we want to try to avoid killing it.  Value set in
296    // system/rootdir/init.rc on startup.
297    static final int HEAVY_WEIGHT_APP_ADJ;
298
299    // This is a process only hosting components that are perceptible to the
300    // user, and we really want to avoid killing them, but they are not
301    // immediately visible. An example is background music playback.  Value set in
302    // system/rootdir/init.rc on startup.
303    static final int PERCEPTIBLE_APP_ADJ;
304
305    // This is a process only hosting activities that are visible to the
306    // user, so we'd prefer they don't disappear. Value set in
307    // system/rootdir/init.rc on startup.
308    static final int VISIBLE_APP_ADJ;
309
310    // This is the process running the current foreground app.  We'd really
311    // rather not kill it! Value set in system/rootdir/init.rc on startup.
312    static final int FOREGROUND_APP_ADJ;
313
314    // This is a process running a core server, such as telephony.  Definitely
315    // don't want to kill it, but doing so is not completely fatal.
316    static final int CORE_SERVER_ADJ = -12;
317
318    // The system process runs at the default adjustment.
319    static final int SYSTEM_ADJ = -16;
320
321    // Memory pages are 4K.
322    static final int PAGE_SIZE = 4*1024;
323
324    // Corresponding memory levels for above adjustments.
325    static final int EMPTY_APP_MEM;
326    static final int HIDDEN_APP_MEM;
327    static final int HOME_APP_MEM;
328    static final int BACKUP_APP_MEM;
329    static final int SECONDARY_SERVER_MEM;
330    static final int HEAVY_WEIGHT_APP_MEM;
331    static final int PERCEPTIBLE_APP_MEM;
332    static final int VISIBLE_APP_MEM;
333    static final int FOREGROUND_APP_MEM;
334
335    // The minimum number of hidden apps we want to be able to keep around,
336    // without empty apps being able to push them out of memory.
337    static final int MIN_HIDDEN_APPS = 2;
338
339    // The maximum number of hidden processes we will keep around before
340    // killing them; this is just a control to not let us go too crazy with
341    // keeping around processes on devices with large amounts of RAM.
342    static final int MAX_HIDDEN_APPS = 15;
343
344    // We put empty content processes after any hidden processes that have
345    // been idle for less than 15 seconds.
346    static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
347
348    // We put empty content processes after any hidden processes that have
349    // been idle for less than 120 seconds.
350    static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
351
352    static int getIntProp(String name, boolean allowZero) {
353        String str = SystemProperties.get(name);
354        if (str == null) {
355            throw new IllegalArgumentException("Property not defined: " + name);
356        }
357        int val = Integer.valueOf(str);
358        if (val == 0 && !allowZero) {
359            throw new IllegalArgumentException("Property must not be zero: " + name);
360        }
361        return val;
362    }
363
364    static {
365        // These values are set in system/rootdir/init.rc on startup.
366        FOREGROUND_APP_ADJ = getIntProp("ro.FOREGROUND_APP_ADJ", true);
367        VISIBLE_APP_ADJ = getIntProp("ro.VISIBLE_APP_ADJ", true);
368        PERCEPTIBLE_APP_ADJ = getIntProp("ro.PERCEPTIBLE_APP_ADJ", true);
369        HEAVY_WEIGHT_APP_ADJ = getIntProp("ro.HEAVY_WEIGHT_APP_ADJ", true);
370        SECONDARY_SERVER_ADJ = getIntProp("ro.SECONDARY_SERVER_ADJ", true);
371        BACKUP_APP_ADJ = getIntProp("ro.BACKUP_APP_ADJ", true);
372        HOME_APP_ADJ = getIntProp("ro.HOME_APP_ADJ", true);
373        HIDDEN_APP_MIN_ADJ = getIntProp("ro.HIDDEN_APP_MIN_ADJ", true);
374        EMPTY_APP_ADJ = getIntProp("ro.EMPTY_APP_ADJ", true);
375        // These days we use the last empty slot for hidden apps as well.
376        HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ;
377        FOREGROUND_APP_MEM = getIntProp("ro.FOREGROUND_APP_MEM", false)*PAGE_SIZE;
378        VISIBLE_APP_MEM = getIntProp("ro.VISIBLE_APP_MEM", false)*PAGE_SIZE;
379        PERCEPTIBLE_APP_MEM = getIntProp("ro.PERCEPTIBLE_APP_MEM", false)*PAGE_SIZE;
380        HEAVY_WEIGHT_APP_MEM = getIntProp("ro.HEAVY_WEIGHT_APP_MEM", false)*PAGE_SIZE;
381        SECONDARY_SERVER_MEM = getIntProp("ro.SECONDARY_SERVER_MEM", false)*PAGE_SIZE;
382        BACKUP_APP_MEM = getIntProp("ro.BACKUP_APP_MEM", false)*PAGE_SIZE;
383        HOME_APP_MEM = getIntProp("ro.HOME_APP_MEM", false)*PAGE_SIZE;
384        HIDDEN_APP_MEM = getIntProp("ro.HIDDEN_APP_MEM", false)*PAGE_SIZE;
385        EMPTY_APP_MEM = getIntProp("ro.EMPTY_APP_MEM", false)*PAGE_SIZE;
386    }
387
388    static final int MY_PID = Process.myPid();
389
390    static final String[] EMPTY_STRING_ARRAY = new String[0];
391
392    public ActivityStack mMainStack;
393
394    /**
395     * Description of a request to start a new activity, which has been held
396     * due to app switches being disabled.
397     */
398    static class PendingActivityLaunch {
399        ActivityRecord r;
400        ActivityRecord sourceRecord;
401        Uri[] grantedUriPermissions;
402        int grantedMode;
403        boolean onlyIfNeeded;
404    }
405
406    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
407            = new ArrayList<PendingActivityLaunch>();
408
409    /**
410     * List of all active broadcasts that are to be executed immediately
411     * (without waiting for another broadcast to finish).  Currently this only
412     * contains broadcasts to registered receivers, to avoid spinning up
413     * a bunch of processes to execute IntentReceiver components.
414     */
415    final ArrayList<BroadcastRecord> mParallelBroadcasts
416            = new ArrayList<BroadcastRecord>();
417
418    /**
419     * List of all active broadcasts that are to be executed one at a time.
420     * The object at the top of the list is the currently activity broadcasts;
421     * those after it are waiting for the top to finish..
422     */
423    final ArrayList<BroadcastRecord> mOrderedBroadcasts
424            = new ArrayList<BroadcastRecord>();
425
426    /**
427     * Historical data of past broadcasts, for debugging.
428     */
429    static final int MAX_BROADCAST_HISTORY = 100;
430    final BroadcastRecord[] mBroadcastHistory
431            = new BroadcastRecord[MAX_BROADCAST_HISTORY];
432
433    /**
434     * Set when we current have a BROADCAST_INTENT_MSG in flight.
435     */
436    boolean mBroadcastsScheduled = false;
437
438    /**
439     * Activity we have told the window manager to have key focus.
440     */
441    ActivityRecord mFocusedActivity = null;
442    /**
443     * List of intents that were used to start the most recent tasks.
444     */
445    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
446
447    /**
448     * All of the applications we currently have running organized by name.
449     * The keys are strings of the application package name (as
450     * returned by the package manager), and the keys are ApplicationRecord
451     * objects.
452     */
453    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
454
455    /**
456     * The currently running heavy-weight process, if any.
457     */
458    ProcessRecord mHeavyWeightProcess = null;
459
460    /**
461     * The last time that various processes have crashed.
462     */
463    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
464
465    /**
466     * Set of applications that we consider to be bad, and will reject
467     * incoming broadcasts from (which the user has no control over).
468     * Processes are added to this set when they have crashed twice within
469     * a minimum amount of time; they are removed from it when they are
470     * later restarted (hopefully due to some user action).  The value is the
471     * time it was added to the list.
472     */
473    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
474
475    /**
476     * All of the processes we currently have running organized by pid.
477     * The keys are the pid running the application.
478     *
479     * <p>NOTE: This object is protected by its own lock, NOT the global
480     * activity manager lock!
481     */
482    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
483
484    /**
485     * All of the processes that have been forced to be foreground.  The key
486     * is the pid of the caller who requested it (we hold a death
487     * link on it).
488     */
489    abstract class ForegroundToken implements IBinder.DeathRecipient {
490        int pid;
491        IBinder token;
492    }
493    final SparseArray<ForegroundToken> mForegroundProcesses
494            = new SparseArray<ForegroundToken>();
495
496    /**
497     * List of records for processes that someone had tried to start before the
498     * system was ready.  We don't start them at that point, but ensure they
499     * are started by the time booting is complete.
500     */
501    final ArrayList<ProcessRecord> mProcessesOnHold
502            = new ArrayList<ProcessRecord>();
503
504    /**
505     * List of records for processes that we have started and are waiting
506     * for them to call back.  This is really only needed when running in
507     * single processes mode, in which case we do not have a unique pid for
508     * each process.
509     */
510    final ArrayList<ProcessRecord> mStartingProcesses
511            = new ArrayList<ProcessRecord>();
512
513    /**
514     * List of persistent applications that are in the process
515     * of being started.
516     */
517    final ArrayList<ProcessRecord> mPersistentStartingProcesses
518            = new ArrayList<ProcessRecord>();
519
520    /**
521     * Processes that are being forcibly torn down.
522     */
523    final ArrayList<ProcessRecord> mRemovedProcesses
524            = new ArrayList<ProcessRecord>();
525
526    /**
527     * List of running applications, sorted by recent usage.
528     * The first entry in the list is the least recently used.
529     * It contains ApplicationRecord objects.  This list does NOT include
530     * any persistent application records (since we never want to exit them).
531     */
532    final ArrayList<ProcessRecord> mLruProcesses
533            = new ArrayList<ProcessRecord>();
534
535    /**
536     * List of processes that should gc as soon as things are idle.
537     */
538    final ArrayList<ProcessRecord> mProcessesToGc
539            = new ArrayList<ProcessRecord>();
540
541    /**
542     * This is the process holding what we currently consider to be
543     * the "home" activity.
544     */
545    ProcessRecord mHomeProcess;
546
547    /**
548     * Packages that the user has asked to have run in screen size
549     * compatibility mode instead of filling the screen.
550     */
551    final CompatModePackages mCompatModePackages;
552
553    /**
554     * Set of PendingResultRecord objects that are currently active.
555     */
556    final HashSet mPendingResultRecords = new HashSet();
557
558    /**
559     * Set of IntentSenderRecord objects that are currently active.
560     */
561    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
562            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
563
564    /**
565     * Fingerprints (hashCode()) of stack traces that we've
566     * already logged DropBox entries for.  Guarded by itself.  If
567     * something (rogue user app) forces this over
568     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
569     */
570    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
571    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
572
573    /**
574     * Strict Mode background batched logging state.
575     *
576     * The string buffer is guarded by itself, and its lock is also
577     * used to determine if another batched write is already
578     * in-flight.
579     */
580    private final StringBuilder mStrictModeBuffer = new StringBuilder();
581
582    /**
583     * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
584     */
585    private boolean mPendingBroadcastTimeoutMessage;
586
587    /**
588     * Intent broadcast that we have tried to start, but are
589     * waiting for its application's process to be created.  We only
590     * need one (instead of a list) because we always process broadcasts
591     * one at a time, so no others can be started while waiting for this
592     * one.
593     */
594    BroadcastRecord mPendingBroadcast = null;
595
596    /**
597     * The receiver index that is pending, to restart the broadcast if needed.
598     */
599    int mPendingBroadcastRecvIndex;
600
601    /**
602     * Keeps track of all IIntentReceivers that have been registered for
603     * broadcasts.  Hash keys are the receiver IBinder, hash value is
604     * a ReceiverList.
605     */
606    final HashMap mRegisteredReceivers = new HashMap();
607
608    /**
609     * Resolver for broadcast intents to registered receivers.
610     * Holds BroadcastFilter (subclass of IntentFilter).
611     */
612    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
613            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
614        @Override
615        protected boolean allowFilterResult(
616                BroadcastFilter filter, List<BroadcastFilter> dest) {
617            IBinder target = filter.receiverList.receiver.asBinder();
618            for (int i=dest.size()-1; i>=0; i--) {
619                if (dest.get(i).receiverList.receiver.asBinder() == target) {
620                    return false;
621                }
622            }
623            return true;
624        }
625
626        @Override
627        protected String packageForFilter(BroadcastFilter filter) {
628            return filter.packageName;
629        }
630    };
631
632    /**
633     * State of all active sticky broadcasts.  Keys are the action of the
634     * sticky Intent, values are an ArrayList of all broadcasted intents with
635     * that action (which should usually be one).
636     */
637    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
638            new HashMap<String, ArrayList<Intent>>();
639
640    /**
641     * All currently running services.
642     */
643    final HashMap<ComponentName, ServiceRecord> mServices =
644        new HashMap<ComponentName, ServiceRecord>();
645
646    /**
647     * All currently running services indexed by the Intent used to start them.
648     */
649    final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
650        new HashMap<Intent.FilterComparison, ServiceRecord>();
651
652    /**
653     * All currently bound service connections.  Keys are the IBinder of
654     * the client's IServiceConnection.
655     */
656    final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
657            = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
658
659    /**
660     * List of services that we have been asked to start,
661     * but haven't yet been able to.  It is used to hold start requests
662     * while waiting for their corresponding application thread to get
663     * going.
664     */
665    final ArrayList<ServiceRecord> mPendingServices
666            = new ArrayList<ServiceRecord>();
667
668    /**
669     * List of services that are scheduled to restart following a crash.
670     */
671    final ArrayList<ServiceRecord> mRestartingServices
672            = new ArrayList<ServiceRecord>();
673
674    /**
675     * List of services that are in the process of being stopped.
676     */
677    final ArrayList<ServiceRecord> mStoppingServices
678            = new ArrayList<ServiceRecord>();
679
680    /**
681     * Backup/restore process management
682     */
683    String mBackupAppName = null;
684    BackupRecord mBackupTarget = null;
685
686    /**
687     * List of PendingThumbnailsRecord objects of clients who are still
688     * waiting to receive all of the thumbnails for a task.
689     */
690    final ArrayList mPendingThumbnails = new ArrayList();
691
692    /**
693     * List of HistoryRecord objects that have been finished and must
694     * still report back to a pending thumbnail receiver.
695     */
696    final ArrayList mCancelledThumbnails = new ArrayList();
697
698    /**
699     * All of the currently running global content providers.  Keys are a
700     * string containing the provider name and values are a
701     * ContentProviderRecord object containing the data about it.  Note
702     * that a single provider may be published under multiple names, so
703     * there may be multiple entries here for a single one in mProvidersByClass.
704     */
705    final HashMap<String, ContentProviderRecord> mProvidersByName
706            = new HashMap<String, ContentProviderRecord>();
707
708    /**
709     * All of the currently running global content providers.  Keys are a
710     * string containing the provider's implementation class and values are a
711     * ContentProviderRecord object containing the data about it.
712     */
713    final HashMap<String, ContentProviderRecord> mProvidersByClass
714            = new HashMap<String, ContentProviderRecord>();
715
716    /**
717     * List of content providers who have clients waiting for them.  The
718     * application is currently being launched and the provider will be
719     * removed from this list once it is published.
720     */
721    final ArrayList<ContentProviderRecord> mLaunchingProviders
722            = new ArrayList<ContentProviderRecord>();
723
724    /**
725     * Global set of specific Uri permissions that have been granted.
726     */
727    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
728            = new SparseArray<HashMap<Uri, UriPermission>>();
729
730    CoreSettingsObserver mCoreSettingsObserver;
731
732    /**
733     * Thread-local storage used to carry caller permissions over through
734     * indirect content-provider access.
735     * @see #ActivityManagerService.openContentUri()
736     */
737    private class Identity {
738        public int pid;
739        public int uid;
740
741        Identity(int _pid, int _uid) {
742            pid = _pid;
743            uid = _uid;
744        }
745    }
746    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
747
748    /**
749     * All information we have collected about the runtime performance of
750     * any user id that can impact battery performance.
751     */
752    final BatteryStatsService mBatteryStatsService;
753
754    /**
755     * information about component usage
756     */
757    final UsageStatsService mUsageStatsService;
758
759    /**
760     * Current configuration information.  HistoryRecord objects are given
761     * a reference to this object to indicate which configuration they are
762     * currently running in, so this object must be kept immutable.
763     */
764    Configuration mConfiguration = new Configuration();
765
766    /**
767     * Current sequencing integer of the configuration, for skipping old
768     * configurations.
769     */
770    int mConfigurationSeq = 0;
771
772    /**
773     * Hardware-reported OpenGLES version.
774     */
775    final int GL_ES_VERSION;
776
777    /**
778     * List of initialization arguments to pass to all processes when binding applications to them.
779     * For example, references to the commonly used services.
780     */
781    HashMap<String, IBinder> mAppBindArgs;
782
783    /**
784     * Temporary to avoid allocations.  Protected by main lock.
785     */
786    final StringBuilder mStringBuilder = new StringBuilder(256);
787
788    /**
789     * Used to control how we initialize the service.
790     */
791    boolean mStartRunning = false;
792    ComponentName mTopComponent;
793    String mTopAction;
794    String mTopData;
795    boolean mProcessesReady = false;
796    boolean mSystemReady = false;
797    boolean mBooting = false;
798    boolean mWaitingUpdate = false;
799    boolean mDidUpdate = false;
800    boolean mOnBattery = false;
801    boolean mLaunchWarningShown = false;
802
803    Context mContext;
804
805    int mFactoryTest;
806
807    boolean mCheckedForSetup;
808
809    /**
810     * The time at which we will allow normal application switches again,
811     * after a call to {@link #stopAppSwitches()}.
812     */
813    long mAppSwitchesAllowedTime;
814
815    /**
816     * This is set to true after the first switch after mAppSwitchesAllowedTime
817     * is set; any switches after that will clear the time.
818     */
819    boolean mDidAppSwitch;
820
821    /**
822     * Last time (in realtime) at which we checked for power usage.
823     */
824    long mLastPowerCheckRealtime;
825
826    /**
827     * Last time (in uptime) at which we checked for power usage.
828     */
829    long mLastPowerCheckUptime;
830
831    /**
832     * Set while we are wanting to sleep, to prevent any
833     * activities from being started/resumed.
834     */
835    boolean mSleeping = false;
836
837    /**
838     * Set if we are shutting down the system, similar to sleeping.
839     */
840    boolean mShuttingDown = false;
841
842    /**
843     * Task identifier that activities are currently being started
844     * in.  Incremented each time a new task is created.
845     * todo: Replace this with a TokenSpace class that generates non-repeating
846     * integers that won't wrap.
847     */
848    int mCurTask = 1;
849
850    /**
851     * Current sequence id for oom_adj computation traversal.
852     */
853    int mAdjSeq = 0;
854
855    /**
856     * Current sequence id for process LRU updating.
857     */
858    int mLruSeq = 0;
859
860    /**
861     * System monitoring: number of processes that died since the last
862     * N procs were started.
863     */
864    int[] mProcDeaths = new int[20];
865
866    /**
867     * This is set if we had to do a delayed dexopt of an app before launching
868     * it, to increasing the ANR timeouts in that case.
869     */
870    boolean mDidDexOpt;
871
872    String mDebugApp = null;
873    boolean mWaitForDebugger = false;
874    boolean mDebugTransient = false;
875    String mOrigDebugApp = null;
876    boolean mOrigWaitForDebugger = false;
877    boolean mAlwaysFinishActivities = false;
878    IActivityController mController = null;
879
880    final RemoteCallbackList<IActivityWatcher> mWatchers
881            = new RemoteCallbackList<IActivityWatcher>();
882
883    final RemoteCallbackList<IProcessObserver> mProcessObservers
884            = new RemoteCallbackList<IProcessObserver>();
885
886    /**
887     * Callback of last caller to {@link #requestPss}.
888     */
889    Runnable mRequestPssCallback;
890
891    /**
892     * Remaining processes for which we are waiting results from the last
893     * call to {@link #requestPss}.
894     */
895    final ArrayList<ProcessRecord> mRequestPssList
896            = new ArrayList<ProcessRecord>();
897
898    /**
899     * Runtime statistics collection thread.  This object's lock is used to
900     * protect all related state.
901     */
902    final Thread mProcessStatsThread;
903
904    /**
905     * Used to collect process stats when showing not responding dialog.
906     * Protected by mProcessStatsThread.
907     */
908    final ProcessStats mProcessStats = new ProcessStats(
909            MONITOR_THREAD_CPU_USAGE);
910    final AtomicLong mLastCpuTime = new AtomicLong(0);
911    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
912
913    long mLastWriteTime = 0;
914
915    /**
916     * Set to true after the system has finished booting.
917     */
918    boolean mBooted = false;
919
920    int mProcessLimit = 0;
921
922    WindowManagerService mWindowManager;
923
924    static ActivityManagerService mSelf;
925    static ActivityThread mSystemThread;
926
927    private final class AppDeathRecipient implements IBinder.DeathRecipient {
928        final ProcessRecord mApp;
929        final int mPid;
930        final IApplicationThread mAppThread;
931
932        AppDeathRecipient(ProcessRecord app, int pid,
933                IApplicationThread thread) {
934            if (localLOGV) Slog.v(
935                TAG, "New death recipient " + this
936                + " for thread " + thread.asBinder());
937            mApp = app;
938            mPid = pid;
939            mAppThread = thread;
940        }
941
942        public void binderDied() {
943            if (localLOGV) Slog.v(
944                TAG, "Death received in " + this
945                + " for thread " + mAppThread.asBinder());
946            synchronized(ActivityManagerService.this) {
947                appDiedLocked(mApp, mPid, mAppThread);
948            }
949        }
950    }
951
952    static final int SHOW_ERROR_MSG = 1;
953    static final int SHOW_NOT_RESPONDING_MSG = 2;
954    static final int SHOW_FACTORY_ERROR_MSG = 3;
955    static final int UPDATE_CONFIGURATION_MSG = 4;
956    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
957    static final int WAIT_FOR_DEBUGGER_MSG = 6;
958    static final int BROADCAST_INTENT_MSG = 7;
959    static final int BROADCAST_TIMEOUT_MSG = 8;
960    static final int SERVICE_TIMEOUT_MSG = 12;
961    static final int UPDATE_TIME_ZONE = 13;
962    static final int SHOW_UID_ERROR_MSG = 14;
963    static final int IM_FEELING_LUCKY_MSG = 15;
964    static final int PROC_START_TIMEOUT_MSG = 20;
965    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
966    static final int KILL_APPLICATION_MSG = 22;
967    static final int FINALIZE_PENDING_INTENT_MSG = 23;
968    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
969    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
970    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
971    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
972    static final int CLEAR_DNS_CACHE = 28;
973    static final int UPDATE_HTTP_PROXY = 29;
974    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
975    static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
976    static final int DISPATCH_PROCESS_DIED = 32;
977
978    AlertDialog mUidAlert;
979    CompatModeDialog mCompatModeDialog;
980
981    final Handler mHandler = new Handler() {
982        //public Handler() {
983        //    if (localLOGV) Slog.v(TAG, "Handler started!");
984        //}
985
986        public void handleMessage(Message msg) {
987            switch (msg.what) {
988            case SHOW_ERROR_MSG: {
989                HashMap data = (HashMap) msg.obj;
990                synchronized (ActivityManagerService.this) {
991                    ProcessRecord proc = (ProcessRecord)data.get("app");
992                    if (proc != null && proc.crashDialog != null) {
993                        Slog.e(TAG, "App already has crash dialog: " + proc);
994                        return;
995                    }
996                    AppErrorResult res = (AppErrorResult) data.get("result");
997                    if (!mSleeping && !mShuttingDown) {
998                        Dialog d = new AppErrorDialog(mContext, res, proc);
999                        d.show();
1000                        proc.crashDialog = d;
1001                    } else {
1002                        // The device is asleep, so just pretend that the user
1003                        // saw a crash dialog and hit "force quit".
1004                        res.set(0);
1005                    }
1006                }
1007
1008                ensureBootCompleted();
1009            } break;
1010            case SHOW_NOT_RESPONDING_MSG: {
1011                synchronized (ActivityManagerService.this) {
1012                    HashMap data = (HashMap) msg.obj;
1013                    ProcessRecord proc = (ProcessRecord)data.get("app");
1014                    if (proc != null && proc.anrDialog != null) {
1015                        Slog.e(TAG, "App already has anr dialog: " + proc);
1016                        return;
1017                    }
1018
1019                    Intent intent = new Intent("android.intent.action.ANR");
1020                    if (!mProcessesReady) {
1021                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1022                    }
1023                    broadcastIntentLocked(null, null, intent,
1024                            null, null, 0, null, null, null,
1025                            false, false, MY_PID, Process.SYSTEM_UID);
1026
1027                    Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1028                            mContext, proc, (ActivityRecord)data.get("activity"));
1029                    d.show();
1030                    proc.anrDialog = d;
1031                }
1032
1033                ensureBootCompleted();
1034            } break;
1035            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1036                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1037                synchronized (ActivityManagerService.this) {
1038                    ProcessRecord proc = (ProcessRecord) data.get("app");
1039                    if (proc == null) {
1040                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1041                        break;
1042                    }
1043                    if (proc.crashDialog != null) {
1044                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1045                        return;
1046                    }
1047                    AppErrorResult res = (AppErrorResult) data.get("result");
1048                    if (!mSleeping && !mShuttingDown) {
1049                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
1050                        d.show();
1051                        proc.crashDialog = d;
1052                    } else {
1053                        // The device is asleep, so just pretend that the user
1054                        // saw a crash dialog and hit "force quit".
1055                        res.set(0);
1056                    }
1057                }
1058                ensureBootCompleted();
1059            } break;
1060            case SHOW_FACTORY_ERROR_MSG: {
1061                Dialog d = new FactoryErrorDialog(
1062                    mContext, msg.getData().getCharSequence("msg"));
1063                d.show();
1064                ensureBootCompleted();
1065            } break;
1066            case UPDATE_CONFIGURATION_MSG: {
1067                final ContentResolver resolver = mContext.getContentResolver();
1068                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1069            } break;
1070            case GC_BACKGROUND_PROCESSES_MSG: {
1071                synchronized (ActivityManagerService.this) {
1072                    performAppGcsIfAppropriateLocked();
1073                }
1074            } break;
1075            case WAIT_FOR_DEBUGGER_MSG: {
1076                synchronized (ActivityManagerService.this) {
1077                    ProcessRecord app = (ProcessRecord)msg.obj;
1078                    if (msg.arg1 != 0) {
1079                        if (!app.waitedForDebugger) {
1080                            Dialog d = new AppWaitingForDebuggerDialog(
1081                                    ActivityManagerService.this,
1082                                    mContext, app);
1083                            app.waitDialog = d;
1084                            app.waitedForDebugger = true;
1085                            d.show();
1086                        }
1087                    } else {
1088                        if (app.waitDialog != null) {
1089                            app.waitDialog.dismiss();
1090                            app.waitDialog = null;
1091                        }
1092                    }
1093                }
1094            } break;
1095            case BROADCAST_INTENT_MSG: {
1096                if (DEBUG_BROADCAST) Slog.v(
1097                        TAG, "Received BROADCAST_INTENT_MSG");
1098                processNextBroadcast(true);
1099            } break;
1100            case BROADCAST_TIMEOUT_MSG: {
1101                synchronized (ActivityManagerService.this) {
1102                    broadcastTimeoutLocked(true);
1103                }
1104            } break;
1105            case SERVICE_TIMEOUT_MSG: {
1106                if (mDidDexOpt) {
1107                    mDidDexOpt = false;
1108                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1109                    nmsg.obj = msg.obj;
1110                    mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1111                    return;
1112                }
1113                serviceTimeout((ProcessRecord)msg.obj);
1114            } break;
1115            case UPDATE_TIME_ZONE: {
1116                synchronized (ActivityManagerService.this) {
1117                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1118                        ProcessRecord r = mLruProcesses.get(i);
1119                        if (r.thread != null) {
1120                            try {
1121                                r.thread.updateTimeZone();
1122                            } catch (RemoteException ex) {
1123                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1124                            }
1125                        }
1126                    }
1127                }
1128            } break;
1129            case CLEAR_DNS_CACHE: {
1130                synchronized (ActivityManagerService.this) {
1131                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1132                        ProcessRecord r = mLruProcesses.get(i);
1133                        if (r.thread != null) {
1134                            try {
1135                                r.thread.clearDnsCache();
1136                            } catch (RemoteException ex) {
1137                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1138                            }
1139                        }
1140                    }
1141                }
1142            } break;
1143            case UPDATE_HTTP_PROXY: {
1144                ProxyProperties proxy = (ProxyProperties)msg.obj;
1145                String host = "";
1146                String port = "";
1147                String exclList = "";
1148                if (proxy != null) {
1149                    host = proxy.getHost();
1150                    port = Integer.toString(proxy.getPort());
1151                    exclList = proxy.getExclusionList();
1152                }
1153                synchronized (ActivityManagerService.this) {
1154                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1155                        ProcessRecord r = mLruProcesses.get(i);
1156                        if (r.thread != null) {
1157                            try {
1158                                r.thread.setHttpProxy(host, port, exclList);
1159                            } catch (RemoteException ex) {
1160                                Slog.w(TAG, "Failed to update http proxy for: " +
1161                                        r.info.processName);
1162                            }
1163                        }
1164                    }
1165                }
1166            } break;
1167            case SHOW_UID_ERROR_MSG: {
1168                // XXX This is a temporary dialog, no need to localize.
1169                AlertDialog d = new BaseErrorDialog(mContext);
1170                d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1171                d.setCancelable(false);
1172                d.setTitle("System UIDs Inconsistent");
1173                d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
1174                d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1175                        mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1176                mUidAlert = d;
1177                d.show();
1178            } break;
1179            case IM_FEELING_LUCKY_MSG: {
1180                if (mUidAlert != null) {
1181                    mUidAlert.dismiss();
1182                    mUidAlert = null;
1183                }
1184            } break;
1185            case PROC_START_TIMEOUT_MSG: {
1186                if (mDidDexOpt) {
1187                    mDidDexOpt = false;
1188                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1189                    nmsg.obj = msg.obj;
1190                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1191                    return;
1192                }
1193                ProcessRecord app = (ProcessRecord)msg.obj;
1194                synchronized (ActivityManagerService.this) {
1195                    processStartTimedOutLocked(app);
1196                }
1197            } break;
1198            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1199                synchronized (ActivityManagerService.this) {
1200                    doPendingActivityLaunchesLocked(true);
1201                }
1202            } break;
1203            case KILL_APPLICATION_MSG: {
1204                synchronized (ActivityManagerService.this) {
1205                    int uid = msg.arg1;
1206                    boolean restart = (msg.arg2 == 1);
1207                    String pkg = (String) msg.obj;
1208                    forceStopPackageLocked(pkg, uid, restart, false, true);
1209                }
1210            } break;
1211            case FINALIZE_PENDING_INTENT_MSG: {
1212                ((PendingIntentRecord)msg.obj).completeFinalize();
1213            } break;
1214            case POST_HEAVY_NOTIFICATION_MSG: {
1215                INotificationManager inm = NotificationManager.getService();
1216                if (inm == null) {
1217                    return;
1218                }
1219
1220                ActivityRecord root = (ActivityRecord)msg.obj;
1221                ProcessRecord process = root.app;
1222                if (process == null) {
1223                    return;
1224                }
1225
1226                try {
1227                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1228                    String text = mContext.getString(R.string.heavy_weight_notification,
1229                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1230                    Notification notification = new Notification();
1231                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1232                    notification.when = 0;
1233                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1234                    notification.tickerText = text;
1235                    notification.defaults = 0; // please be quiet
1236                    notification.sound = null;
1237                    notification.vibrate = null;
1238                    notification.setLatestEventInfo(context, text,
1239                            mContext.getText(R.string.heavy_weight_notification_detail),
1240                            PendingIntent.getActivity(mContext, 0, root.intent,
1241                                    PendingIntent.FLAG_CANCEL_CURRENT));
1242
1243                    try {
1244                        int[] outId = new int[1];
1245                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
1246                                notification, outId);
1247                    } catch (RuntimeException e) {
1248                        Slog.w(ActivityManagerService.TAG,
1249                                "Error showing notification for heavy-weight app", e);
1250                    } catch (RemoteException e) {
1251                    }
1252                } catch (NameNotFoundException e) {
1253                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1254                }
1255            } break;
1256            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1257                INotificationManager inm = NotificationManager.getService();
1258                if (inm == null) {
1259                    return;
1260                }
1261                try {
1262                    inm.cancelNotification("android",
1263                            R.string.heavy_weight_notification);
1264                } catch (RuntimeException e) {
1265                    Slog.w(ActivityManagerService.TAG,
1266                            "Error canceling notification for service", e);
1267                } catch (RemoteException e) {
1268                }
1269            } break;
1270            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1271                synchronized (ActivityManagerService.this) {
1272                    checkExcessivePowerUsageLocked(true);
1273                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1274                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1275                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1276                }
1277            } break;
1278            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1279                synchronized (ActivityManagerService.this) {
1280                    ActivityRecord ar = (ActivityRecord)msg.obj;
1281                    if (mCompatModeDialog != null) {
1282                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1283                                ar.info.applicationInfo.packageName)) {
1284                            return;
1285                        }
1286                        mCompatModeDialog.dismiss();
1287                        mCompatModeDialog = null;
1288                    }
1289                    if (ar != null && false) {
1290                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1291                                ar.packageName)) {
1292                            int mode = mCompatModePackages.computeCompatModeLocked(
1293                                    ar.info.applicationInfo);
1294                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1295                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1296                                mCompatModeDialog = new CompatModeDialog(
1297                                        ActivityManagerService.this, mContext,
1298                                        ar.info.applicationInfo);
1299                                mCompatModeDialog.show();
1300                            }
1301                        }
1302                    }
1303                }
1304                break;
1305            }
1306            case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
1307                final int pid = msg.arg1;
1308                final int uid = msg.arg2;
1309                final boolean foregroundActivities = (Boolean) msg.obj;
1310                dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
1311                break;
1312            }
1313            case DISPATCH_PROCESS_DIED: {
1314                final int pid = msg.arg1;
1315                final int uid = msg.arg2;
1316                dispatchProcessDied(pid, uid);
1317                break;
1318            }
1319            }
1320        }
1321    };
1322
1323    public static void setSystemProcess() {
1324        try {
1325            ActivityManagerService m = mSelf;
1326
1327            ServiceManager.addService("activity", m);
1328            ServiceManager.addService("meminfo", new MemBinder(m));
1329            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1330            if (MONITOR_CPU_USAGE) {
1331                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1332            }
1333            ServiceManager.addService("permission", new PermissionController(m));
1334
1335            ApplicationInfo info =
1336                mSelf.mContext.getPackageManager().getApplicationInfo(
1337                        "android", STOCK_PM_FLAGS);
1338            mSystemThread.installSystemApplicationInfo(info);
1339
1340            synchronized (mSelf) {
1341                ProcessRecord app = mSelf.newProcessRecordLocked(
1342                        mSystemThread.getApplicationThread(), info,
1343                        info.processName);
1344                app.persistent = true;
1345                app.pid = MY_PID;
1346                app.maxAdj = SYSTEM_ADJ;
1347                mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1348                synchronized (mSelf.mPidsSelfLocked) {
1349                    mSelf.mPidsSelfLocked.put(app.pid, app);
1350                }
1351                mSelf.updateLruProcessLocked(app, true, true);
1352            }
1353        } catch (PackageManager.NameNotFoundException e) {
1354            throw new RuntimeException(
1355                    "Unable to find android system package", e);
1356        }
1357    }
1358
1359    public void setWindowManager(WindowManagerService wm) {
1360        mWindowManager = wm;
1361    }
1362
1363    public static final Context main(int factoryTest) {
1364        AThread thr = new AThread();
1365        thr.start();
1366
1367        synchronized (thr) {
1368            while (thr.mService == null) {
1369                try {
1370                    thr.wait();
1371                } catch (InterruptedException e) {
1372                }
1373            }
1374        }
1375
1376        ActivityManagerService m = thr.mService;
1377        mSelf = m;
1378        ActivityThread at = ActivityThread.systemMain();
1379        mSystemThread = at;
1380        Context context = at.getSystemContext();
1381        context.setTheme(android.R.style.Theme_Holo);
1382        m.mContext = context;
1383        m.mFactoryTest = factoryTest;
1384        m.mMainStack = new ActivityStack(m, context, true);
1385
1386        m.mBatteryStatsService.publish(context);
1387        m.mUsageStatsService.publish(context);
1388
1389        synchronized (thr) {
1390            thr.mReady = true;
1391            thr.notifyAll();
1392        }
1393
1394        m.startRunning(null, null, null, null);
1395
1396        return context;
1397    }
1398
1399    public static ActivityManagerService self() {
1400        return mSelf;
1401    }
1402
1403    static class AThread extends Thread {
1404        ActivityManagerService mService;
1405        boolean mReady = false;
1406
1407        public AThread() {
1408            super("ActivityManager");
1409        }
1410
1411        public void run() {
1412            Looper.prepare();
1413
1414            android.os.Process.setThreadPriority(
1415                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1416            android.os.Process.setCanSelfBackground(false);
1417
1418            ActivityManagerService m = new ActivityManagerService();
1419
1420            synchronized (this) {
1421                mService = m;
1422                notifyAll();
1423            }
1424
1425            synchronized (this) {
1426                while (!mReady) {
1427                    try {
1428                        wait();
1429                    } catch (InterruptedException e) {
1430                    }
1431                }
1432            }
1433
1434            // For debug builds, log event loop stalls to dropbox for analysis.
1435            if (StrictMode.conditionallyEnableDebugLogging()) {
1436                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1437            }
1438
1439            Looper.loop();
1440        }
1441    }
1442
1443    static class MemBinder extends Binder {
1444        ActivityManagerService mActivityManagerService;
1445        MemBinder(ActivityManagerService activityManagerService) {
1446            mActivityManagerService = activityManagerService;
1447        }
1448
1449        @Override
1450        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1451            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args);
1452        }
1453    }
1454
1455    static class GraphicsBinder extends Binder {
1456        ActivityManagerService mActivityManagerService;
1457        GraphicsBinder(ActivityManagerService activityManagerService) {
1458            mActivityManagerService = activityManagerService;
1459        }
1460
1461        @Override
1462        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1463            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1464        }
1465    }
1466
1467    static class CpuBinder extends Binder {
1468        ActivityManagerService mActivityManagerService;
1469        CpuBinder(ActivityManagerService activityManagerService) {
1470            mActivityManagerService = activityManagerService;
1471        }
1472
1473        @Override
1474        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1475            synchronized (mActivityManagerService.mProcessStatsThread) {
1476                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1477                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1478                        SystemClock.uptimeMillis()));
1479            }
1480        }
1481    }
1482
1483    private ActivityManagerService() {
1484        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1485
1486        File dataDir = Environment.getDataDirectory();
1487        File systemDir = new File(dataDir, "system");
1488        systemDir.mkdirs();
1489        mBatteryStatsService = new BatteryStatsService(new File(
1490                systemDir, "batterystats.bin").toString());
1491        mBatteryStatsService.getActiveStatistics().readLocked();
1492        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1493        mOnBattery = DEBUG_POWER ? true
1494                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1495        mBatteryStatsService.getActiveStatistics().setCallback(this);
1496
1497        mUsageStatsService = new UsageStatsService(new File(
1498                systemDir, "usagestats").toString());
1499
1500        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1501            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1502
1503        mConfiguration.setToDefaults();
1504        mConfiguration.locale = Locale.getDefault();
1505        mProcessStats.init();
1506
1507        mCompatModePackages = new CompatModePackages(this, systemDir);
1508
1509        // Add ourself to the Watchdog monitors.
1510        Watchdog.getInstance().addMonitor(this);
1511
1512        mProcessStatsThread = new Thread("ProcessStats") {
1513            public void run() {
1514                while (true) {
1515                    try {
1516                        try {
1517                            synchronized(this) {
1518                                final long now = SystemClock.uptimeMillis();
1519                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1520                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1521                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1522                                //        + ", write delay=" + nextWriteDelay);
1523                                if (nextWriteDelay < nextCpuDelay) {
1524                                    nextCpuDelay = nextWriteDelay;
1525                                }
1526                                if (nextCpuDelay > 0) {
1527                                    mProcessStatsMutexFree.set(true);
1528                                    this.wait(nextCpuDelay);
1529                                }
1530                            }
1531                        } catch (InterruptedException e) {
1532                        }
1533                        updateCpuStatsNow();
1534                    } catch (Exception e) {
1535                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1536                    }
1537                }
1538            }
1539        };
1540        mProcessStatsThread.start();
1541    }
1542
1543    @Override
1544    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1545            throws RemoteException {
1546        try {
1547            return super.onTransact(code, data, reply, flags);
1548        } catch (RuntimeException e) {
1549            // The activity manager only throws security exceptions, so let's
1550            // log all others.
1551            if (!(e instanceof SecurityException)) {
1552                Slog.e(TAG, "Activity Manager Crash", e);
1553            }
1554            throw e;
1555        }
1556    }
1557
1558    void updateCpuStats() {
1559        final long now = SystemClock.uptimeMillis();
1560        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1561            return;
1562        }
1563        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1564            synchronized (mProcessStatsThread) {
1565                mProcessStatsThread.notify();
1566            }
1567        }
1568    }
1569
1570    void updateCpuStatsNow() {
1571        synchronized (mProcessStatsThread) {
1572            mProcessStatsMutexFree.set(false);
1573            final long now = SystemClock.uptimeMillis();
1574            boolean haveNewCpuStats = false;
1575
1576            if (MONITOR_CPU_USAGE &&
1577                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1578                mLastCpuTime.set(now);
1579                haveNewCpuStats = true;
1580                mProcessStats.update();
1581                //Slog.i(TAG, mProcessStats.printCurrentState());
1582                //Slog.i(TAG, "Total CPU usage: "
1583                //        + mProcessStats.getTotalCpuPercent() + "%");
1584
1585                // Slog the cpu usage if the property is set.
1586                if ("true".equals(SystemProperties.get("events.cpu"))) {
1587                    int user = mProcessStats.getLastUserTime();
1588                    int system = mProcessStats.getLastSystemTime();
1589                    int iowait = mProcessStats.getLastIoWaitTime();
1590                    int irq = mProcessStats.getLastIrqTime();
1591                    int softIrq = mProcessStats.getLastSoftIrqTime();
1592                    int idle = mProcessStats.getLastIdleTime();
1593
1594                    int total = user + system + iowait + irq + softIrq + idle;
1595                    if (total == 0) total = 1;
1596
1597                    EventLog.writeEvent(EventLogTags.CPU,
1598                            ((user+system+iowait+irq+softIrq) * 100) / total,
1599                            (user * 100) / total,
1600                            (system * 100) / total,
1601                            (iowait * 100) / total,
1602                            (irq * 100) / total,
1603                            (softIrq * 100) / total);
1604                }
1605            }
1606
1607            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1608            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1609            synchronized(bstats) {
1610                synchronized(mPidsSelfLocked) {
1611                    if (haveNewCpuStats) {
1612                        if (mOnBattery) {
1613                            int perc = bstats.startAddingCpuLocked();
1614                            int totalUTime = 0;
1615                            int totalSTime = 0;
1616                            final int N = mProcessStats.countStats();
1617                            for (int i=0; i<N; i++) {
1618                                ProcessStats.Stats st = mProcessStats.getStats(i);
1619                                if (!st.working) {
1620                                    continue;
1621                                }
1622                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1623                                int otherUTime = (st.rel_utime*perc)/100;
1624                                int otherSTime = (st.rel_stime*perc)/100;
1625                                totalUTime += otherUTime;
1626                                totalSTime += otherSTime;
1627                                if (pr != null) {
1628                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1629                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1630                                            st.rel_stime-otherSTime);
1631                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1632                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1633                                } else {
1634                                    BatteryStatsImpl.Uid.Proc ps =
1635                                            bstats.getProcessStatsLocked(st.name, st.pid);
1636                                    if (ps != null) {
1637                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1638                                                st.rel_stime-otherSTime);
1639                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1640                                    }
1641                                }
1642                            }
1643                            bstats.finishAddingCpuLocked(perc, totalUTime,
1644                                    totalSTime, cpuSpeedTimes);
1645                        }
1646                    }
1647                }
1648
1649                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1650                    mLastWriteTime = now;
1651                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1652                }
1653            }
1654        }
1655    }
1656
1657    @Override
1658    public void batteryNeedsCpuUpdate() {
1659        updateCpuStatsNow();
1660    }
1661
1662    @Override
1663    public void batteryPowerChanged(boolean onBattery) {
1664        // When plugging in, update the CPU stats first before changing
1665        // the plug state.
1666        updateCpuStatsNow();
1667        synchronized (this) {
1668            synchronized(mPidsSelfLocked) {
1669                mOnBattery = DEBUG_POWER ? true : onBattery;
1670            }
1671        }
1672    }
1673
1674    /**
1675     * Initialize the application bind args. These are passed to each
1676     * process when the bindApplication() IPC is sent to the process. They're
1677     * lazily setup to make sure the services are running when they're asked for.
1678     */
1679    private HashMap<String, IBinder> getCommonServicesLocked() {
1680        if (mAppBindArgs == null) {
1681            mAppBindArgs = new HashMap<String, IBinder>();
1682
1683            // Setup the application init args
1684            mAppBindArgs.put("package", ServiceManager.getService("package"));
1685            mAppBindArgs.put("window", ServiceManager.getService("window"));
1686            mAppBindArgs.put(Context.ALARM_SERVICE,
1687                    ServiceManager.getService(Context.ALARM_SERVICE));
1688        }
1689        return mAppBindArgs;
1690    }
1691
1692    final void setFocusedActivityLocked(ActivityRecord r) {
1693        if (mFocusedActivity != r) {
1694            mFocusedActivity = r;
1695            mWindowManager.setFocusedApp(r, true);
1696        }
1697    }
1698
1699    private final void updateLruProcessInternalLocked(ProcessRecord app,
1700            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1701        // put it on the LRU to keep track of when it should be exited.
1702        int lrui = mLruProcesses.indexOf(app);
1703        if (lrui >= 0) mLruProcesses.remove(lrui);
1704
1705        int i = mLruProcesses.size()-1;
1706        int skipTop = 0;
1707
1708        app.lruSeq = mLruSeq;
1709
1710        // compute the new weight for this process.
1711        if (updateActivityTime) {
1712            app.lastActivityTime = SystemClock.uptimeMillis();
1713        }
1714        if (app.activities.size() > 0) {
1715            // If this process has activities, we more strongly want to keep
1716            // it around.
1717            app.lruWeight = app.lastActivityTime;
1718        } else if (app.pubProviders.size() > 0) {
1719            // If this process contains content providers, we want to keep
1720            // it a little more strongly.
1721            app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
1722            // Also don't let it kick out the first few "real" hidden processes.
1723            skipTop = MIN_HIDDEN_APPS;
1724        } else {
1725            // If this process doesn't have activities, we less strongly
1726            // want to keep it around, and generally want to avoid getting
1727            // in front of any very recently used activities.
1728            app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
1729            // Also don't let it kick out the first few "real" hidden processes.
1730            skipTop = MIN_HIDDEN_APPS;
1731        }
1732
1733        while (i >= 0) {
1734            ProcessRecord p = mLruProcesses.get(i);
1735            // If this app shouldn't be in front of the first N background
1736            // apps, then skip over that many that are currently hidden.
1737            if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
1738                skipTop--;
1739            }
1740            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1741                mLruProcesses.add(i+1, app);
1742                break;
1743            }
1744            i--;
1745        }
1746        if (i < 0) {
1747            mLruProcesses.add(0, app);
1748        }
1749
1750        // If the app is currently using a content provider or service,
1751        // bump those processes as well.
1752        if (app.connections.size() > 0) {
1753            for (ConnectionRecord cr : app.connections) {
1754                if (cr.binding != null && cr.binding.service != null
1755                        && cr.binding.service.app != null
1756                        && cr.binding.service.app.lruSeq != mLruSeq) {
1757                    updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1758                            updateActivityTime, i+1);
1759                }
1760            }
1761        }
1762        if (app.conProviders.size() > 0) {
1763            for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1764                if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1765                    updateLruProcessInternalLocked(cpr.app, oomAdj,
1766                            updateActivityTime, i+1);
1767                }
1768            }
1769        }
1770
1771        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1772        if (oomAdj) {
1773            updateOomAdjLocked();
1774        }
1775    }
1776
1777    final void updateLruProcessLocked(ProcessRecord app,
1778            boolean oomAdj, boolean updateActivityTime) {
1779        mLruSeq++;
1780        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1781    }
1782
1783    final ProcessRecord getProcessRecordLocked(
1784            String processName, int uid) {
1785        if (uid == Process.SYSTEM_UID) {
1786            // The system gets to run in any process.  If there are multiple
1787            // processes with the same uid, just pick the first (this
1788            // should never happen).
1789            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1790                    processName);
1791            return procs != null ? procs.valueAt(0) : null;
1792        }
1793        ProcessRecord proc = mProcessNames.get(processName, uid);
1794        return proc;
1795    }
1796
1797    void ensurePackageDexOpt(String packageName) {
1798        IPackageManager pm = AppGlobals.getPackageManager();
1799        try {
1800            if (pm.performDexOpt(packageName)) {
1801                mDidDexOpt = true;
1802            }
1803        } catch (RemoteException e) {
1804        }
1805    }
1806
1807    boolean isNextTransitionForward() {
1808        int transit = mWindowManager.getPendingAppTransition();
1809        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1810                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1811                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1812    }
1813
1814    final ProcessRecord startProcessLocked(String processName,
1815            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1816            String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
1817        ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1818        // We don't have to do anything more if:
1819        // (1) There is an existing application record; and
1820        // (2) The caller doesn't think it is dead, OR there is no thread
1821        //     object attached to it so we know it couldn't have crashed; and
1822        // (3) There is a pid assigned to it, so it is either starting or
1823        //     already running.
1824        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1825                + " app=" + app + " knownToBeDead=" + knownToBeDead
1826                + " thread=" + (app != null ? app.thread : null)
1827                + " pid=" + (app != null ? app.pid : -1));
1828        if (app != null && app.pid > 0) {
1829            if (!knownToBeDead || app.thread == null) {
1830                // We already have the app running, or are waiting for it to
1831                // come up (we have a pid but not yet its thread), so keep it.
1832                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1833                // If this is a new package in the process, add the package to the list
1834                app.addPackage(info.packageName);
1835                return app;
1836            } else {
1837                // An application record is attached to a previous process,
1838                // clean it up now.
1839                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1840                handleAppDiedLocked(app, true);
1841            }
1842        }
1843
1844        String hostingNameStr = hostingName != null
1845                ? hostingName.flattenToShortString() : null;
1846
1847        if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1848            // If we are in the background, then check to see if this process
1849            // is bad.  If so, we will just silently fail.
1850            if (mBadProcesses.get(info.processName, info.uid) != null) {
1851                if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1852                        + "/" + info.processName);
1853                return null;
1854            }
1855        } else {
1856            // When the user is explicitly starting a process, then clear its
1857            // crash count so that we won't make it bad until they see at
1858            // least one crash dialog again, and make the process good again
1859            // if it had been bad.
1860            if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1861                    + "/" + info.processName);
1862            mProcessCrashTimes.remove(info.processName, info.uid);
1863            if (mBadProcesses.get(info.processName, info.uid) != null) {
1864                EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1865                        info.processName);
1866                mBadProcesses.remove(info.processName, info.uid);
1867                if (app != null) {
1868                    app.bad = false;
1869                }
1870            }
1871        }
1872
1873        if (app == null) {
1874            app = newProcessRecordLocked(null, info, processName);
1875            mProcessNames.put(processName, info.uid, app);
1876        } else {
1877            // If this is a new package in the process, add the package to the list
1878            app.addPackage(info.packageName);
1879        }
1880
1881        // If the system is not ready yet, then hold off on starting this
1882        // process until it is.
1883        if (!mProcessesReady
1884                && !isAllowedWhileBooting(info)
1885                && !allowWhileBooting) {
1886            if (!mProcessesOnHold.contains(app)) {
1887                mProcessesOnHold.add(app);
1888            }
1889            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1890            return app;
1891        }
1892
1893        startProcessLocked(app, hostingType, hostingNameStr);
1894        return (app.pid != 0) ? app : null;
1895    }
1896
1897    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1898        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1899    }
1900
1901    private final void startProcessLocked(ProcessRecord app,
1902            String hostingType, String hostingNameStr) {
1903        if (app.pid > 0 && app.pid != MY_PID) {
1904            synchronized (mPidsSelfLocked) {
1905                mPidsSelfLocked.remove(app.pid);
1906                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1907            }
1908            app.pid = 0;
1909        }
1910
1911        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1912                "startProcessLocked removing on hold: " + app);
1913        mProcessesOnHold.remove(app);
1914
1915        updateCpuStats();
1916
1917        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1918        mProcDeaths[0] = 0;
1919
1920        try {
1921            int uid = app.info.uid;
1922            int[] gids = null;
1923            try {
1924                gids = mContext.getPackageManager().getPackageGids(
1925                        app.info.packageName);
1926            } catch (PackageManager.NameNotFoundException e) {
1927                Slog.w(TAG, "Unable to retrieve gids", e);
1928            }
1929            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1930                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1931                        && mTopComponent != null
1932                        && app.processName.equals(mTopComponent.getPackageName())) {
1933                    uid = 0;
1934                }
1935                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1936                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1937                    uid = 0;
1938                }
1939            }
1940            int debugFlags = 0;
1941            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1942                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1943                // Also turn on CheckJNI for debuggable apps. It's quite
1944                // awkward to turn on otherwise.
1945                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1946            }
1947            // Run the app in safe mode if its manifest requests so or the
1948            // system is booted in safe mode.
1949            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1950                Zygote.systemInSafeMode == true) {
1951                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1952            }
1953            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1954                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1955            }
1956            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1957                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1958            }
1959            if ("1".equals(SystemProperties.get("debug.assert"))) {
1960                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1961            }
1962            int pid = Process.start("android.app.ActivityThread",
1963                    app.processName, uid, uid, gids, debugFlags,
1964                    app.info.targetSdkVersion, null);
1965            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1966            synchronized (bs) {
1967                if (bs.isOnBattery()) {
1968                    app.batteryStats.incStartsLocked();
1969                }
1970            }
1971
1972            EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
1973                    app.processName, hostingType,
1974                    hostingNameStr != null ? hostingNameStr : "");
1975
1976            if (app.persistent) {
1977                Watchdog.getInstance().processStarted(app.processName, pid);
1978            }
1979
1980            StringBuilder buf = mStringBuilder;
1981            buf.setLength(0);
1982            buf.append("Start proc ");
1983            buf.append(app.processName);
1984            buf.append(" for ");
1985            buf.append(hostingType);
1986            if (hostingNameStr != null) {
1987                buf.append(" ");
1988                buf.append(hostingNameStr);
1989            }
1990            buf.append(": pid=");
1991            buf.append(pid);
1992            buf.append(" uid=");
1993            buf.append(uid);
1994            buf.append(" gids={");
1995            if (gids != null) {
1996                for (int gi=0; gi<gids.length; gi++) {
1997                    if (gi != 0) buf.append(", ");
1998                    buf.append(gids[gi]);
1999
2000                }
2001            }
2002            buf.append("}");
2003            Slog.i(TAG, buf.toString());
2004            if (pid == 0 || pid == MY_PID) {
2005                // Processes are being emulated with threads.
2006                app.pid = MY_PID;
2007                app.removed = false;
2008                mStartingProcesses.add(app);
2009            } else if (pid > 0) {
2010                app.pid = pid;
2011                app.removed = false;
2012                synchronized (mPidsSelfLocked) {
2013                    this.mPidsSelfLocked.put(pid, app);
2014                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2015                    msg.obj = app;
2016                    mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
2017                }
2018            } else {
2019                app.pid = 0;
2020                RuntimeException e = new RuntimeException(
2021                        "Failure starting process " + app.processName
2022                        + ": returned pid=" + pid);
2023                Slog.e(TAG, e.getMessage(), e);
2024            }
2025        } catch (RuntimeException e) {
2026            // XXX do better error recovery.
2027            app.pid = 0;
2028            Slog.e(TAG, "Failure starting process " + app.processName, e);
2029        }
2030    }
2031
2032    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2033        if (resumed) {
2034            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2035        } else {
2036            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2037        }
2038    }
2039
2040    boolean startHomeActivityLocked() {
2041        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2042                && mTopAction == null) {
2043            // We are running in factory test mode, but unable to find
2044            // the factory test app, so just sit around displaying the
2045            // error message and don't try to start anything.
2046            return false;
2047        }
2048        Intent intent = new Intent(
2049            mTopAction,
2050            mTopData != null ? Uri.parse(mTopData) : null);
2051        intent.setComponent(mTopComponent);
2052        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2053            intent.addCategory(Intent.CATEGORY_HOME);
2054        }
2055        ActivityInfo aInfo =
2056            intent.resolveActivityInfo(mContext.getPackageManager(),
2057                    STOCK_PM_FLAGS);
2058        if (aInfo != null) {
2059            intent.setComponent(new ComponentName(
2060                    aInfo.applicationInfo.packageName, aInfo.name));
2061            // Don't do this if the home app is currently being
2062            // instrumented.
2063            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2064                    aInfo.applicationInfo.uid);
2065            if (app == null || app.instrumentationClass == null) {
2066                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2067                mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
2068                        null, null, 0, 0, 0, false, false, null);
2069            }
2070        }
2071
2072
2073        return true;
2074    }
2075
2076    /**
2077     * Starts the "new version setup screen" if appropriate.
2078     */
2079    void startSetupActivityLocked() {
2080        // Only do this once per boot.
2081        if (mCheckedForSetup) {
2082            return;
2083        }
2084
2085        // We will show this screen if the current one is a different
2086        // version than the last one shown, and we are not running in
2087        // low-level factory test mode.
2088        final ContentResolver resolver = mContext.getContentResolver();
2089        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2090                Settings.Secure.getInt(resolver,
2091                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2092            mCheckedForSetup = true;
2093
2094            // See if we should be showing the platform update setup UI.
2095            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2096            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2097                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2098
2099            // We don't allow third party apps to replace this.
2100            ResolveInfo ri = null;
2101            for (int i=0; ris != null && i<ris.size(); i++) {
2102                if ((ris.get(i).activityInfo.applicationInfo.flags
2103                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2104                    ri = ris.get(i);
2105                    break;
2106                }
2107            }
2108
2109            if (ri != null) {
2110                String vers = ri.activityInfo.metaData != null
2111                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2112                        : null;
2113                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2114                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2115                            Intent.METADATA_SETUP_VERSION);
2116                }
2117                String lastVers = Settings.Secure.getString(
2118                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2119                if (vers != null && !vers.equals(lastVers)) {
2120                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2121                    intent.setComponent(new ComponentName(
2122                            ri.activityInfo.packageName, ri.activityInfo.name));
2123                    mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
2124                            null, null, 0, 0, 0, false, false, null);
2125                }
2126            }
2127        }
2128    }
2129
2130    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2131        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2132    }
2133
2134    public int getFrontActivityScreenCompatMode() {
2135        synchronized (this) {
2136            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2137        }
2138    }
2139
2140    public void setFrontActivityScreenCompatMode(int mode) {
2141        synchronized (this) {
2142            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2143        }
2144    }
2145
2146    public int getPackageScreenCompatMode(String packageName) {
2147        synchronized (this) {
2148            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2149        }
2150    }
2151
2152    public void setPackageScreenCompatMode(String packageName, int mode) {
2153        synchronized (this) {
2154            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2155        }
2156    }
2157
2158    public boolean getPackageAskScreenCompat(String packageName) {
2159        synchronized (this) {
2160            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2161        }
2162    }
2163
2164    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2165        synchronized (this) {
2166            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2167        }
2168    }
2169
2170    void reportResumedActivityLocked(ActivityRecord r) {
2171        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2172
2173        final int identHash = System.identityHashCode(r);
2174        updateUsageStats(r, true);
2175
2176        int i = mWatchers.beginBroadcast();
2177        while (i > 0) {
2178            i--;
2179            IActivityWatcher w = mWatchers.getBroadcastItem(i);
2180            if (w != null) {
2181                try {
2182                    w.activityResuming(identHash);
2183                } catch (RemoteException e) {
2184                }
2185            }
2186        }
2187        mWatchers.finishBroadcast();
2188    }
2189
2190    private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2191        int i = mProcessObservers.beginBroadcast();
2192        while (i > 0) {
2193            i--;
2194            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2195            if (observer != null) {
2196                try {
2197                    observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2198                } catch (RemoteException e) {
2199                }
2200            }
2201        }
2202        mProcessObservers.finishBroadcast();
2203    }
2204
2205    private void dispatchProcessDied(int pid, int uid) {
2206        int i = mProcessObservers.beginBroadcast();
2207        while (i > 0) {
2208            i--;
2209            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2210            if (observer != null) {
2211                try {
2212                    observer.onProcessDied(pid, uid);
2213                } catch (RemoteException e) {
2214                }
2215            }
2216        }
2217        mProcessObservers.finishBroadcast();
2218    }
2219
2220    final void doPendingActivityLaunchesLocked(boolean doResume) {
2221        final int N = mPendingActivityLaunches.size();
2222        if (N <= 0) {
2223            return;
2224        }
2225        for (int i=0; i<N; i++) {
2226            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2227            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2228                    pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2229                    doResume && i == (N-1));
2230        }
2231        mPendingActivityLaunches.clear();
2232    }
2233
2234    public final int startActivity(IApplicationThread caller,
2235            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2236            int grantedMode, IBinder resultTo,
2237            String resultWho, int requestCode, boolean onlyIfNeeded,
2238            boolean debug) {
2239        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2240                grantedUriPermissions, grantedMode, resultTo, resultWho,
2241                requestCode, onlyIfNeeded, debug, null, null);
2242    }
2243
2244    public final WaitResult startActivityAndWait(IApplicationThread caller,
2245            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2246            int grantedMode, IBinder resultTo,
2247            String resultWho, int requestCode, boolean onlyIfNeeded,
2248            boolean debug) {
2249        WaitResult res = new WaitResult();
2250        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2251                grantedUriPermissions, grantedMode, resultTo, resultWho,
2252                requestCode, onlyIfNeeded, debug, res, null);
2253        return res;
2254    }
2255
2256    public final int startActivityWithConfig(IApplicationThread caller,
2257            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2258            int grantedMode, IBinder resultTo,
2259            String resultWho, int requestCode, boolean onlyIfNeeded,
2260            boolean debug, Configuration config) {
2261        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2262                grantedUriPermissions, grantedMode, resultTo, resultWho,
2263                requestCode, onlyIfNeeded, debug, null, config);
2264    }
2265
2266    public int startActivityIntentSender(IApplicationThread caller,
2267            IntentSender intent, Intent fillInIntent, String resolvedType,
2268            IBinder resultTo, String resultWho, int requestCode,
2269            int flagsMask, int flagsValues) {
2270        // Refuse possible leaked file descriptors
2271        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2272            throw new IllegalArgumentException("File descriptors passed in Intent");
2273        }
2274
2275        IIntentSender sender = intent.getTarget();
2276        if (!(sender instanceof PendingIntentRecord)) {
2277            throw new IllegalArgumentException("Bad PendingIntent object");
2278        }
2279
2280        PendingIntentRecord pir = (PendingIntentRecord)sender;
2281
2282        synchronized (this) {
2283            // If this is coming from the currently resumed activity, it is
2284            // effectively saying that app switches are allowed at this point.
2285            if (mMainStack.mResumedActivity != null
2286                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2287                            Binder.getCallingUid()) {
2288                mAppSwitchesAllowedTime = 0;
2289            }
2290        }
2291
2292        return pir.sendInner(0, fillInIntent, resolvedType, null,
2293                null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2294    }
2295
2296    public boolean startNextMatchingActivity(IBinder callingActivity,
2297            Intent intent) {
2298        // Refuse possible leaked file descriptors
2299        if (intent != null && intent.hasFileDescriptors() == true) {
2300            throw new IllegalArgumentException("File descriptors passed in Intent");
2301        }
2302
2303        synchronized (this) {
2304            int index = mMainStack.indexOfTokenLocked(callingActivity);
2305            if (index < 0) {
2306                return false;
2307            }
2308            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
2309            if (r.app == null || r.app.thread == null) {
2310                // The caller is not running...  d'oh!
2311                return false;
2312            }
2313            intent = new Intent(intent);
2314            // The caller is not allowed to change the data.
2315            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2316            // And we are resetting to find the next component...
2317            intent.setComponent(null);
2318
2319            ActivityInfo aInfo = null;
2320            try {
2321                List<ResolveInfo> resolves =
2322                    AppGlobals.getPackageManager().queryIntentActivities(
2323                            intent, r.resolvedType,
2324                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
2325
2326                // Look for the original activity in the list...
2327                final int N = resolves != null ? resolves.size() : 0;
2328                for (int i=0; i<N; i++) {
2329                    ResolveInfo rInfo = resolves.get(i);
2330                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2331                            && rInfo.activityInfo.name.equals(r.info.name)) {
2332                        // We found the current one...  the next matching is
2333                        // after it.
2334                        i++;
2335                        if (i<N) {
2336                            aInfo = resolves.get(i).activityInfo;
2337                        }
2338                        break;
2339                    }
2340                }
2341            } catch (RemoteException e) {
2342            }
2343
2344            if (aInfo == null) {
2345                // Nobody who is next!
2346                return false;
2347            }
2348
2349            intent.setComponent(new ComponentName(
2350                    aInfo.applicationInfo.packageName, aInfo.name));
2351            intent.setFlags(intent.getFlags()&~(
2352                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2353                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2354                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2355                    Intent.FLAG_ACTIVITY_NEW_TASK));
2356
2357            // Okay now we need to start the new activity, replacing the
2358            // currently running activity.  This is a little tricky because
2359            // we want to start the new one as if the current one is finished,
2360            // but not finish the current one first so that there is no flicker.
2361            // And thus...
2362            final boolean wasFinishing = r.finishing;
2363            r.finishing = true;
2364
2365            // Propagate reply information over to the new activity.
2366            final ActivityRecord resultTo = r.resultTo;
2367            final String resultWho = r.resultWho;
2368            final int requestCode = r.requestCode;
2369            r.resultTo = null;
2370            if (resultTo != null) {
2371                resultTo.removeResultsLocked(r, resultWho, requestCode);
2372            }
2373
2374            final long origId = Binder.clearCallingIdentity();
2375            // XXX we are not dealing with propagating grantedUriPermissions...
2376            // those are not yet exposed to user code, so there is no need.
2377            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2378                    r.resolvedType, null, 0, aInfo, resultTo, resultWho,
2379                    requestCode, -1, r.launchedFromUid, false, false, null);
2380            Binder.restoreCallingIdentity(origId);
2381
2382            r.finishing = wasFinishing;
2383            if (res != START_SUCCESS) {
2384                return false;
2385            }
2386            return true;
2387        }
2388    }
2389
2390    public final int startActivityInPackage(int uid,
2391            Intent intent, String resolvedType, IBinder resultTo,
2392            String resultWho, int requestCode, boolean onlyIfNeeded) {
2393
2394        // This is so super not safe, that only the system (or okay root)
2395        // can do it.
2396        final int callingUid = Binder.getCallingUid();
2397        if (callingUid != 0 && callingUid != Process.myUid()) {
2398            throw new SecurityException(
2399                    "startActivityInPackage only available to the system");
2400        }
2401
2402        return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2403                null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false, null, null);
2404    }
2405
2406    public final int startActivities(IApplicationThread caller,
2407            Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2408        return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2409    }
2410
2411    public final int startActivitiesInPackage(int uid,
2412            Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2413
2414        // This is so super not safe, that only the system (or okay root)
2415        // can do it.
2416        final int callingUid = Binder.getCallingUid();
2417        if (callingUid != 0 && callingUid != Process.myUid()) {
2418            throw new SecurityException(
2419                    "startActivityInPackage only available to the system");
2420        }
2421
2422        return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
2423    }
2424
2425    final void addRecentTaskLocked(TaskRecord task) {
2426        int N = mRecentTasks.size();
2427        // Quick case: check if the top-most recent task is the same.
2428        if (N > 0 && mRecentTasks.get(0) == task) {
2429            return;
2430        }
2431        // Remove any existing entries that are the same kind of task.
2432        for (int i=0; i<N; i++) {
2433            TaskRecord tr = mRecentTasks.get(i);
2434            if ((task.affinity != null && task.affinity.equals(tr.affinity))
2435                    || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2436                mRecentTasks.remove(i);
2437                i--;
2438                N--;
2439                if (task.intent == null) {
2440                    // If the new recent task we are adding is not fully
2441                    // specified, then replace it with the existing recent task.
2442                    task = tr;
2443                }
2444            }
2445        }
2446        if (N >= MAX_RECENT_TASKS) {
2447            mRecentTasks.remove(N-1);
2448        }
2449        mRecentTasks.add(0, task);
2450    }
2451
2452    public void setRequestedOrientation(IBinder token,
2453            int requestedOrientation) {
2454        synchronized (this) {
2455            int index = mMainStack.indexOfTokenLocked(token);
2456            if (index < 0) {
2457                return;
2458            }
2459            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
2460            final long origId = Binder.clearCallingIdentity();
2461            mWindowManager.setAppOrientation(r, requestedOrientation);
2462            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2463                    mConfiguration,
2464                    r.mayFreezeScreenLocked(r.app) ? r : null);
2465            if (config != null) {
2466                r.frozenBeforeDestroy = true;
2467                if (!updateConfigurationLocked(config, r)) {
2468                    mMainStack.resumeTopActivityLocked(null);
2469                }
2470            }
2471            Binder.restoreCallingIdentity(origId);
2472        }
2473    }
2474
2475    public int getRequestedOrientation(IBinder token) {
2476        synchronized (this) {
2477            int index = mMainStack.indexOfTokenLocked(token);
2478            if (index < 0) {
2479                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2480            }
2481            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
2482            return mWindowManager.getAppOrientation(r);
2483        }
2484    }
2485
2486    /**
2487     * This is the internal entry point for handling Activity.finish().
2488     *
2489     * @param token The Binder token referencing the Activity we want to finish.
2490     * @param resultCode Result code, if any, from this Activity.
2491     * @param resultData Result data (Intent), if any, from this Activity.
2492     *
2493     * @return Returns true if the activity successfully finished, or false if it is still running.
2494     */
2495    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2496        // Refuse possible leaked file descriptors
2497        if (resultData != null && resultData.hasFileDescriptors() == true) {
2498            throw new IllegalArgumentException("File descriptors passed in Intent");
2499        }
2500
2501        synchronized(this) {
2502            if (mController != null) {
2503                // Find the first activity that is not finishing.
2504                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2505                if (next != null) {
2506                    // ask watcher if this is allowed
2507                    boolean resumeOK = true;
2508                    try {
2509                        resumeOK = mController.activityResuming(next.packageName);
2510                    } catch (RemoteException e) {
2511                        mController = null;
2512                    }
2513
2514                    if (!resumeOK) {
2515                        return false;
2516                    }
2517                }
2518            }
2519            final long origId = Binder.clearCallingIdentity();
2520            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2521                    resultData, "app-request");
2522            Binder.restoreCallingIdentity(origId);
2523            return res;
2524        }
2525    }
2526
2527    public final void finishHeavyWeightApp() {
2528        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2529                != PackageManager.PERMISSION_GRANTED) {
2530            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2531                    + Binder.getCallingPid()
2532                    + ", uid=" + Binder.getCallingUid()
2533                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2534            Slog.w(TAG, msg);
2535            throw new SecurityException(msg);
2536        }
2537
2538        synchronized(this) {
2539            if (mHeavyWeightProcess == null) {
2540                return;
2541            }
2542
2543            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2544                    mHeavyWeightProcess.activities);
2545            for (int i=0; i<activities.size(); i++) {
2546                ActivityRecord r = activities.get(i);
2547                if (!r.finishing) {
2548                    int index = mMainStack.indexOfTokenLocked(r);
2549                    if (index >= 0) {
2550                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2551                                null, "finish-heavy");
2552                    }
2553                }
2554            }
2555
2556            mHeavyWeightProcess = null;
2557            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2558        }
2559    }
2560
2561    public void crashApplication(int uid, int initialPid, String packageName,
2562            String message) {
2563        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2564                != PackageManager.PERMISSION_GRANTED) {
2565            String msg = "Permission Denial: crashApplication() from pid="
2566                    + Binder.getCallingPid()
2567                    + ", uid=" + Binder.getCallingUid()
2568                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2569            Slog.w(TAG, msg);
2570            throw new SecurityException(msg);
2571        }
2572
2573        synchronized(this) {
2574            ProcessRecord proc = null;
2575
2576            // Figure out which process to kill.  We don't trust that initialPid
2577            // still has any relation to current pids, so must scan through the
2578            // list.
2579            synchronized (mPidsSelfLocked) {
2580                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2581                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2582                    if (p.info.uid != uid) {
2583                        continue;
2584                    }
2585                    if (p.pid == initialPid) {
2586                        proc = p;
2587                        break;
2588                    }
2589                    for (String str : p.pkgList) {
2590                        if (str.equals(packageName)) {
2591                            proc = p;
2592                        }
2593                    }
2594                }
2595            }
2596
2597            if (proc == null) {
2598                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2599                        + " initialPid=" + initialPid
2600                        + " packageName=" + packageName);
2601                return;
2602            }
2603
2604            if (proc.thread != null) {
2605                if (proc.pid == Process.myPid()) {
2606                    Log.w(TAG, "crashApplication: trying to crash self!");
2607                    return;
2608                }
2609                long ident = Binder.clearCallingIdentity();
2610                try {
2611                    proc.thread.scheduleCrash(message);
2612                } catch (RemoteException e) {
2613                }
2614                Binder.restoreCallingIdentity(ident);
2615            }
2616        }
2617    }
2618
2619    public final void finishSubActivity(IBinder token, String resultWho,
2620            int requestCode) {
2621        synchronized(this) {
2622            int index = mMainStack.indexOfTokenLocked(token);
2623            if (index < 0) {
2624                return;
2625            }
2626            ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
2627
2628            final long origId = Binder.clearCallingIdentity();
2629
2630            int i;
2631            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2632                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2633                if (r.resultTo == self && r.requestCode == requestCode) {
2634                    if ((r.resultWho == null && resultWho == null) ||
2635                        (r.resultWho != null && r.resultWho.equals(resultWho))) {
2636                        mMainStack.finishActivityLocked(r, i,
2637                                Activity.RESULT_CANCELED, null, "request-sub");
2638                    }
2639                }
2640            }
2641
2642            Binder.restoreCallingIdentity(origId);
2643        }
2644    }
2645
2646    public boolean willActivityBeVisible(IBinder token) {
2647        synchronized(this) {
2648            int i;
2649            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2650                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2651                if (r == token) {
2652                    return true;
2653                }
2654                if (r.fullscreen && !r.finishing) {
2655                    return false;
2656                }
2657            }
2658            return true;
2659        }
2660    }
2661
2662    public void overridePendingTransition(IBinder token, String packageName,
2663            int enterAnim, int exitAnim) {
2664        synchronized(this) {
2665            int index = mMainStack.indexOfTokenLocked(token);
2666            if (index < 0) {
2667                return;
2668            }
2669            ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
2670
2671            final long origId = Binder.clearCallingIdentity();
2672
2673            if (self.state == ActivityState.RESUMED
2674                    || self.state == ActivityState.PAUSING) {
2675                mWindowManager.overridePendingAppTransition(packageName,
2676                        enterAnim, exitAnim);
2677            }
2678
2679            Binder.restoreCallingIdentity(origId);
2680        }
2681    }
2682
2683    /**
2684     * Main function for removing an existing process from the activity manager
2685     * as a result of that process going away.  Clears out all connections
2686     * to the process.
2687     */
2688    private final void handleAppDiedLocked(ProcessRecord app,
2689            boolean restarting) {
2690        cleanUpApplicationRecordLocked(app, restarting, -1);
2691        if (!restarting) {
2692            mLruProcesses.remove(app);
2693        }
2694
2695        // Just in case...
2696        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2697            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2698            mMainStack.mPausingActivity = null;
2699        }
2700        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2701            mMainStack.mLastPausedActivity = null;
2702        }
2703
2704        // Remove this application's activities from active lists.
2705        mMainStack.removeHistoryRecordsForAppLocked(app);
2706
2707        boolean atTop = true;
2708        boolean hasVisibleActivities = false;
2709
2710        // Clean out the history list.
2711        int i = mMainStack.mHistory.size();
2712        if (localLOGV) Slog.v(
2713            TAG, "Removing app " + app + " from history with " + i + " entries");
2714        while (i > 0) {
2715            i--;
2716            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2717            if (localLOGV) Slog.v(
2718                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2719            if (r.app == app) {
2720                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2721                    if (localLOGV) Slog.v(
2722                        TAG, "Removing this entry!  frozen=" + r.haveState
2723                        + " finishing=" + r.finishing);
2724                    r.makeFinishing();
2725                    mMainStack.mHistory.remove(i);
2726                    r.takeFromHistory();
2727                    mWindowManager.removeAppToken(r);
2728                    if (VALIDATE_TOKENS) {
2729                        mWindowManager.validateAppTokens(mMainStack.mHistory);
2730                    }
2731                    r.removeUriPermissionsLocked();
2732
2733                } else {
2734                    // We have the current state for this activity, so
2735                    // it can be restarted later when needed.
2736                    if (localLOGV) Slog.v(
2737                        TAG, "Keeping entry, setting app to null");
2738                    if (r.visible) {
2739                        hasVisibleActivities = true;
2740                    }
2741                    r.app = null;
2742                    r.nowVisible = false;
2743                    if (!r.haveState) {
2744                        r.icicle = null;
2745                    }
2746                }
2747
2748                r.stack.cleanUpActivityLocked(r, true);
2749                r.state = ActivityState.STOPPED;
2750            }
2751            atTop = false;
2752        }
2753
2754        app.activities.clear();
2755
2756        if (app.instrumentationClass != null) {
2757            Slog.w(TAG, "Crash of app " + app.processName
2758                  + " running instrumentation " + app.instrumentationClass);
2759            Bundle info = new Bundle();
2760            info.putString("shortMsg", "Process crashed.");
2761            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2762        }
2763
2764        if (!restarting) {
2765            if (!mMainStack.resumeTopActivityLocked(null)) {
2766                // If there was nothing to resume, and we are not already
2767                // restarting this process, but there is a visible activity that
2768                // is hosted by the process...  then make sure all visible
2769                // activities are running, taking care of restarting this
2770                // process.
2771                if (hasVisibleActivities) {
2772                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2773                }
2774            }
2775        }
2776    }
2777
2778    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2779        IBinder threadBinder = thread.asBinder();
2780
2781        // Find the application record.
2782        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2783            ProcessRecord rec = mLruProcesses.get(i);
2784            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2785                return i;
2786            }
2787        }
2788        return -1;
2789    }
2790
2791    final ProcessRecord getRecordForAppLocked(
2792            IApplicationThread thread) {
2793        if (thread == null) {
2794            return null;
2795        }
2796
2797        int appIndex = getLRURecordIndexForAppLocked(thread);
2798        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2799    }
2800
2801    final void appDiedLocked(ProcessRecord app, int pid,
2802            IApplicationThread thread) {
2803
2804        mProcDeaths[0]++;
2805
2806        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2807        synchronized (stats) {
2808            stats.noteProcessDiedLocked(app.info.uid, pid);
2809        }
2810
2811        // Clean up already done if the process has been re-started.
2812        if (app.pid == pid && app.thread != null &&
2813                app.thread.asBinder() == thread.asBinder()) {
2814            if (!app.killedBackground) {
2815                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2816                        + ") has died.");
2817            }
2818            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2819            if (localLOGV) Slog.v(
2820                TAG, "Dying app: " + app + ", pid: " + pid
2821                + ", thread: " + thread.asBinder());
2822            boolean doLowMem = app.instrumentationClass == null;
2823            handleAppDiedLocked(app, false);
2824
2825            if (doLowMem) {
2826                // If there are no longer any background processes running,
2827                // and the app that died was not running instrumentation,
2828                // then tell everyone we are now low on memory.
2829                boolean haveBg = false;
2830                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2831                    ProcessRecord rec = mLruProcesses.get(i);
2832                    if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
2833                        haveBg = true;
2834                        break;
2835                    }
2836                }
2837
2838                if (!haveBg) {
2839                    Slog.i(TAG, "Low Memory: No more background processes.");
2840                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2841                    long now = SystemClock.uptimeMillis();
2842                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2843                        ProcessRecord rec = mLruProcesses.get(i);
2844                        if (rec != app && rec.thread != null &&
2845                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2846                            // The low memory report is overriding any current
2847                            // state for a GC request.  Make sure to do
2848                            // heavy/important/visible/foreground processes first.
2849                            if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) {
2850                                rec.lastRequestedGc = 0;
2851                            } else {
2852                                rec.lastRequestedGc = rec.lastLowMemory;
2853                            }
2854                            rec.reportLowMemory = true;
2855                            rec.lastLowMemory = now;
2856                            mProcessesToGc.remove(rec);
2857                            addProcessToGcListLocked(rec);
2858                        }
2859                    }
2860                    scheduleAppGcsLocked();
2861                }
2862            }
2863        } else if (app.pid != pid) {
2864            // A new process has already been started.
2865            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2866                    + ") has died and restarted (pid " + app.pid + ").");
2867            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2868        } else if (DEBUG_PROCESSES) {
2869            Slog.d(TAG, "Received spurious death notification for thread "
2870                    + thread.asBinder());
2871        }
2872    }
2873
2874    /**
2875     * If a stack trace dump file is configured, dump process stack traces.
2876     * @param clearTraces causes the dump file to be erased prior to the new
2877     *    traces being written, if true; when false, the new traces will be
2878     *    appended to any existing file content.
2879     * @param firstPids of dalvik VM processes to dump stack traces for first
2880     * @param lastPids of dalvik VM processes to dump stack traces for last
2881     * @return file containing stack traces, or null if no dump file is configured
2882     */
2883    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2884            ProcessStats processStats, SparseArray<Boolean> lastPids) {
2885        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2886        if (tracesPath == null || tracesPath.length() == 0) {
2887            return null;
2888        }
2889
2890        File tracesFile = new File(tracesPath);
2891        try {
2892            File tracesDir = tracesFile.getParentFile();
2893            if (!tracesDir.exists()) tracesFile.mkdirs();
2894            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
2895
2896            if (clearTraces && tracesFile.exists()) tracesFile.delete();
2897            tracesFile.createNewFile();
2898            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2899        } catch (IOException e) {
2900            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
2901            return null;
2902        }
2903
2904        // Use a FileObserver to detect when traces finish writing.
2905        // The order of traces is considered important to maintain for legibility.
2906        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2907            public synchronized void onEvent(int event, String path) { notify(); }
2908        };
2909
2910        try {
2911            observer.startWatching();
2912
2913            // First collect all of the stacks of the most important pids.
2914            try {
2915                int num = firstPids.size();
2916                for (int i = 0; i < num; i++) {
2917                    synchronized (observer) {
2918                        Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2919                        observer.wait(200);  // Wait for write-close, give up after 200msec
2920                    }
2921                }
2922            } catch (InterruptedException e) {
2923                Log.wtf(TAG, e);
2924            }
2925
2926            // Next measure CPU usage.
2927            if (processStats != null) {
2928                processStats.init();
2929                System.gc();
2930                processStats.update();
2931                try {
2932                    synchronized (processStats) {
2933                        processStats.wait(500); // measure over 1/2 second.
2934                    }
2935                } catch (InterruptedException e) {
2936                }
2937                processStats.update();
2938
2939                // We'll take the stack crawls of just the top apps using CPU.
2940                final int N = processStats.countWorkingStats();
2941                int numProcs = 0;
2942                for (int i=0; i<N && numProcs<5; i++) {
2943                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
2944                    if (lastPids.indexOfKey(stats.pid) >= 0) {
2945                        numProcs++;
2946                        try {
2947                            synchronized (observer) {
2948                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2949                                observer.wait(200);  // Wait for write-close, give up after 200msec
2950                            }
2951                        } catch (InterruptedException e) {
2952                            Log.wtf(TAG, e);
2953                        }
2954
2955                    }
2956                }
2957            }
2958
2959            return tracesFile;
2960
2961        } finally {
2962            observer.stopWatching();
2963        }
2964    }
2965
2966    private final class AppNotResponding implements Runnable {
2967        private final ProcessRecord mApp;
2968        private final String mAnnotation;
2969
2970        public AppNotResponding(ProcessRecord app, String annotation) {
2971            mApp = app;
2972            mAnnotation = annotation;
2973        }
2974
2975        @Override
2976        public void run() {
2977            appNotResponding(mApp, null, null, mAnnotation);
2978        }
2979    }
2980
2981    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2982            ActivityRecord parent, final String annotation) {
2983        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2984        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2985
2986        if (mController != null) {
2987            try {
2988                // 0 == continue, -1 = kill process immediately
2989                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2990                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2991            } catch (RemoteException e) {
2992                mController = null;
2993            }
2994        }
2995
2996        long anrTime = SystemClock.uptimeMillis();
2997        if (MONITOR_CPU_USAGE) {
2998            updateCpuStatsNow();
2999        }
3000
3001        synchronized (this) {
3002            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3003            if (mShuttingDown) {
3004                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3005                return;
3006            } else if (app.notResponding) {
3007                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3008                return;
3009            } else if (app.crashing) {
3010                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3011                return;
3012            }
3013
3014            // In case we come through here for the same app before completing
3015            // this one, mark as anring now so we will bail out.
3016            app.notResponding = true;
3017
3018            // Log the ANR to the event log.
3019            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3020                    annotation);
3021
3022            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3023            firstPids.add(app.pid);
3024
3025            int parentPid = app.pid;
3026            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3027            if (parentPid != app.pid) firstPids.add(parentPid);
3028
3029            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3030
3031            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3032                ProcessRecord r = mLruProcesses.get(i);
3033                if (r != null && r.thread != null) {
3034                    int pid = r.pid;
3035                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3036                        if (r.persistent) {
3037                            firstPids.add(pid);
3038                        } else {
3039                            lastPids.put(pid, Boolean.TRUE);
3040                        }
3041                    }
3042                }
3043            }
3044        }
3045
3046        // Log the ANR to the main log.
3047        StringBuilder info = mStringBuilder;
3048        info.setLength(0);
3049        info.append("ANR in ").append(app.processName);
3050        if (activity != null && activity.shortComponentName != null) {
3051            info.append(" (").append(activity.shortComponentName).append(")");
3052        }
3053        info.append("\n");
3054        if (annotation != null) {
3055            info.append("Reason: ").append(annotation).append("\n");
3056        }
3057        if (parent != null && parent != activity) {
3058            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3059        }
3060
3061        final ProcessStats processStats = new ProcessStats(true);
3062
3063        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3064
3065        String cpuInfo = null;
3066        if (MONITOR_CPU_USAGE) {
3067            updateCpuStatsNow();
3068            synchronized (mProcessStatsThread) {
3069                cpuInfo = mProcessStats.printCurrentState(anrTime);
3070            }
3071            info.append(processStats.printCurrentLoad());
3072            info.append(cpuInfo);
3073        }
3074
3075        info.append(processStats.printCurrentState(anrTime));
3076
3077        Slog.e(TAG, info.toString());
3078        if (tracesFile == null) {
3079            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3080            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3081        }
3082
3083        addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
3084
3085        if (mController != null) {
3086            try {
3087                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3088                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3089                if (res != 0) {
3090                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3091                    return;
3092                }
3093            } catch (RemoteException e) {
3094                mController = null;
3095            }
3096        }
3097
3098        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3099        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3100                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3101
3102        synchronized (this) {
3103            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3104                Slog.w(TAG, "Killing " + app + ": background ANR");
3105                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3106                        app.processName, app.setAdj, "background ANR");
3107                Process.killProcessQuiet(app.pid);
3108                return;
3109            }
3110
3111            // Set the app's notResponding state, and look up the errorReportReceiver
3112            makeAppNotRespondingLocked(app,
3113                    activity != null ? activity.shortComponentName : null,
3114                    annotation != null ? "ANR " + annotation : "ANR",
3115                    info.toString());
3116
3117            // Bring up the infamous App Not Responding dialog
3118            Message msg = Message.obtain();
3119            HashMap map = new HashMap();
3120            msg.what = SHOW_NOT_RESPONDING_MSG;
3121            msg.obj = map;
3122            map.put("app", app);
3123            if (activity != null) {
3124                map.put("activity", activity);
3125            }
3126
3127            mHandler.sendMessage(msg);
3128        }
3129    }
3130
3131    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3132        if (!mLaunchWarningShown) {
3133            mLaunchWarningShown = true;
3134            mHandler.post(new Runnable() {
3135                @Override
3136                public void run() {
3137                    synchronized (ActivityManagerService.this) {
3138                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3139                        d.show();
3140                        mHandler.postDelayed(new Runnable() {
3141                            @Override
3142                            public void run() {
3143                                synchronized (ActivityManagerService.this) {
3144                                    d.dismiss();
3145                                    mLaunchWarningShown = false;
3146                                }
3147                            }
3148                        }, 4000);
3149                    }
3150                }
3151            });
3152        }
3153    }
3154
3155    public boolean clearApplicationUserData(final String packageName,
3156            final IPackageDataObserver observer) {
3157        int uid = Binder.getCallingUid();
3158        int pid = Binder.getCallingPid();
3159        long callingId = Binder.clearCallingIdentity();
3160        try {
3161            IPackageManager pm = AppGlobals.getPackageManager();
3162            int pkgUid = -1;
3163            synchronized(this) {
3164                try {
3165                    pkgUid = pm.getPackageUid(packageName);
3166                } catch (RemoteException e) {
3167                }
3168                if (pkgUid == -1) {
3169                    Slog.w(TAG, "Invalid packageName:" + packageName);
3170                    return false;
3171                }
3172                if (uid == pkgUid || checkComponentPermission(
3173                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3174                        pid, uid, -1, true)
3175                        == PackageManager.PERMISSION_GRANTED) {
3176                    forceStopPackageLocked(packageName, pkgUid);
3177                } else {
3178                    throw new SecurityException(pid+" does not have permission:"+
3179                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3180                                    "for process:"+packageName);
3181                }
3182            }
3183
3184            try {
3185                //clear application user data
3186                pm.clearApplicationUserData(packageName, observer);
3187                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3188                        Uri.fromParts("package", packageName, null));
3189                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3190                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3191                        null, null, 0, null, null, null, false, false);
3192            } catch (RemoteException e) {
3193            }
3194        } finally {
3195            Binder.restoreCallingIdentity(callingId);
3196        }
3197        return true;
3198    }
3199
3200    public void killBackgroundProcesses(final String packageName) {
3201        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3202                != PackageManager.PERMISSION_GRANTED &&
3203                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3204                        != PackageManager.PERMISSION_GRANTED) {
3205            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3206                    + Binder.getCallingPid()
3207                    + ", uid=" + Binder.getCallingUid()
3208                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3209            Slog.w(TAG, msg);
3210            throw new SecurityException(msg);
3211        }
3212
3213        long callingId = Binder.clearCallingIdentity();
3214        try {
3215            IPackageManager pm = AppGlobals.getPackageManager();
3216            int pkgUid = -1;
3217            synchronized(this) {
3218                try {
3219                    pkgUid = pm.getPackageUid(packageName);
3220                } catch (RemoteException e) {
3221                }
3222                if (pkgUid == -1) {
3223                    Slog.w(TAG, "Invalid packageName: " + packageName);
3224                    return;
3225                }
3226                killPackageProcessesLocked(packageName, pkgUid,
3227                        SECONDARY_SERVER_ADJ, false, true);
3228            }
3229        } finally {
3230            Binder.restoreCallingIdentity(callingId);
3231        }
3232    }
3233
3234    public void forceStopPackage(final String packageName) {
3235        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3236                != PackageManager.PERMISSION_GRANTED) {
3237            String msg = "Permission Denial: forceStopPackage() from pid="
3238                    + Binder.getCallingPid()
3239                    + ", uid=" + Binder.getCallingUid()
3240                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3241            Slog.w(TAG, msg);
3242            throw new SecurityException(msg);
3243        }
3244
3245        long callingId = Binder.clearCallingIdentity();
3246        try {
3247            IPackageManager pm = AppGlobals.getPackageManager();
3248            int pkgUid = -1;
3249            synchronized(this) {
3250                try {
3251                    pkgUid = pm.getPackageUid(packageName);
3252                } catch (RemoteException e) {
3253                }
3254                if (pkgUid == -1) {
3255                    Slog.w(TAG, "Invalid packageName: " + packageName);
3256                    return;
3257                }
3258                forceStopPackageLocked(packageName, pkgUid);
3259                try {
3260                    pm.setPackageStoppedState(packageName, true);
3261                } catch (RemoteException e) {
3262                } catch (IllegalArgumentException e) {
3263                    Slog.w(TAG, "Failed trying to unstop package "
3264                            + packageName + ": " + e);
3265                }
3266            }
3267        } finally {
3268            Binder.restoreCallingIdentity(callingId);
3269        }
3270    }
3271
3272    /*
3273     * The pkg name and uid have to be specified.
3274     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3275     */
3276    public void killApplicationWithUid(String pkg, int uid) {
3277        if (pkg == null) {
3278            return;
3279        }
3280        // Make sure the uid is valid.
3281        if (uid < 0) {
3282            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3283            return;
3284        }
3285        int callerUid = Binder.getCallingUid();
3286        // Only the system server can kill an application
3287        if (callerUid == Process.SYSTEM_UID) {
3288            // Post an aysnc message to kill the application
3289            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3290            msg.arg1 = uid;
3291            msg.arg2 = 0;
3292            msg.obj = pkg;
3293            mHandler.sendMessage(msg);
3294        } else {
3295            throw new SecurityException(callerUid + " cannot kill pkg: " +
3296                    pkg);
3297        }
3298    }
3299
3300    public void closeSystemDialogs(String reason) {
3301        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3302        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3303        if (reason != null) {
3304            intent.putExtra("reason", reason);
3305        }
3306
3307        final int uid = Binder.getCallingUid();
3308        final long origId = Binder.clearCallingIdentity();
3309        synchronized (this) {
3310            int i = mWatchers.beginBroadcast();
3311            while (i > 0) {
3312                i--;
3313                IActivityWatcher w = mWatchers.getBroadcastItem(i);
3314                if (w != null) {
3315                    try {
3316                        w.closingSystemDialogs(reason);
3317                    } catch (RemoteException e) {
3318                    }
3319                }
3320            }
3321            mWatchers.finishBroadcast();
3322
3323            mWindowManager.closeSystemDialogs(reason);
3324
3325            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3326                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3327                if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3328                    r.stack.finishActivityLocked(r, i,
3329                            Activity.RESULT_CANCELED, null, "close-sys");
3330                }
3331            }
3332
3333            broadcastIntentLocked(null, null, intent, null,
3334                    null, 0, null, null, null, false, false, -1, uid);
3335        }
3336        Binder.restoreCallingIdentity(origId);
3337    }
3338
3339    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3340            throws RemoteException {
3341        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3342        for (int i=pids.length-1; i>=0; i--) {
3343            infos[i] = new Debug.MemoryInfo();
3344            Debug.getMemoryInfo(pids[i], infos[i]);
3345        }
3346        return infos;
3347    }
3348
3349    public void killApplicationProcess(String processName, int uid) {
3350        if (processName == null) {
3351            return;
3352        }
3353
3354        int callerUid = Binder.getCallingUid();
3355        // Only the system server can kill an application
3356        if (callerUid == Process.SYSTEM_UID) {
3357            synchronized (this) {
3358                ProcessRecord app = getProcessRecordLocked(processName, uid);
3359                if (app != null && app.thread != null) {
3360                    try {
3361                        app.thread.scheduleSuicide();
3362                    } catch (RemoteException e) {
3363                        // If the other end already died, then our work here is done.
3364                    }
3365                } else {
3366                    Slog.w(TAG, "Process/uid not found attempting kill of "
3367                            + processName + " / " + uid);
3368                }
3369            }
3370        } else {
3371            throw new SecurityException(callerUid + " cannot kill app process: " +
3372                    processName);
3373        }
3374    }
3375
3376    private void forceStopPackageLocked(final String packageName, int uid) {
3377        forceStopPackageLocked(packageName, uid, false, false, true);
3378        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3379                Uri.fromParts("package", packageName, null));
3380        if (!mProcessesReady) {
3381            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3382        }
3383        intent.putExtra(Intent.EXTRA_UID, uid);
3384        broadcastIntentLocked(null, null, intent,
3385                null, null, 0, null, null, null,
3386                false, false, MY_PID, Process.SYSTEM_UID);
3387    }
3388
3389    private final boolean killPackageProcessesLocked(String packageName, int uid,
3390            int minOomAdj, boolean callerWillRestart, boolean doit) {
3391        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3392
3393        // Remove all processes this package may have touched: all with the
3394        // same UID (except for the system or root user), and all whose name
3395        // matches the package name.
3396        final String procNamePrefix = packageName + ":";
3397        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3398            final int NA = apps.size();
3399            for (int ia=0; ia<NA; ia++) {
3400                ProcessRecord app = apps.valueAt(ia);
3401                if (app.removed) {
3402                    if (doit) {
3403                        procs.add(app);
3404                    }
3405                } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3406                        || app.processName.equals(packageName)
3407                        || app.processName.startsWith(procNamePrefix)) {
3408                    if (app.setAdj >= minOomAdj) {
3409                        if (!doit) {
3410                            return true;
3411                        }
3412                        app.removed = true;
3413                        procs.add(app);
3414                    }
3415                }
3416            }
3417        }
3418
3419        int N = procs.size();
3420        for (int i=0; i<N; i++) {
3421            removeProcessLocked(procs.get(i), callerWillRestart);
3422        }
3423        return N > 0;
3424    }
3425
3426    private final boolean forceStopPackageLocked(String name, int uid,
3427            boolean callerWillRestart, boolean purgeCache, boolean doit) {
3428        int i;
3429        int N;
3430
3431        if (uid < 0) {
3432            try {
3433                uid = AppGlobals.getPackageManager().getPackageUid(name);
3434            } catch (RemoteException e) {
3435            }
3436        }
3437
3438        if (doit) {
3439            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3440
3441            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3442            while (badApps.hasNext()) {
3443                SparseArray<Long> ba = badApps.next();
3444                if (ba.get(uid) != null) {
3445                    badApps.remove();
3446                }
3447            }
3448        }
3449
3450        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3451                callerWillRestart, doit);
3452
3453        for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3454            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3455            if (r.packageName.equals(name)) {
3456                if (!doit) {
3457                    return true;
3458                }
3459                didSomething = true;
3460                Slog.i(TAG, "  Force finishing activity " + r);
3461                if (r.app != null) {
3462                    r.app.removed = true;
3463                }
3464                r.app = null;
3465                r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
3466            }
3467        }
3468
3469        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3470        for (ServiceRecord service : mServices.values()) {
3471            if (service.packageName.equals(name)) {
3472                if (!doit) {
3473                    return true;
3474                }
3475                didSomething = true;
3476                Slog.i(TAG, "  Force stopping service " + service);
3477                if (service.app != null) {
3478                    service.app.removed = true;
3479                }
3480                service.app = null;
3481                services.add(service);
3482            }
3483        }
3484
3485        N = services.size();
3486        for (i=0; i<N; i++) {
3487            bringDownServiceLocked(services.get(i), true);
3488        }
3489
3490        if (doit) {
3491            if (purgeCache) {
3492                AttributeCache ac = AttributeCache.instance();
3493                if (ac != null) {
3494                    ac.removePackage(name);
3495                }
3496            }
3497            mMainStack.resumeTopActivityLocked(null);
3498        }
3499
3500        return didSomething;
3501    }
3502
3503    private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
3504        final String name = app.processName;
3505        final int uid = app.info.uid;
3506        if (DEBUG_PROCESSES) Slog.d(
3507            TAG, "Force removing process " + app + " (" + name
3508            + "/" + uid + ")");
3509
3510        mProcessNames.remove(name, uid);
3511        if (mHeavyWeightProcess == app) {
3512            mHeavyWeightProcess = null;
3513            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3514        }
3515        boolean needRestart = false;
3516        if (app.pid > 0 && app.pid != MY_PID) {
3517            int pid = app.pid;
3518            synchronized (mPidsSelfLocked) {
3519                mPidsSelfLocked.remove(pid);
3520                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3521            }
3522            handleAppDiedLocked(app, true);
3523            mLruProcesses.remove(app);
3524            Process.killProcess(pid);
3525
3526            if (app.persistent) {
3527                if (!callerWillRestart) {
3528                    addAppLocked(app.info);
3529                } else {
3530                    needRestart = true;
3531                }
3532            }
3533        } else {
3534            mRemovedProcesses.add(app);
3535        }
3536
3537        return needRestart;
3538    }
3539
3540    private final void processStartTimedOutLocked(ProcessRecord app) {
3541        final int pid = app.pid;
3542        boolean gone = false;
3543        synchronized (mPidsSelfLocked) {
3544            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3545            if (knownApp != null && knownApp.thread == null) {
3546                mPidsSelfLocked.remove(pid);
3547                gone = true;
3548            }
3549        }
3550
3551        if (gone) {
3552            Slog.w(TAG, "Process " + app + " failed to attach");
3553            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
3554                    app.processName);
3555            mProcessNames.remove(app.processName, app.info.uid);
3556            if (mHeavyWeightProcess == app) {
3557                mHeavyWeightProcess = null;
3558                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3559            }
3560            // Take care of any launching providers waiting for this process.
3561            checkAppInLaunchingProvidersLocked(app, true);
3562            // Take care of any services that are waiting for the process.
3563            for (int i=0; i<mPendingServices.size(); i++) {
3564                ServiceRecord sr = mPendingServices.get(i);
3565                if (app.info.uid == sr.appInfo.uid
3566                        && app.processName.equals(sr.processName)) {
3567                    Slog.w(TAG, "Forcing bringing down service: " + sr);
3568                    mPendingServices.remove(i);
3569                    i--;
3570                    bringDownServiceLocked(sr, true);
3571                }
3572            }
3573            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3574                    app.processName, app.setAdj, "start timeout");
3575            Process.killProcessQuiet(pid);
3576            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3577                Slog.w(TAG, "Unattached app died before backup, skipping");
3578                try {
3579                    IBackupManager bm = IBackupManager.Stub.asInterface(
3580                            ServiceManager.getService(Context.BACKUP_SERVICE));
3581                    bm.agentDisconnected(app.info.packageName);
3582                } catch (RemoteException e) {
3583                    // Can't happen; the backup manager is local
3584                }
3585            }
3586            if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
3587                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3588                mPendingBroadcast.state = BroadcastRecord.IDLE;
3589                mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
3590                mPendingBroadcast = null;
3591                scheduleBroadcastsLocked();
3592            }
3593        } else {
3594            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3595        }
3596    }
3597
3598    private final boolean attachApplicationLocked(IApplicationThread thread,
3599            int pid) {
3600
3601        // Find the application record that is being attached...  either via
3602        // the pid if we are running in multiple processes, or just pull the
3603        // next app record if we are emulating process with anonymous threads.
3604        ProcessRecord app;
3605        if (pid != MY_PID && pid >= 0) {
3606            synchronized (mPidsSelfLocked) {
3607                app = mPidsSelfLocked.get(pid);
3608            }
3609        } else if (mStartingProcesses.size() > 0) {
3610            app = mStartingProcesses.remove(0);
3611            app.setPid(pid);
3612        } else {
3613            app = null;
3614        }
3615
3616        if (app == null) {
3617            Slog.w(TAG, "No pending application record for pid " + pid
3618                    + " (IApplicationThread " + thread + "); dropping process");
3619            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3620            if (pid > 0 && pid != MY_PID) {
3621                Process.killProcessQuiet(pid);
3622            } else {
3623                try {
3624                    thread.scheduleExit();
3625                } catch (Exception e) {
3626                    // Ignore exceptions.
3627                }
3628            }
3629            return false;
3630        }
3631
3632        // If this application record is still attached to a previous
3633        // process, clean it up now.
3634        if (app.thread != null) {
3635            handleAppDiedLocked(app, true);
3636        }
3637
3638        // Tell the process all about itself.
3639
3640        if (localLOGV) Slog.v(
3641                TAG, "Binding process pid " + pid + " to record " + app);
3642
3643        String processName = app.processName;
3644        try {
3645            thread.asBinder().linkToDeath(new AppDeathRecipient(
3646                    app, pid, thread), 0);
3647        } catch (RemoteException e) {
3648            app.resetPackageList();
3649            startProcessLocked(app, "link fail", processName);
3650            return false;
3651        }
3652
3653        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3654
3655        app.thread = thread;
3656        app.curAdj = app.setAdj = -100;
3657        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3658        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3659        app.forcingToForeground = null;
3660        app.foregroundServices = false;
3661        app.debugging = false;
3662
3663        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3664
3665        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3666        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3667
3668        if (!normalMode) {
3669            Slog.i(TAG, "Launching preboot mode app: " + app);
3670        }
3671
3672        if (localLOGV) Slog.v(
3673            TAG, "New app record " + app
3674            + " thread=" + thread.asBinder() + " pid=" + pid);
3675        try {
3676            int testMode = IApplicationThread.DEBUG_OFF;
3677            if (mDebugApp != null && mDebugApp.equals(processName)) {
3678                testMode = mWaitForDebugger
3679                    ? IApplicationThread.DEBUG_WAIT
3680                    : IApplicationThread.DEBUG_ON;
3681                app.debugging = true;
3682                if (mDebugTransient) {
3683                    mDebugApp = mOrigDebugApp;
3684                    mWaitForDebugger = mOrigWaitForDebugger;
3685                }
3686            }
3687
3688            // If the app is being launched for restore or full backup, set it up specially
3689            boolean isRestrictedBackupMode = false;
3690            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3691                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3692                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
3693                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3694            }
3695
3696            ensurePackageDexOpt(app.instrumentationInfo != null
3697                    ? app.instrumentationInfo.packageName
3698                    : app.info.packageName);
3699            if (app.instrumentationClass != null) {
3700                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
3701            }
3702            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
3703                    + processName + " with config " + mConfiguration);
3704            ApplicationInfo appInfo = app.instrumentationInfo != null
3705                    ? app.instrumentationInfo : app.info;
3706            app.compat = compatibilityInfoForPackageLocked(appInfo);
3707            thread.bindApplication(processName, appInfo, providers,
3708                    app.instrumentationClass, app.instrumentationProfileFile,
3709                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
3710                    isRestrictedBackupMode || !normalMode,
3711                    mConfiguration, app.compat, getCommonServicesLocked(),
3712                    mCoreSettingsObserver.getCoreSettingsLocked());
3713            updateLruProcessLocked(app, false, true);
3714            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
3715        } catch (Exception e) {
3716            // todo: Yikes!  What should we do?  For now we will try to
3717            // start another process, but that could easily get us in
3718            // an infinite loop of restarting processes...
3719            Slog.w(TAG, "Exception thrown during bind!", e);
3720
3721            app.resetPackageList();
3722            startProcessLocked(app, "bind fail", processName);
3723            return false;
3724        }
3725
3726        // Remove this record from the list of starting applications.
3727        mPersistentStartingProcesses.remove(app);
3728        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3729                "Attach application locked removing on hold: " + app);
3730        mProcessesOnHold.remove(app);
3731
3732        boolean badApp = false;
3733        boolean didSomething = false;
3734
3735        // See if the top visible activity is waiting to run in this process...
3736        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
3737        if (hr != null && normalMode) {
3738            if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3739                    && processName.equals(hr.processName)) {
3740                try {
3741                    if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
3742                        didSomething = true;
3743                    }
3744                } catch (Exception e) {
3745                    Slog.w(TAG, "Exception in new application when starting activity "
3746                          + hr.intent.getComponent().flattenToShortString(), e);
3747                    badApp = true;
3748                }
3749            } else {
3750                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
3751            }
3752        }
3753
3754        // Find any services that should be running in this process...
3755        if (!badApp && mPendingServices.size() > 0) {
3756            ServiceRecord sr = null;
3757            try {
3758                for (int i=0; i<mPendingServices.size(); i++) {
3759                    sr = mPendingServices.get(i);
3760                    if (app.info.uid != sr.appInfo.uid
3761                            || !processName.equals(sr.processName)) {
3762                        continue;
3763                    }
3764
3765                    mPendingServices.remove(i);
3766                    i--;
3767                    realStartServiceLocked(sr, app);
3768                    didSomething = true;
3769                }
3770            } catch (Exception e) {
3771                Slog.w(TAG, "Exception in new application when starting service "
3772                      + sr.shortName, e);
3773                badApp = true;
3774            }
3775        }
3776
3777        // Check if the next broadcast receiver is in this process...
3778        BroadcastRecord br = mPendingBroadcast;
3779        if (!badApp && br != null && br.curApp == app) {
3780            try {
3781                mPendingBroadcast = null;
3782                processCurBroadcastLocked(br, app);
3783                didSomething = true;
3784            } catch (Exception e) {
3785                Slog.w(TAG, "Exception in new application when starting receiver "
3786                      + br.curComponent.flattenToShortString(), e);
3787                badApp = true;
3788                logBroadcastReceiverDiscardLocked(br);
3789                finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3790                        br.resultExtras, br.resultAbort, true);
3791                scheduleBroadcastsLocked();
3792                // We need to reset the state if we fails to start the receiver.
3793                br.state = BroadcastRecord.IDLE;
3794            }
3795        }
3796
3797        // Check whether the next backup agent is in this process...
3798        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
3799            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
3800            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
3801            try {
3802                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3803                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3804                        mBackupTarget.backupMode);
3805            } catch (Exception e) {
3806                Slog.w(TAG, "Exception scheduling backup agent creation: ");
3807                e.printStackTrace();
3808            }
3809        }
3810
3811        if (badApp) {
3812            // todo: Also need to kill application to deal with all
3813            // kinds of exceptions.
3814            handleAppDiedLocked(app, false);
3815            return false;
3816        }
3817
3818        if (!didSomething) {
3819            updateOomAdjLocked();
3820        }
3821
3822        return true;
3823    }
3824
3825    public final void attachApplication(IApplicationThread thread) {
3826        synchronized (this) {
3827            int callingPid = Binder.getCallingPid();
3828            final long origId = Binder.clearCallingIdentity();
3829            attachApplicationLocked(thread, callingPid);
3830            Binder.restoreCallingIdentity(origId);
3831        }
3832    }
3833
3834    public final void activityIdle(IBinder token, Configuration config) {
3835        final long origId = Binder.clearCallingIdentity();
3836        mMainStack.activityIdleInternal(token, false, config);
3837        Binder.restoreCallingIdentity(origId);
3838    }
3839
3840    void enableScreenAfterBoot() {
3841        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
3842                SystemClock.uptimeMillis());
3843        mWindowManager.enableScreenAfterBoot();
3844    }
3845
3846    final void finishBooting() {
3847        IntentFilter pkgFilter = new IntentFilter();
3848        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3849        pkgFilter.addDataScheme("package");
3850        mContext.registerReceiver(new BroadcastReceiver() {
3851            @Override
3852            public void onReceive(Context context, Intent intent) {
3853                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3854                if (pkgs != null) {
3855                    for (String pkg : pkgs) {
3856                        synchronized (ActivityManagerService.this) {
3857                          if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3858                              setResultCode(Activity.RESULT_OK);
3859                              return;
3860                          }
3861                       }
3862                    }
3863                }
3864            }
3865        }, pkgFilter);
3866
3867        synchronized (this) {
3868            // Ensure that any processes we had put on hold are now started
3869            // up.
3870            final int NP = mProcessesOnHold.size();
3871            if (NP > 0) {
3872                ArrayList<ProcessRecord> procs =
3873                    new ArrayList<ProcessRecord>(mProcessesOnHold);
3874                for (int ip=0; ip<NP; ip++) {
3875                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3876                            + procs.get(ip));
3877                    startProcessLocked(procs.get(ip), "on-hold", null);
3878                }
3879            }
3880
3881            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
3882                // Start looking for apps that are abusing wake locks.
3883                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
3884                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
3885                // Tell anyone interested that we are done booting!
3886                SystemProperties.set("sys.boot_completed", "1");
3887                broadcastIntentLocked(null, null,
3888                        new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3889                        null, null, 0, null, null,
3890                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3891                        false, false, MY_PID, Process.SYSTEM_UID);
3892            }
3893        }
3894    }
3895
3896    final void ensureBootCompleted() {
3897        boolean booting;
3898        boolean enableScreen;
3899        synchronized (this) {
3900            booting = mBooting;
3901            mBooting = false;
3902            enableScreen = !mBooted;
3903            mBooted = true;
3904        }
3905
3906        if (booting) {
3907            finishBooting();
3908        }
3909
3910        if (enableScreen) {
3911            enableScreenAfterBoot();
3912        }
3913    }
3914
3915    public final void activityPaused(IBinder token) {
3916        final long origId = Binder.clearCallingIdentity();
3917        mMainStack.activityPaused(token, false);
3918        Binder.restoreCallingIdentity(origId);
3919    }
3920
3921    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3922            CharSequence description) {
3923        if (localLOGV) Slog.v(
3924            TAG, "Activity stopped: token=" + token);
3925
3926        // Refuse possible leaked file descriptors
3927        if (icicle != null && icicle.hasFileDescriptors()) {
3928            throw new IllegalArgumentException("File descriptors passed in Bundle");
3929        }
3930
3931        ActivityRecord r = null;
3932
3933        final long origId = Binder.clearCallingIdentity();
3934
3935        synchronized (this) {
3936            int index = mMainStack.indexOfTokenLocked(token);
3937            if (index >= 0) {
3938                r = (ActivityRecord)mMainStack.mHistory.get(index);
3939                r.icicle = icicle;
3940                r.haveState = true;
3941                r.updateThumbnail(thumbnail, description);
3942                r.stopped = true;
3943                r.state = ActivityState.STOPPED;
3944                if (!r.finishing) {
3945                    if (r.configDestroy) {
3946                        r.stack.destroyActivityLocked(r, true);
3947                        r.stack.resumeTopActivityLocked(null);
3948                    }
3949                }
3950            }
3951        }
3952
3953        if (r != null) {
3954            sendPendingThumbnail(r, null, null, null, false);
3955        }
3956
3957        trimApplications();
3958
3959        Binder.restoreCallingIdentity(origId);
3960    }
3961
3962    public final void activityDestroyed(IBinder token) {
3963        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
3964        mMainStack.activityDestroyed(token);
3965    }
3966
3967    public String getCallingPackage(IBinder token) {
3968        synchronized (this) {
3969            ActivityRecord r = getCallingRecordLocked(token);
3970            return r != null && r.app != null ? r.info.packageName : null;
3971        }
3972    }
3973
3974    public ComponentName getCallingActivity(IBinder token) {
3975        synchronized (this) {
3976            ActivityRecord r = getCallingRecordLocked(token);
3977            return r != null ? r.intent.getComponent() : null;
3978        }
3979    }
3980
3981    private ActivityRecord getCallingRecordLocked(IBinder token) {
3982        int index = mMainStack.indexOfTokenLocked(token);
3983        if (index >= 0) {
3984            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
3985            if (r != null) {
3986                return r.resultTo;
3987            }
3988        }
3989        return null;
3990    }
3991
3992    public ComponentName getActivityClassForToken(IBinder token) {
3993        synchronized(this) {
3994            int index = mMainStack.indexOfTokenLocked(token);
3995            if (index >= 0) {
3996                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
3997                return r.intent.getComponent();
3998            }
3999            return null;
4000        }
4001    }
4002
4003    public String getPackageForToken(IBinder token) {
4004        synchronized(this) {
4005            int index = mMainStack.indexOfTokenLocked(token);
4006            if (index >= 0) {
4007                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
4008                return r.packageName;
4009            }
4010            return null;
4011        }
4012    }
4013
4014    public IIntentSender getIntentSender(int type,
4015            String packageName, IBinder token, String resultWho,
4016            int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
4017        // Refuse possible leaked file descriptors
4018        if (intents != null) {
4019            if (intents.length < 1) {
4020                throw new IllegalArgumentException("Intents array length must be >= 1");
4021            }
4022            for (int i=0; i<intents.length; i++) {
4023                Intent intent = intents[i];
4024                if (intent != null) {
4025                    if (intent.hasFileDescriptors()) {
4026                        throw new IllegalArgumentException("File descriptors passed in Intent");
4027                    }
4028                    if (type == INTENT_SENDER_BROADCAST &&
4029                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4030                        throw new IllegalArgumentException(
4031                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4032                    }
4033                    intents[i] = new Intent(intent);
4034                }
4035            }
4036            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4037                throw new IllegalArgumentException(
4038                        "Intent array length does not match resolvedTypes length");
4039            }
4040        }
4041
4042        synchronized(this) {
4043            int callingUid = Binder.getCallingUid();
4044            try {
4045                if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
4046                        Process.supportsProcesses()) {
4047                    int uid = AppGlobals.getPackageManager()
4048                            .getPackageUid(packageName);
4049                    if (uid != Binder.getCallingUid()) {
4050                        String msg = "Permission Denial: getIntentSender() from pid="
4051                            + Binder.getCallingPid()
4052                            + ", uid=" + Binder.getCallingUid()
4053                            + ", (need uid=" + uid + ")"
4054                            + " is not allowed to send as package " + packageName;
4055                        Slog.w(TAG, msg);
4056                        throw new SecurityException(msg);
4057                    }
4058                }
4059
4060                return getIntentSenderLocked(type, packageName, callingUid,
4061                        token, resultWho, requestCode, intents, resolvedTypes, flags);
4062
4063            } catch (RemoteException e) {
4064                throw new SecurityException(e);
4065            }
4066        }
4067    }
4068
4069    IIntentSender getIntentSenderLocked(int type,
4070            String packageName, int callingUid, IBinder token, String resultWho,
4071            int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
4072        ActivityRecord activity = null;
4073        if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4074            int index = mMainStack.indexOfTokenLocked(token);
4075            if (index < 0) {
4076                return null;
4077            }
4078            activity = (ActivityRecord)mMainStack.mHistory.get(index);
4079            if (activity.finishing) {
4080                return null;
4081            }
4082        }
4083
4084        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4085        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4086        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4087        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4088                |PendingIntent.FLAG_UPDATE_CURRENT);
4089
4090        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4091                type, packageName, activity, resultWho,
4092                requestCode, intents, resolvedTypes, flags);
4093        WeakReference<PendingIntentRecord> ref;
4094        ref = mIntentSenderRecords.get(key);
4095        PendingIntentRecord rec = ref != null ? ref.get() : null;
4096        if (rec != null) {
4097            if (!cancelCurrent) {
4098                if (updateCurrent) {
4099                    if (rec.key.requestIntent != null) {
4100                        rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4101                    }
4102                    if (intents != null) {
4103                        intents[intents.length-1] = rec.key.requestIntent;
4104                        rec.key.allIntents = intents;
4105                        rec.key.allResolvedTypes = resolvedTypes;
4106                    } else {
4107                        rec.key.allIntents = null;
4108                        rec.key.allResolvedTypes = null;
4109                    }
4110                }
4111                return rec;
4112            }
4113            rec.canceled = true;
4114            mIntentSenderRecords.remove(key);
4115        }
4116        if (noCreate) {
4117            return rec;
4118        }
4119        rec = new PendingIntentRecord(this, key, callingUid);
4120        mIntentSenderRecords.put(key, rec.ref);
4121        if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4122            if (activity.pendingResults == null) {
4123                activity.pendingResults
4124                        = new HashSet<WeakReference<PendingIntentRecord>>();
4125            }
4126            activity.pendingResults.add(rec.ref);
4127        }
4128        return rec;
4129    }
4130
4131    public void cancelIntentSender(IIntentSender sender) {
4132        if (!(sender instanceof PendingIntentRecord)) {
4133            return;
4134        }
4135        synchronized(this) {
4136            PendingIntentRecord rec = (PendingIntentRecord)sender;
4137            try {
4138                int uid = AppGlobals.getPackageManager()
4139                        .getPackageUid(rec.key.packageName);
4140                if (uid != Binder.getCallingUid()) {
4141                    String msg = "Permission Denial: cancelIntentSender() from pid="
4142                        + Binder.getCallingPid()
4143                        + ", uid=" + Binder.getCallingUid()
4144                        + " is not allowed to cancel packges "
4145                        + rec.key.packageName;
4146                    Slog.w(TAG, msg);
4147                    throw new SecurityException(msg);
4148                }
4149            } catch (RemoteException e) {
4150                throw new SecurityException(e);
4151            }
4152            cancelIntentSenderLocked(rec, true);
4153        }
4154    }
4155
4156    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4157        rec.canceled = true;
4158        mIntentSenderRecords.remove(rec.key);
4159        if (cleanActivity && rec.key.activity != null) {
4160            rec.key.activity.pendingResults.remove(rec.ref);
4161        }
4162    }
4163
4164    public String getPackageForIntentSender(IIntentSender pendingResult) {
4165        if (!(pendingResult instanceof PendingIntentRecord)) {
4166            return null;
4167        }
4168        try {
4169            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4170            return res.key.packageName;
4171        } catch (ClassCastException e) {
4172        }
4173        return null;
4174    }
4175
4176    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4177        if (!(pendingResult instanceof PendingIntentRecord)) {
4178            return false;
4179        }
4180        try {
4181            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4182            if (res.key.allIntents == null) {
4183                return false;
4184            }
4185            for (int i=0; i<res.key.allIntents.length; i++) {
4186                Intent intent = res.key.allIntents[i];
4187                if (intent.getPackage() != null && intent.getComponent() != null) {
4188                    return false;
4189                }
4190            }
4191            return true;
4192        } catch (ClassCastException e) {
4193        }
4194        return false;
4195    }
4196
4197    public void setProcessLimit(int max) {
4198        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4199                "setProcessLimit()");
4200        mProcessLimit = max;
4201    }
4202
4203    public int getProcessLimit() {
4204        return mProcessLimit;
4205    }
4206
4207    void foregroundTokenDied(ForegroundToken token) {
4208        synchronized (ActivityManagerService.this) {
4209            synchronized (mPidsSelfLocked) {
4210                ForegroundToken cur
4211                    = mForegroundProcesses.get(token.pid);
4212                if (cur != token) {
4213                    return;
4214                }
4215                mForegroundProcesses.remove(token.pid);
4216                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4217                if (pr == null) {
4218                    return;
4219                }
4220                pr.forcingToForeground = null;
4221                pr.foregroundServices = false;
4222            }
4223            updateOomAdjLocked();
4224        }
4225    }
4226
4227    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4228        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4229                "setProcessForeground()");
4230        synchronized(this) {
4231            boolean changed = false;
4232
4233            synchronized (mPidsSelfLocked) {
4234                ProcessRecord pr = mPidsSelfLocked.get(pid);
4235                if (pr == null) {
4236                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4237                    return;
4238                }
4239                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4240                if (oldToken != null) {
4241                    oldToken.token.unlinkToDeath(oldToken, 0);
4242                    mForegroundProcesses.remove(pid);
4243                    pr.forcingToForeground = null;
4244                    changed = true;
4245                }
4246                if (isForeground && token != null) {
4247                    ForegroundToken newToken = new ForegroundToken() {
4248                        public void binderDied() {
4249                            foregroundTokenDied(this);
4250                        }
4251                    };
4252                    newToken.pid = pid;
4253                    newToken.token = token;
4254                    try {
4255                        token.linkToDeath(newToken, 0);
4256                        mForegroundProcesses.put(pid, newToken);
4257                        pr.forcingToForeground = token;
4258                        changed = true;
4259                    } catch (RemoteException e) {
4260                        // If the process died while doing this, we will later
4261                        // do the cleanup with the process death link.
4262                    }
4263                }
4264            }
4265
4266            if (changed) {
4267                updateOomAdjLocked();
4268            }
4269        }
4270    }
4271
4272    // =========================================================
4273    // PERMISSIONS
4274    // =========================================================
4275
4276    static class PermissionController extends IPermissionController.Stub {
4277        ActivityManagerService mActivityManagerService;
4278        PermissionController(ActivityManagerService activityManagerService) {
4279            mActivityManagerService = activityManagerService;
4280        }
4281
4282        public boolean checkPermission(String permission, int pid, int uid) {
4283            return mActivityManagerService.checkPermission(permission, pid,
4284                    uid) == PackageManager.PERMISSION_GRANTED;
4285        }
4286    }
4287
4288    /**
4289     * This can be called with or without the global lock held.
4290     */
4291    int checkComponentPermission(String permission, int pid, int uid,
4292            int owningUid, boolean exported) {
4293        // We might be performing an operation on behalf of an indirect binder
4294        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4295        // client identity accordingly before proceeding.
4296        Identity tlsIdentity = sCallerIdentity.get();
4297        if (tlsIdentity != null) {
4298            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4299                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4300            uid = tlsIdentity.uid;
4301            pid = tlsIdentity.pid;
4302        }
4303
4304        // Root, system server and our own process get to do everything.
4305        if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
4306            !Process.supportsProcesses()) {
4307            return PackageManager.PERMISSION_GRANTED;
4308        }
4309        // If there is a uid that owns whatever is being accessed, it has
4310        // blanket access to it regardless of the permissions it requires.
4311        if (owningUid >= 0 && uid == owningUid) {
4312            return PackageManager.PERMISSION_GRANTED;
4313        }
4314        // If the target is not exported, then nobody else can get to it.
4315        if (!exported) {
4316            Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
4317            return PackageManager.PERMISSION_DENIED;
4318        }
4319        if (permission == null) {
4320            return PackageManager.PERMISSION_GRANTED;
4321        }
4322        try {
4323            return AppGlobals.getPackageManager()
4324                    .checkUidPermission(permission, uid);
4325        } catch (RemoteException e) {
4326            // Should never happen, but if it does... deny!
4327            Slog.e(TAG, "PackageManager is dead?!?", e);
4328        }
4329        return PackageManager.PERMISSION_DENIED;
4330    }
4331
4332    /**
4333     * As the only public entry point for permissions checking, this method
4334     * can enforce the semantic that requesting a check on a null global
4335     * permission is automatically denied.  (Internally a null permission
4336     * string is used when calling {@link #checkComponentPermission} in cases
4337     * when only uid-based security is needed.)
4338     *
4339     * This can be called with or without the global lock held.
4340     */
4341    public int checkPermission(String permission, int pid, int uid) {
4342        if (permission == null) {
4343            return PackageManager.PERMISSION_DENIED;
4344        }
4345        return checkComponentPermission(permission, pid, uid, -1, true);
4346    }
4347
4348    /**
4349     * Binder IPC calls go through the public entry point.
4350     * This can be called with or without the global lock held.
4351     */
4352    int checkCallingPermission(String permission) {
4353        return checkPermission(permission,
4354                Binder.getCallingPid(),
4355                Binder.getCallingUid());
4356    }
4357
4358    /**
4359     * This can be called with or without the global lock held.
4360     */
4361    void enforceCallingPermission(String permission, String func) {
4362        if (checkCallingPermission(permission)
4363                == PackageManager.PERMISSION_GRANTED) {
4364            return;
4365        }
4366
4367        String msg = "Permission Denial: " + func + " from pid="
4368                + Binder.getCallingPid()
4369                + ", uid=" + Binder.getCallingUid()
4370                + " requires " + permission;
4371        Slog.w(TAG, msg);
4372        throw new SecurityException(msg);
4373    }
4374
4375    private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
4376            ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4377        boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4378        boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4379        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4380                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4381        try {
4382            // Is the component private from the target uid?
4383            final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4384
4385            // Acceptable if the there is no read permission needed from the
4386            // target or the target is holding the read permission.
4387            if (!readPerm) {
4388                if ((!prv && pi.readPermission == null) ||
4389                        (pm.checkUidPermission(pi.readPermission, uid)
4390                                == PackageManager.PERMISSION_GRANTED)) {
4391                    readPerm = true;
4392                }
4393            }
4394
4395            // Acceptable if the there is no write permission needed from the
4396            // target or the target is holding the read permission.
4397            if (!writePerm) {
4398                if (!prv && (pi.writePermission == null) ||
4399                        (pm.checkUidPermission(pi.writePermission, uid)
4400                                == PackageManager.PERMISSION_GRANTED)) {
4401                    writePerm = true;
4402                }
4403            }
4404
4405            // Acceptable if there is a path permission matching the URI that
4406            // the target holds the permission on.
4407            PathPermission[] pps = pi.pathPermissions;
4408            if (pps != null && (!readPerm || !writePerm)) {
4409                final String path = uri.getPath();
4410                int i = pps.length;
4411                while (i > 0 && (!readPerm || !writePerm)) {
4412                    i--;
4413                    PathPermission pp = pps[i];
4414                    if (!readPerm) {
4415                        final String pprperm = pp.getReadPermission();
4416                        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4417                                + pprperm + " for " + pp.getPath()
4418                                + ": match=" + pp.match(path)
4419                                + " check=" + pm.checkUidPermission(pprperm, uid));
4420                        if (pprperm != null && pp.match(path) &&
4421                                (pm.checkUidPermission(pprperm, uid)
4422                                        == PackageManager.PERMISSION_GRANTED)) {
4423                            readPerm = true;
4424                        }
4425                    }
4426                    if (!writePerm) {
4427                        final String ppwperm = pp.getWritePermission();
4428                        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4429                                + ppwperm + " for " + pp.getPath()
4430                                + ": match=" + pp.match(path)
4431                                + " check=" + pm.checkUidPermission(ppwperm, uid));
4432                        if (ppwperm != null && pp.match(path) &&
4433                                (pm.checkUidPermission(ppwperm, uid)
4434                                        == PackageManager.PERMISSION_GRANTED)) {
4435                            writePerm = true;
4436                        }
4437                    }
4438                }
4439            }
4440        } catch (RemoteException e) {
4441            return false;
4442        }
4443
4444        return readPerm && writePerm;
4445    }
4446
4447    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4448            int modeFlags) {
4449        // Root gets to do everything.
4450        if (uid == 0 || !Process.supportsProcesses()) {
4451            return true;
4452        }
4453        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4454        if (perms == null) return false;
4455        UriPermission perm = perms.get(uri);
4456        if (perm == null) return false;
4457        return (modeFlags&perm.modeFlags) == modeFlags;
4458    }
4459
4460    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4461        // Another redirected-binder-call permissions check as in
4462        // {@link checkComponentPermission}.
4463        Identity tlsIdentity = sCallerIdentity.get();
4464        if (tlsIdentity != null) {
4465            uid = tlsIdentity.uid;
4466            pid = tlsIdentity.pid;
4467        }
4468
4469        // Our own process gets to do everything.
4470        if (pid == MY_PID) {
4471            return PackageManager.PERMISSION_GRANTED;
4472        }
4473        synchronized(this) {
4474            return checkUriPermissionLocked(uri, uid, modeFlags)
4475                    ? PackageManager.PERMISSION_GRANTED
4476                    : PackageManager.PERMISSION_DENIED;
4477        }
4478    }
4479
4480    /**
4481     * Check if the targetPkg can be granted permission to access uri by
4482     * the callingUid using the given modeFlags.  Throws a security exception
4483     * if callingUid is not allowed to do this.  Returns the uid of the target
4484     * if the URI permission grant should be performed; returns -1 if it is not
4485     * needed (for example targetPkg already has permission to access the URI).
4486     */
4487    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4488            Uri uri, int modeFlags) {
4489        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4490                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4491        if (modeFlags == 0) {
4492            return -1;
4493        }
4494
4495        if (targetPkg != null) {
4496            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4497                    "Checking grant " + targetPkg + " permission to " + uri);
4498        }
4499
4500        final IPackageManager pm = AppGlobals.getPackageManager();
4501
4502        // If this is not a content: uri, we can't do anything with it.
4503        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4504            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4505                    "Can't grant URI permission for non-content URI: " + uri);
4506            return -1;
4507        }
4508
4509        String name = uri.getAuthority();
4510        ProviderInfo pi = null;
4511        ContentProviderRecord cpr = mProvidersByName.get(name);
4512        if (cpr != null) {
4513            pi = cpr.info;
4514        } else {
4515            try {
4516                pi = pm.resolveContentProvider(name,
4517                        PackageManager.GET_URI_PERMISSION_PATTERNS);
4518            } catch (RemoteException ex) {
4519            }
4520        }
4521        if (pi == null) {
4522            Slog.w(TAG, "No content provider found for: " + name);
4523            return -1;
4524        }
4525
4526        int targetUid;
4527        if (targetPkg != null) {
4528            try {
4529                targetUid = pm.getPackageUid(targetPkg);
4530                if (targetUid < 0) {
4531                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4532                            "Can't grant URI permission no uid for: " + targetPkg);
4533                    return -1;
4534                }
4535            } catch (RemoteException ex) {
4536                return -1;
4537            }
4538        } else {
4539            targetUid = -1;
4540        }
4541
4542        if (targetUid >= 0) {
4543            // First...  does the target actually need this permission?
4544            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4545                // No need to grant the target this permission.
4546                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4547                        "Target " + targetPkg + " already has full permission to " + uri);
4548                return -1;
4549            }
4550        } else {
4551            // First...  there is no target package, so can anyone access it?
4552            boolean allowed = pi.exported;
4553            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4554                if (pi.readPermission != null) {
4555                    allowed = false;
4556                }
4557            }
4558            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4559                if (pi.writePermission != null) {
4560                    allowed = false;
4561                }
4562            }
4563            if (allowed) {
4564                return -1;
4565            }
4566        }
4567
4568        // Second...  is the provider allowing granting of URI permissions?
4569        if (!pi.grantUriPermissions) {
4570            throw new SecurityException("Provider " + pi.packageName
4571                    + "/" + pi.name
4572                    + " does not allow granting of Uri permissions (uri "
4573                    + uri + ")");
4574        }
4575        if (pi.uriPermissionPatterns != null) {
4576            final int N = pi.uriPermissionPatterns.length;
4577            boolean allowed = false;
4578            for (int i=0; i<N; i++) {
4579                if (pi.uriPermissionPatterns[i] != null
4580                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4581                    allowed = true;
4582                    break;
4583                }
4584            }
4585            if (!allowed) {
4586                throw new SecurityException("Provider " + pi.packageName
4587                        + "/" + pi.name
4588                        + " does not allow granting of permission to path of Uri "
4589                        + uri);
4590            }
4591        }
4592
4593        // Third...  does the caller itself have permission to access
4594        // this uri?
4595        if (callingUid != Process.myUid()) {
4596            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4597                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4598                    throw new SecurityException("Uid " + callingUid
4599                            + " does not have permission to uri " + uri);
4600                }
4601            }
4602        }
4603
4604        return targetUid;
4605    }
4606
4607    public int checkGrantUriPermission(int callingUid, String targetPkg,
4608            Uri uri, int modeFlags) {
4609        synchronized(this) {
4610            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4611        }
4612    }
4613
4614    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4615            Uri uri, int modeFlags, UriPermissionOwner owner) {
4616        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4617                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4618        if (modeFlags == 0) {
4619            return;
4620        }
4621
4622        // So here we are: the caller has the assumed permission
4623        // to the uri, and the target doesn't.  Let's now give this to
4624        // the target.
4625
4626        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4627                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
4628
4629        HashMap<Uri, UriPermission> targetUris
4630                = mGrantedUriPermissions.get(targetUid);
4631        if (targetUris == null) {
4632            targetUris = new HashMap<Uri, UriPermission>();
4633            mGrantedUriPermissions.put(targetUid, targetUris);
4634        }
4635
4636        UriPermission perm = targetUris.get(uri);
4637        if (perm == null) {
4638            perm = new UriPermission(targetUid, uri);
4639            targetUris.put(uri, perm);
4640        }
4641
4642        perm.modeFlags |= modeFlags;
4643        if (owner == null) {
4644            perm.globalModeFlags |= modeFlags;
4645        } else {
4646            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4647                 perm.readOwners.add(owner);
4648                 owner.addReadPermission(perm);
4649            }
4650            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4651                 perm.writeOwners.add(owner);
4652                 owner.addWritePermission(perm);
4653            }
4654        }
4655    }
4656
4657    void grantUriPermissionLocked(int callingUid,
4658            String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
4659        if (targetPkg == null) {
4660            throw new NullPointerException("targetPkg");
4661        }
4662
4663        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4664        if (targetUid < 0) {
4665            return;
4666        }
4667
4668        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4669    }
4670
4671    /**
4672     * Like checkGrantUriPermissionLocked, but takes an Intent.
4673     */
4674    int checkGrantUriPermissionFromIntentLocked(int callingUid,
4675            String targetPkg, Intent intent) {
4676        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4677                "Checking URI perm to " + (intent != null ? intent.getData() : null)
4678                + " from " + intent + "; flags=0x"
4679                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4680
4681        if (targetPkg == null) {
4682            throw new NullPointerException("targetPkg");
4683        }
4684
4685        if (intent == null) {
4686            return -1;
4687        }
4688        Uri data = intent.getData();
4689        if (data == null) {
4690            return -1;
4691        }
4692        return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4693                intent.getFlags());
4694    }
4695
4696    /**
4697     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4698     */
4699    void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4700            String targetPkg, Intent intent, UriPermissionOwner owner) {
4701        grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4702                intent.getFlags(), owner);
4703    }
4704
4705    void grantUriPermissionFromIntentLocked(int callingUid,
4706            String targetPkg, Intent intent, UriPermissionOwner owner) {
4707        int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4708        if (targetUid < 0) {
4709            return;
4710        }
4711
4712        grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
4713    }
4714
4715    public void grantUriPermission(IApplicationThread caller, String targetPkg,
4716            Uri uri, int modeFlags) {
4717        synchronized(this) {
4718            final ProcessRecord r = getRecordForAppLocked(caller);
4719            if (r == null) {
4720                throw new SecurityException("Unable to find app for caller "
4721                        + caller
4722                        + " when granting permission to uri " + uri);
4723            }
4724            if (targetPkg == null) {
4725                throw new IllegalArgumentException("null target");
4726            }
4727            if (uri == null) {
4728                throw new IllegalArgumentException("null uri");
4729            }
4730
4731            grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4732                    null);
4733        }
4734    }
4735
4736    void removeUriPermissionIfNeededLocked(UriPermission perm) {
4737        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4738                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4739            HashMap<Uri, UriPermission> perms
4740                    = mGrantedUriPermissions.get(perm.uid);
4741            if (perms != null) {
4742                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4743                        "Removing " + perm.uid + " permission to " + perm.uri);
4744                perms.remove(perm.uri);
4745                if (perms.size() == 0) {
4746                    mGrantedUriPermissions.remove(perm.uid);
4747                }
4748            }
4749        }
4750    }
4751
4752    private void revokeUriPermissionLocked(int callingUid, Uri uri,
4753            int modeFlags) {
4754        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4755                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4756        if (modeFlags == 0) {
4757            return;
4758        }
4759
4760        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4761                "Revoking all granted permissions to " + uri);
4762
4763        final IPackageManager pm = AppGlobals.getPackageManager();
4764
4765        final String authority = uri.getAuthority();
4766        ProviderInfo pi = null;
4767        ContentProviderRecord cpr = mProvidersByName.get(authority);
4768        if (cpr != null) {
4769            pi = cpr.info;
4770        } else {
4771            try {
4772                pi = pm.resolveContentProvider(authority,
4773                        PackageManager.GET_URI_PERMISSION_PATTERNS);
4774            } catch (RemoteException ex) {
4775            }
4776        }
4777        if (pi == null) {
4778            Slog.w(TAG, "No content provider found for: " + authority);
4779            return;
4780        }
4781
4782        // Does the caller have this permission on the URI?
4783        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4784            // Right now, if you are not the original owner of the permission,
4785            // you are not allowed to revoke it.
4786            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4787                throw new SecurityException("Uid " + callingUid
4788                        + " does not have permission to uri " + uri);
4789            //}
4790        }
4791
4792        // Go through all of the permissions and remove any that match.
4793        final List<String> SEGMENTS = uri.getPathSegments();
4794        if (SEGMENTS != null) {
4795            final int NS = SEGMENTS.size();
4796            int N = mGrantedUriPermissions.size();
4797            for (int i=0; i<N; i++) {
4798                HashMap<Uri, UriPermission> perms
4799                        = mGrantedUriPermissions.valueAt(i);
4800                Iterator<UriPermission> it = perms.values().iterator();
4801            toploop:
4802                while (it.hasNext()) {
4803                    UriPermission perm = it.next();
4804                    Uri targetUri = perm.uri;
4805                    if (!authority.equals(targetUri.getAuthority())) {
4806                        continue;
4807                    }
4808                    List<String> targetSegments = targetUri.getPathSegments();
4809                    if (targetSegments == null) {
4810                        continue;
4811                    }
4812                    if (targetSegments.size() < NS) {
4813                        continue;
4814                    }
4815                    for (int j=0; j<NS; j++) {
4816                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4817                            continue toploop;
4818                        }
4819                    }
4820                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4821                            "Revoking " + perm.uid + " permission to " + perm.uri);
4822                    perm.clearModes(modeFlags);
4823                    if (perm.modeFlags == 0) {
4824                        it.remove();
4825                    }
4826                }
4827                if (perms.size() == 0) {
4828                    mGrantedUriPermissions.remove(
4829                            mGrantedUriPermissions.keyAt(i));
4830                    N--;
4831                    i--;
4832                }
4833            }
4834        }
4835    }
4836
4837    public void revokeUriPermission(IApplicationThread caller, Uri uri,
4838            int modeFlags) {
4839        synchronized(this) {
4840            final ProcessRecord r = getRecordForAppLocked(caller);
4841            if (r == null) {
4842                throw new SecurityException("Unable to find app for caller "
4843                        + caller
4844                        + " when revoking permission to uri " + uri);
4845            }
4846            if (uri == null) {
4847                Slog.w(TAG, "revokeUriPermission: null uri");
4848                return;
4849            }
4850
4851            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4852                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4853            if (modeFlags == 0) {
4854                return;
4855            }
4856
4857            final IPackageManager pm = AppGlobals.getPackageManager();
4858
4859            final String authority = uri.getAuthority();
4860            ProviderInfo pi = null;
4861            ContentProviderRecord cpr = mProvidersByName.get(authority);
4862            if (cpr != null) {
4863                pi = cpr.info;
4864            } else {
4865                try {
4866                    pi = pm.resolveContentProvider(authority,
4867                            PackageManager.GET_URI_PERMISSION_PATTERNS);
4868                } catch (RemoteException ex) {
4869                }
4870            }
4871            if (pi == null) {
4872                Slog.w(TAG, "No content provider found for: " + authority);
4873                return;
4874            }
4875
4876            revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4877        }
4878    }
4879
4880    @Override
4881    public IBinder newUriPermissionOwner(String name) {
4882        synchronized(this) {
4883            UriPermissionOwner owner = new UriPermissionOwner(this, name);
4884            return owner.getExternalTokenLocked();
4885        }
4886    }
4887
4888    @Override
4889    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4890            Uri uri, int modeFlags) {
4891        synchronized(this) {
4892            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4893            if (owner == null) {
4894                throw new IllegalArgumentException("Unknown owner: " + token);
4895            }
4896            if (fromUid != Binder.getCallingUid()) {
4897                if (Binder.getCallingUid() != Process.myUid()) {
4898                    // Only system code can grant URI permissions on behalf
4899                    // of other users.
4900                    throw new SecurityException("nice try");
4901                }
4902            }
4903            if (targetPkg == null) {
4904                throw new IllegalArgumentException("null target");
4905            }
4906            if (uri == null) {
4907                throw new IllegalArgumentException("null uri");
4908            }
4909
4910            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4911        }
4912    }
4913
4914    @Override
4915    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4916        synchronized(this) {
4917            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4918            if (owner == null) {
4919                throw new IllegalArgumentException("Unknown owner: " + token);
4920            }
4921
4922            if (uri == null) {
4923                owner.removeUriPermissionsLocked(mode);
4924            } else {
4925                owner.removeUriPermissionLocked(uri, mode);
4926            }
4927        }
4928    }
4929
4930    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4931        synchronized (this) {
4932            ProcessRecord app =
4933                who != null ? getRecordForAppLocked(who) : null;
4934            if (app == null) return;
4935
4936            Message msg = Message.obtain();
4937            msg.what = WAIT_FOR_DEBUGGER_MSG;
4938            msg.obj = app;
4939            msg.arg1 = waiting ? 1 : 0;
4940            mHandler.sendMessage(msg);
4941        }
4942    }
4943
4944    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
4945        outInfo.availMem = Process.getFreeMemory();
4946        outInfo.threshold = HOME_APP_MEM;
4947        outInfo.lowMemory = outInfo.availMem <
4948                (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
4949    }
4950
4951    // =========================================================
4952    // TASK MANAGEMENT
4953    // =========================================================
4954
4955    public List getTasks(int maxNum, int flags,
4956                         IThumbnailReceiver receiver) {
4957        ArrayList list = new ArrayList();
4958
4959        PendingThumbnailsRecord pending = null;
4960        IApplicationThread topThumbnail = null;
4961        ActivityRecord topRecord = null;
4962
4963        synchronized(this) {
4964            if (localLOGV) Slog.v(
4965                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4966                + ", receiver=" + receiver);
4967
4968            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4969                    != PackageManager.PERMISSION_GRANTED) {
4970                if (receiver != null) {
4971                    // If the caller wants to wait for pending thumbnails,
4972                    // it ain't gonna get them.
4973                    try {
4974                        receiver.finished();
4975                    } catch (RemoteException ex) {
4976                    }
4977                }
4978                String msg = "Permission Denial: getTasks() from pid="
4979                        + Binder.getCallingPid()
4980                        + ", uid=" + Binder.getCallingUid()
4981                        + " requires " + android.Manifest.permission.GET_TASKS;
4982                Slog.w(TAG, msg);
4983                throw new SecurityException(msg);
4984            }
4985
4986            int pos = mMainStack.mHistory.size()-1;
4987            ActivityRecord next =
4988                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
4989            ActivityRecord top = null;
4990            TaskRecord curTask = null;
4991            int numActivities = 0;
4992            int numRunning = 0;
4993            while (pos >= 0 && maxNum > 0) {
4994                final ActivityRecord r = next;
4995                pos--;
4996                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
4997
4998                // Initialize state for next task if needed.
4999                if (top == null ||
5000                        (top.state == ActivityState.INITIALIZING
5001                            && top.task == r.task)) {
5002                    top = r;
5003                    curTask = r.task;
5004                    numActivities = numRunning = 0;
5005                }
5006
5007                // Add 'r' into the current task.
5008                numActivities++;
5009                if (r.app != null && r.app.thread != null) {
5010                    numRunning++;
5011                }
5012
5013                if (localLOGV) Slog.v(
5014                    TAG, r.intent.getComponent().flattenToShortString()
5015                    + ": task=" + r.task);
5016
5017                // If the next one is a different task, generate a new
5018                // TaskInfo entry for what we have.
5019                if (next == null || next.task != curTask) {
5020                    ActivityManager.RunningTaskInfo ci
5021                            = new ActivityManager.RunningTaskInfo();
5022                    ci.id = curTask.taskId;
5023                    ci.baseActivity = r.intent.getComponent();
5024                    ci.topActivity = top.intent.getComponent();
5025                    if (top.thumbHolder != null) {
5026                        ci.description = top.thumbHolder.lastDescription;
5027                    }
5028                    ci.numActivities = numActivities;
5029                    ci.numRunning = numRunning;
5030                    //System.out.println(
5031                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5032                    if (ci.thumbnail == null && receiver != null) {
5033                        if (localLOGV) Slog.v(
5034                            TAG, "State=" + top.state + "Idle=" + top.idle
5035                            + " app=" + top.app
5036                            + " thr=" + (top.app != null ? top.app.thread : null));
5037                        if (top.state == ActivityState.RESUMED
5038                                || top.state == ActivityState.PAUSING) {
5039                            if (top.idle && top.app != null
5040                                && top.app.thread != null) {
5041                                topRecord = top;
5042                                topThumbnail = top.app.thread;
5043                            } else {
5044                                top.thumbnailNeeded = true;
5045                            }
5046                        }
5047                        if (pending == null) {
5048                            pending = new PendingThumbnailsRecord(receiver);
5049                        }
5050                        pending.pendingRecords.add(top);
5051                    }
5052                    list.add(ci);
5053                    maxNum--;
5054                    top = null;
5055                }
5056            }
5057
5058            if (pending != null) {
5059                mPendingThumbnails.add(pending);
5060            }
5061        }
5062
5063        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5064
5065        if (topThumbnail != null) {
5066            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5067            try {
5068                topThumbnail.requestThumbnail(topRecord);
5069            } catch (Exception e) {
5070                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5071                sendPendingThumbnail(null, topRecord, null, null, true);
5072            }
5073        }
5074
5075        if (pending == null && receiver != null) {
5076            // In this case all thumbnails were available and the client
5077            // is being asked to be told when the remaining ones come in...
5078            // which is unusually, since the top-most currently running
5079            // activity should never have a canned thumbnail!  Oh well.
5080            try {
5081                receiver.finished();
5082            } catch (RemoteException ex) {
5083            }
5084        }
5085
5086        return list;
5087    }
5088
5089    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5090            int flags) {
5091        synchronized (this) {
5092            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5093                    "getRecentTasks()");
5094
5095            IPackageManager pm = AppGlobals.getPackageManager();
5096
5097            final int N = mRecentTasks.size();
5098            ArrayList<ActivityManager.RecentTaskInfo> res
5099                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5100                            maxNum < N ? maxNum : N);
5101            for (int i=0; i<N && maxNum > 0; i++) {
5102                TaskRecord tr = mRecentTasks.get(i);
5103                if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5104                        || (tr.intent == null)
5105                        || ((tr.intent.getFlags()
5106                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5107                    ActivityManager.RecentTaskInfo rti
5108                            = new ActivityManager.RecentTaskInfo();
5109                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5110                    rti.persistentId = tr.taskId;
5111                    rti.baseIntent = new Intent(
5112                            tr.intent != null ? tr.intent : tr.affinityIntent);
5113                    rti.origActivity = tr.origActivity;
5114                    rti.description = tr.lastDescription;
5115
5116                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5117                        // Check whether this activity is currently available.
5118                        try {
5119                            if (rti.origActivity != null) {
5120                                if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5121                                    continue;
5122                                }
5123                            } else if (rti.baseIntent != null) {
5124                                if (pm.queryIntentActivities(rti.baseIntent,
5125                                        null, 0) == null) {
5126                                    continue;
5127                                }
5128                            }
5129                        } catch (RemoteException e) {
5130                            // Will never happen.
5131                        }
5132                    }
5133
5134                    res.add(rti);
5135                    maxNum--;
5136                }
5137            }
5138            return res;
5139        }
5140    }
5141
5142    private TaskRecord taskForIdLocked(int id) {
5143        final int N = mRecentTasks.size();
5144        for (int i=0; i<N; i++) {
5145            TaskRecord tr = mRecentTasks.get(i);
5146            if (tr.taskId == id) {
5147                return tr;
5148            }
5149        }
5150        return null;
5151    }
5152
5153    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5154        synchronized (this) {
5155            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5156                    "getTaskThumbnails()");
5157            TaskRecord tr = taskForIdLocked(id);
5158            if (tr != null) {
5159                return mMainStack.getTaskThumbnailsLocked(tr);
5160            }
5161        }
5162        return null;
5163    }
5164
5165    public boolean removeSubTask(int taskId, int subTaskIndex) {
5166        synchronized (this) {
5167            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5168                    "removeSubTask()");
5169            long ident = Binder.clearCallingIdentity();
5170            try {
5171                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5172            } finally {
5173                Binder.restoreCallingIdentity(ident);
5174            }
5175        }
5176    }
5177
5178    private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
5179        TaskRecord tr = root.task;
5180        Intent baseIntent = new Intent(
5181                tr.intent != null ? tr.intent : tr.affinityIntent);
5182        ComponentName component = baseIntent.getComponent();
5183        if (component == null) {
5184            Slog.w(TAG, "Now component for base intent of task: " + tr);
5185            return;
5186        }
5187
5188        // Find any running services associated with this app.
5189        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5190        for (ServiceRecord sr : mServices.values()) {
5191            if (sr.packageName.equals(component.getPackageName())) {
5192                services.add(sr);
5193            }
5194        }
5195
5196        // Take care of any running services associated with the app.
5197        for (int i=0; i<services.size(); i++) {
5198            ServiceRecord sr = services.get(i);
5199            if (sr.startRequested) {
5200                if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
5201                    Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
5202                    stopServiceLocked(sr);
5203                } else {
5204                    sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5205                            sr.makeNextStartId(), baseIntent, -1));
5206                    if (sr.app != null && sr.app.thread != null) {
5207                        sendServiceArgsLocked(sr, false);
5208                    }
5209                }
5210            }
5211        }
5212
5213        if (killProcesses) {
5214            // Find any running processes associated with this app.
5215            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5216            SparseArray<ProcessRecord> appProcs
5217                    = mProcessNames.getMap().get(component.getPackageName());
5218            if (appProcs != null) {
5219                for (int i=0; i<appProcs.size(); i++) {
5220                    procs.add(appProcs.valueAt(i));
5221                }
5222            }
5223
5224            // Kill the running processes.
5225            for (int i=0; i<procs.size(); i++) {
5226                ProcessRecord pr = procs.get(i);
5227                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5228                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5229                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5230                            pr.processName, pr.setAdj, "remove task");
5231                    Process.killProcessQuiet(pr.pid);
5232                } else {
5233                    pr.waitingToKill = "remove task";
5234                }
5235            }
5236        }
5237    }
5238
5239    public boolean removeTask(int taskId, int flags) {
5240        synchronized (this) {
5241            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5242                    "removeTask()");
5243            long ident = Binder.clearCallingIdentity();
5244            try {
5245                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5246                if (r != null) {
5247                    mRecentTasks.remove(r.task);
5248                    cleanUpRemovedTaskLocked(r,
5249                            (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
5250                    return true;
5251                }
5252            } finally {
5253                Binder.restoreCallingIdentity(ident);
5254            }
5255        }
5256        return false;
5257    }
5258
5259    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5260        int j;
5261        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5262        TaskRecord jt = startTask;
5263
5264        // First look backwards
5265        for (j=startIndex-1; j>=0; j--) {
5266            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5267            if (r.task != jt) {
5268                jt = r.task;
5269                if (affinity.equals(jt.affinity)) {
5270                    return j;
5271                }
5272            }
5273        }
5274
5275        // Now look forwards
5276        final int N = mMainStack.mHistory.size();
5277        jt = startTask;
5278        for (j=startIndex+1; j<N; j++) {
5279            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5280            if (r.task != jt) {
5281                if (affinity.equals(jt.affinity)) {
5282                    return j;
5283                }
5284                jt = r.task;
5285            }
5286        }
5287
5288        // Might it be at the top?
5289        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5290            return N-1;
5291        }
5292
5293        return -1;
5294    }
5295
5296    /**
5297     * TODO: Add mController hook
5298     */
5299    public void moveTaskToFront(int task, int flags) {
5300        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5301                "moveTaskToFront()");
5302
5303        synchronized(this) {
5304            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5305                    Binder.getCallingUid(), "Task to front")) {
5306                return;
5307            }
5308            final long origId = Binder.clearCallingIdentity();
5309            try {
5310                TaskRecord tr = taskForIdLocked(task);
5311                if (tr != null) {
5312                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5313                        mMainStack.mUserLeaving = true;
5314                    }
5315                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5316                        // Caller wants the home activity moved with it.  To accomplish this,
5317                        // we'll just move the home task to the top first.
5318                        mMainStack.moveHomeToFrontLocked();
5319                    }
5320                    mMainStack.moveTaskToFrontLocked(tr, null);
5321                    return;
5322                }
5323                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5324                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5325                    if (hr.task.taskId == task) {
5326                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5327                            mMainStack.mUserLeaving = true;
5328                        }
5329                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5330                            // Caller wants the home activity moved with it.  To accomplish this,
5331                            // we'll just move the home task to the top first.
5332                            mMainStack.moveHomeToFrontLocked();
5333                        }
5334                        mMainStack.moveTaskToFrontLocked(hr.task, null);
5335                        return;
5336                    }
5337                }
5338            } finally {
5339                Binder.restoreCallingIdentity(origId);
5340            }
5341        }
5342    }
5343
5344    public void moveTaskToBack(int task) {
5345        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5346                "moveTaskToBack()");
5347
5348        synchronized(this) {
5349            if (mMainStack.mResumedActivity != null
5350                    && mMainStack.mResumedActivity.task.taskId == task) {
5351                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5352                        Binder.getCallingUid(), "Task to back")) {
5353                    return;
5354                }
5355            }
5356            final long origId = Binder.clearCallingIdentity();
5357            mMainStack.moveTaskToBackLocked(task, null);
5358            Binder.restoreCallingIdentity(origId);
5359        }
5360    }
5361
5362    /**
5363     * Moves an activity, and all of the other activities within the same task, to the bottom
5364     * of the history stack.  The activity's order within the task is unchanged.
5365     *
5366     * @param token A reference to the activity we wish to move
5367     * @param nonRoot If false then this only works if the activity is the root
5368     *                of a task; if true it will work for any activity in a task.
5369     * @return Returns true if the move completed, false if not.
5370     */
5371    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5372        synchronized(this) {
5373            final long origId = Binder.clearCallingIdentity();
5374            int taskId = getTaskForActivityLocked(token, !nonRoot);
5375            if (taskId >= 0) {
5376                return mMainStack.moveTaskToBackLocked(taskId, null);
5377            }
5378            Binder.restoreCallingIdentity(origId);
5379        }
5380        return false;
5381    }
5382
5383    public void moveTaskBackwards(int task) {
5384        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5385                "moveTaskBackwards()");
5386
5387        synchronized(this) {
5388            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5389                    Binder.getCallingUid(), "Task backwards")) {
5390                return;
5391            }
5392            final long origId = Binder.clearCallingIdentity();
5393            moveTaskBackwardsLocked(task);
5394            Binder.restoreCallingIdentity(origId);
5395        }
5396    }
5397
5398    private final void moveTaskBackwardsLocked(int task) {
5399        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5400    }
5401
5402    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5403        synchronized(this) {
5404            return getTaskForActivityLocked(token, onlyRoot);
5405        }
5406    }
5407
5408    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5409        final int N = mMainStack.mHistory.size();
5410        TaskRecord lastTask = null;
5411        for (int i=0; i<N; i++) {
5412            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5413            if (r == token) {
5414                if (!onlyRoot || lastTask != r.task) {
5415                    return r.task.taskId;
5416                }
5417                return -1;
5418            }
5419            lastTask = r.task;
5420        }
5421
5422        return -1;
5423    }
5424
5425    public void finishOtherInstances(IBinder token, ComponentName className) {
5426        synchronized(this) {
5427            final long origId = Binder.clearCallingIdentity();
5428
5429            int N = mMainStack.mHistory.size();
5430            TaskRecord lastTask = null;
5431            for (int i=0; i<N; i++) {
5432                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5433                if (r.realActivity.equals(className)
5434                        && r != token && lastTask != r.task) {
5435                    if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
5436                            null, "others")) {
5437                        i--;
5438                        N--;
5439                    }
5440                }
5441                lastTask = r.task;
5442            }
5443
5444            Binder.restoreCallingIdentity(origId);
5445        }
5446    }
5447
5448    // =========================================================
5449    // THUMBNAILS
5450    // =========================================================
5451
5452    public void reportThumbnail(IBinder token,
5453            Bitmap thumbnail, CharSequence description) {
5454        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5455        final long origId = Binder.clearCallingIdentity();
5456        sendPendingThumbnail(null, token, thumbnail, description, true);
5457        Binder.restoreCallingIdentity(origId);
5458    }
5459
5460    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5461            Bitmap thumbnail, CharSequence description, boolean always) {
5462        TaskRecord task = null;
5463        ArrayList receivers = null;
5464
5465        //System.out.println("Send pending thumbnail: " + r);
5466
5467        synchronized(this) {
5468            if (r == null) {
5469                int index = mMainStack.indexOfTokenLocked(token);
5470                if (index < 0) {
5471                    return;
5472                }
5473                r = (ActivityRecord)mMainStack.mHistory.get(index);
5474            }
5475            if (thumbnail == null && r.thumbHolder != null) {
5476                thumbnail = r.thumbHolder.lastThumbnail;
5477                description = r.thumbHolder.lastDescription;
5478            }
5479            if (thumbnail == null && !always) {
5480                // If there is no thumbnail, and this entry is not actually
5481                // going away, then abort for now and pick up the next
5482                // thumbnail we get.
5483                return;
5484            }
5485            task = r.task;
5486
5487            int N = mPendingThumbnails.size();
5488            int i=0;
5489            while (i<N) {
5490                PendingThumbnailsRecord pr =
5491                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5492                //System.out.println("Looking in " + pr.pendingRecords);
5493                if (pr.pendingRecords.remove(r)) {
5494                    if (receivers == null) {
5495                        receivers = new ArrayList();
5496                    }
5497                    receivers.add(pr);
5498                    if (pr.pendingRecords.size() == 0) {
5499                        pr.finished = true;
5500                        mPendingThumbnails.remove(i);
5501                        N--;
5502                        continue;
5503                    }
5504                }
5505                i++;
5506            }
5507        }
5508
5509        if (receivers != null) {
5510            final int N = receivers.size();
5511            for (int i=0; i<N; i++) {
5512                try {
5513                    PendingThumbnailsRecord pr =
5514                        (PendingThumbnailsRecord)receivers.get(i);
5515                    pr.receiver.newThumbnail(
5516                        task != null ? task.taskId : -1, thumbnail, description);
5517                    if (pr.finished) {
5518                        pr.receiver.finished();
5519                    }
5520                } catch (Exception e) {
5521                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
5522                }
5523            }
5524        }
5525    }
5526
5527    // =========================================================
5528    // CONTENT PROVIDERS
5529    // =========================================================
5530
5531    private final List generateApplicationProvidersLocked(ProcessRecord app) {
5532        List providers = null;
5533        try {
5534            providers = AppGlobals.getPackageManager().
5535                queryContentProviders(app.processName, app.info.uid,
5536                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
5537        } catch (RemoteException ex) {
5538        }
5539        if (providers != null) {
5540            final int N = providers.size();
5541            for (int i=0; i<N; i++) {
5542                ProviderInfo cpi =
5543                    (ProviderInfo)providers.get(i);
5544                ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
5545                if (cpr == null) {
5546                    cpr = new ContentProviderRecord(cpi, app.info);
5547                    mProvidersByClass.put(cpi.name, cpr);
5548                }
5549                app.pubProviders.put(cpi.name, cpr);
5550                app.addPackage(cpi.applicationInfo.packageName);
5551                ensurePackageDexOpt(cpi.applicationInfo.packageName);
5552            }
5553        }
5554        return providers;
5555    }
5556
5557    private final String checkContentProviderPermissionLocked(
5558            ProviderInfo cpi, ProcessRecord r) {
5559        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5560        final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5561        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
5562                cpi.applicationInfo.uid, cpi.exported)
5563                == PackageManager.PERMISSION_GRANTED) {
5564            return null;
5565        }
5566        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
5567                cpi.applicationInfo.uid, cpi.exported)
5568                == PackageManager.PERMISSION_GRANTED) {
5569            return null;
5570        }
5571
5572        PathPermission[] pps = cpi.pathPermissions;
5573        if (pps != null) {
5574            int i = pps.length;
5575            while (i > 0) {
5576                i--;
5577                PathPermission pp = pps[i];
5578                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
5579                        cpi.applicationInfo.uid, cpi.exported)
5580                        == PackageManager.PERMISSION_GRANTED) {
5581                    return null;
5582                }
5583                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
5584                        cpi.applicationInfo.uid, cpi.exported)
5585                        == PackageManager.PERMISSION_GRANTED) {
5586                    return null;
5587                }
5588            }
5589        }
5590
5591        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5592        if (perms != null) {
5593            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5594                if (uri.getKey().getAuthority().equals(cpi.authority)) {
5595                    return null;
5596                }
5597            }
5598        }
5599
5600        String msg;
5601        if (!cpi.exported) {
5602            msg = "Permission Denial: opening provider " + cpi.name
5603                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5604                    + ", uid=" + callingUid + ") that is not exported from uid "
5605                    + cpi.applicationInfo.uid;
5606        } else {
5607            msg = "Permission Denial: opening provider " + cpi.name
5608                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5609                    + ", uid=" + callingUid + ") requires "
5610                    + cpi.readPermission + " or " + cpi.writePermission;
5611        }
5612        Slog.w(TAG, msg);
5613        return msg;
5614    }
5615
5616    private final ContentProviderHolder getContentProviderImpl(
5617        IApplicationThread caller, String name) {
5618        ContentProviderRecord cpr;
5619        ProviderInfo cpi = null;
5620
5621        synchronized(this) {
5622            ProcessRecord r = null;
5623            if (caller != null) {
5624                r = getRecordForAppLocked(caller);
5625                if (r == null) {
5626                    throw new SecurityException(
5627                            "Unable to find app for caller " + caller
5628                          + " (pid=" + Binder.getCallingPid()
5629                          + ") when getting content provider " + name);
5630                }
5631            }
5632
5633            // First check if this content provider has been published...
5634            cpr = mProvidersByName.get(name);
5635            if (cpr != null) {
5636                cpi = cpr.info;
5637                String msg;
5638                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5639                    throw new SecurityException(msg);
5640                }
5641
5642                if (r != null && cpr.canRunHere(r)) {
5643                    // This provider has been published or is in the process
5644                    // of being published...  but it is also allowed to run
5645                    // in the caller's process, so don't make a connection
5646                    // and just let the caller instantiate its own instance.
5647                    if (cpr.provider != null) {
5648                        // don't give caller the provider object, it needs
5649                        // to make its own.
5650                        cpr = new ContentProviderRecord(cpr);
5651                    }
5652                    return cpr;
5653                }
5654
5655                final long origId = Binder.clearCallingIdentity();
5656
5657                // In this case the provider instance already exists, so we can
5658                // return it right away.
5659                if (r != null) {
5660                    if (DEBUG_PROVIDER) Slog.v(TAG,
5661                            "Adding provider requested by "
5662                            + r.processName + " from process "
5663                            + cpr.info.processName);
5664                    Integer cnt = r.conProviders.get(cpr);
5665                    if (cnt == null) {
5666                        r.conProviders.put(cpr, new Integer(1));
5667                    } else {
5668                        r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5669                    }
5670                    cpr.clients.add(r);
5671                    if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) {
5672                        // If this is a perceptible app accessing the provider,
5673                        // make sure to count it as being accessed and thus
5674                        // back up on the LRU list.  This is good because
5675                        // content providers are often expensive to start.
5676                        updateLruProcessLocked(cpr.app, false, true);
5677                    }
5678                } else {
5679                    cpr.externals++;
5680                }
5681
5682                if (cpr.app != null) {
5683                    updateOomAdjLocked(cpr.app);
5684                }
5685
5686                Binder.restoreCallingIdentity(origId);
5687
5688            } else {
5689                try {
5690                    cpi = AppGlobals.getPackageManager().
5691                        resolveContentProvider(name,
5692                                STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
5693                } catch (RemoteException ex) {
5694                }
5695                if (cpi == null) {
5696                    return null;
5697                }
5698
5699                String msg;
5700                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5701                    throw new SecurityException(msg);
5702                }
5703
5704                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
5705                        && !cpi.processName.equals("system")) {
5706                    // If this content provider does not run in the system
5707                    // process, and the system is not yet ready to run other
5708                    // processes, then fail fast instead of hanging.
5709                    throw new IllegalArgumentException(
5710                            "Attempt to launch content provider before system ready");
5711                }
5712
5713                cpr = mProvidersByClass.get(cpi.name);
5714                final boolean firstClass = cpr == null;
5715                if (firstClass) {
5716                    try {
5717                        ApplicationInfo ai =
5718                            AppGlobals.getPackageManager().
5719                                getApplicationInfo(
5720                                        cpi.applicationInfo.packageName,
5721                                        STOCK_PM_FLAGS);
5722                        if (ai == null) {
5723                            Slog.w(TAG, "No package info for content provider "
5724                                    + cpi.name);
5725                            return null;
5726                        }
5727                        cpr = new ContentProviderRecord(cpi, ai);
5728                    } catch (RemoteException ex) {
5729                        // pm is in same process, this will never happen.
5730                    }
5731                }
5732
5733                if (r != null && cpr.canRunHere(r)) {
5734                    // If this is a multiprocess provider, then just return its
5735                    // info and allow the caller to instantiate it.  Only do
5736                    // this if the provider is the same user as the caller's
5737                    // process, or can run as root (so can be in any process).
5738                    return cpr;
5739                }
5740
5741                if (DEBUG_PROVIDER) {
5742                    RuntimeException e = new RuntimeException("here");
5743                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
5744                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
5745                }
5746
5747                // This is single process, and our app is now connecting to it.
5748                // See if we are already in the process of launching this
5749                // provider.
5750                final int N = mLaunchingProviders.size();
5751                int i;
5752                for (i=0; i<N; i++) {
5753                    if (mLaunchingProviders.get(i) == cpr) {
5754                        break;
5755                    }
5756                }
5757
5758                // If the provider is not already being launched, then get it
5759                // started.
5760                if (i >= N) {
5761                    final long origId = Binder.clearCallingIdentity();
5762
5763                    try {
5764                        // Content provider is now in use, its package can't be stopped.
5765                        try {
5766                            AppGlobals.getPackageManager().setPackageStoppedState(
5767                                    cpr.appInfo.packageName, false);
5768                        } catch (RemoteException e) {
5769                        } catch (IllegalArgumentException e) {
5770                            Slog.w(TAG, "Failed trying to unstop package "
5771                                    + cpr.appInfo.packageName + ": " + e);
5772                        }
5773
5774                        ProcessRecord proc = startProcessLocked(cpi.processName,
5775                                cpr.appInfo, false, 0, "content provider",
5776                                new ComponentName(cpi.applicationInfo.packageName,
5777                                        cpi.name), false);
5778                        if (proc == null) {
5779                            Slog.w(TAG, "Unable to launch app "
5780                                    + cpi.applicationInfo.packageName + "/"
5781                                    + cpi.applicationInfo.uid + " for provider "
5782                                    + name + ": process is bad");
5783                            return null;
5784                        }
5785                        cpr.launchingApp = proc;
5786                        mLaunchingProviders.add(cpr);
5787                    } finally {
5788                        Binder.restoreCallingIdentity(origId);
5789                    }
5790                }
5791
5792                // Make sure the provider is published (the same provider class
5793                // may be published under multiple names).
5794                if (firstClass) {
5795                    mProvidersByClass.put(cpi.name, cpr);
5796                }
5797                mProvidersByName.put(name, cpr);
5798
5799                if (r != null) {
5800                    if (DEBUG_PROVIDER) Slog.v(TAG,
5801                            "Adding provider requested by "
5802                            + r.processName + " from process "
5803                            + cpr.info.processName);
5804                    Integer cnt = r.conProviders.get(cpr);
5805                    if (cnt == null) {
5806                        r.conProviders.put(cpr, new Integer(1));
5807                    } else {
5808                        r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5809                    }
5810                    cpr.clients.add(r);
5811                } else {
5812                    cpr.externals++;
5813                }
5814            }
5815        }
5816
5817        // Wait for the provider to be published...
5818        synchronized (cpr) {
5819            while (cpr.provider == null) {
5820                if (cpr.launchingApp == null) {
5821                    Slog.w(TAG, "Unable to launch app "
5822                            + cpi.applicationInfo.packageName + "/"
5823                            + cpi.applicationInfo.uid + " for provider "
5824                            + name + ": launching app became null");
5825                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
5826                            cpi.applicationInfo.packageName,
5827                            cpi.applicationInfo.uid, name);
5828                    return null;
5829                }
5830                try {
5831                    cpr.wait();
5832                } catch (InterruptedException ex) {
5833                }
5834            }
5835        }
5836        return cpr;
5837    }
5838
5839    public final ContentProviderHolder getContentProvider(
5840            IApplicationThread caller, String name) {
5841        if (caller == null) {
5842            String msg = "null IApplicationThread when getting content provider "
5843                    + name;
5844            Slog.w(TAG, msg);
5845            throw new SecurityException(msg);
5846        }
5847
5848        return getContentProviderImpl(caller, name);
5849    }
5850
5851    private ContentProviderHolder getContentProviderExternal(String name) {
5852        return getContentProviderImpl(null, name);
5853    }
5854
5855    /**
5856     * Drop a content provider from a ProcessRecord's bookkeeping
5857     * @param cpr
5858     */
5859    public void removeContentProvider(IApplicationThread caller, String name) {
5860        synchronized (this) {
5861            ContentProviderRecord cpr = mProvidersByName.get(name);
5862            if(cpr == null) {
5863                // remove from mProvidersByClass
5864                if (DEBUG_PROVIDER) Slog.v(TAG, name +
5865                        " provider not found in providers list");
5866                return;
5867            }
5868            final ProcessRecord r = getRecordForAppLocked(caller);
5869            if (r == null) {
5870                throw new SecurityException(
5871                        "Unable to find app for caller " + caller +
5872                        " when removing content provider " + name);
5873            }
5874            //update content provider record entry info
5875            ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
5876            if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
5877                    + r.info.processName + " from process "
5878                    + localCpr.appInfo.processName);
5879            if (localCpr.app == r) {
5880                //should not happen. taken care of as a local provider
5881                Slog.w(TAG, "removeContentProvider called on local provider: "
5882                        + cpr.info.name + " in process " + r.processName);
5883                return;
5884            } else {
5885                Integer cnt = r.conProviders.get(localCpr);
5886                if (cnt == null || cnt.intValue() <= 1) {
5887                    localCpr.clients.remove(r);
5888                    r.conProviders.remove(localCpr);
5889                } else {
5890                    r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5891                }
5892            }
5893            updateOomAdjLocked();
5894        }
5895    }
5896
5897    private void removeContentProviderExternal(String name) {
5898        synchronized (this) {
5899            ContentProviderRecord cpr = mProvidersByName.get(name);
5900            if(cpr == null) {
5901                //remove from mProvidersByClass
5902                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
5903                return;
5904            }
5905
5906            //update content provider record entry info
5907            ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
5908            localCpr.externals--;
5909            if (localCpr.externals < 0) {
5910                Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
5911            }
5912            updateOomAdjLocked();
5913        }
5914    }
5915
5916    public final void publishContentProviders(IApplicationThread caller,
5917            List<ContentProviderHolder> providers) {
5918        if (providers == null) {
5919            return;
5920        }
5921
5922        synchronized(this) {
5923            final ProcessRecord r = getRecordForAppLocked(caller);
5924            if (r == null) {
5925                throw new SecurityException(
5926                        "Unable to find app for caller " + caller
5927                      + " (pid=" + Binder.getCallingPid()
5928                      + ") when publishing content providers");
5929            }
5930
5931            final long origId = Binder.clearCallingIdentity();
5932
5933            final int N = providers.size();
5934            for (int i=0; i<N; i++) {
5935                ContentProviderHolder src = providers.get(i);
5936                if (src == null || src.info == null || src.provider == null) {
5937                    continue;
5938                }
5939                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
5940                if (dst != null) {
5941                    mProvidersByClass.put(dst.info.name, dst);
5942                    String names[] = dst.info.authority.split(";");
5943                    for (int j = 0; j < names.length; j++) {
5944                        mProvidersByName.put(names[j], dst);
5945                    }
5946
5947                    int NL = mLaunchingProviders.size();
5948                    int j;
5949                    for (j=0; j<NL; j++) {
5950                        if (mLaunchingProviders.get(j) == dst) {
5951                            mLaunchingProviders.remove(j);
5952                            j--;
5953                            NL--;
5954                        }
5955                    }
5956                    synchronized (dst) {
5957                        dst.provider = src.provider;
5958                        dst.app = r;
5959                        dst.notifyAll();
5960                    }
5961                    updateOomAdjLocked(r);
5962                }
5963            }
5964
5965            Binder.restoreCallingIdentity(origId);
5966        }
5967    }
5968
5969    public static final void installSystemProviders() {
5970        List providers;
5971        synchronized (mSelf) {
5972            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5973            providers = mSelf.generateApplicationProvidersLocked(app);
5974            if (providers != null) {
5975                for (int i=providers.size()-1; i>=0; i--) {
5976                    ProviderInfo pi = (ProviderInfo)providers.get(i);
5977                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5978                        Slog.w(TAG, "Not installing system proc provider " + pi.name
5979                                + ": not system .apk");
5980                        providers.remove(i);
5981                    }
5982                }
5983            }
5984        }
5985        if (providers != null) {
5986            mSystemThread.installSystemProviders(providers);
5987        }
5988
5989        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
5990    }
5991
5992    /**
5993     * Allows app to retrieve the MIME type of a URI without having permission
5994     * to access its content provider.
5995     *
5996     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5997     *
5998     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5999     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6000     */
6001    public String getProviderMimeType(Uri uri) {
6002        final String name = uri.getAuthority();
6003        final long ident = Binder.clearCallingIdentity();
6004        ContentProviderHolder holder = null;
6005
6006        try {
6007            holder = getContentProviderExternal(name);
6008            if (holder != null) {
6009                return holder.provider.getType(uri);
6010            }
6011        } catch (RemoteException e) {
6012            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6013            return null;
6014        } finally {
6015            if (holder != null) {
6016                removeContentProviderExternal(name);
6017            }
6018            Binder.restoreCallingIdentity(ident);
6019        }
6020
6021        return null;
6022    }
6023
6024    // =========================================================
6025    // GLOBAL MANAGEMENT
6026    // =========================================================
6027
6028    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6029            ApplicationInfo info, String customProcess) {
6030        String proc = customProcess != null ? customProcess : info.processName;
6031        BatteryStatsImpl.Uid.Proc ps = null;
6032        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6033        synchronized (stats) {
6034            ps = stats.getProcessStatsLocked(info.uid, proc);
6035        }
6036        return new ProcessRecord(ps, thread, info, proc);
6037    }
6038
6039    final ProcessRecord addAppLocked(ApplicationInfo info) {
6040        ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6041
6042        if (app == null) {
6043            app = newProcessRecordLocked(null, info, null);
6044            mProcessNames.put(info.processName, info.uid, app);
6045            updateLruProcessLocked(app, true, true);
6046        }
6047
6048        // This package really, really can not be stopped.
6049        try {
6050            AppGlobals.getPackageManager().setPackageStoppedState(
6051                    info.packageName, false);
6052        } catch (RemoteException e) {
6053        } catch (IllegalArgumentException e) {
6054            Slog.w(TAG, "Failed trying to unstop package "
6055                    + info.packageName + ": " + e);
6056        }
6057
6058        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6059                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6060            app.persistent = true;
6061            app.maxAdj = CORE_SERVER_ADJ;
6062        }
6063        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6064            mPersistentStartingProcesses.add(app);
6065            startProcessLocked(app, "added application", app.processName);
6066        }
6067
6068        return app;
6069    }
6070
6071    public void unhandledBack() {
6072        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6073                "unhandledBack()");
6074
6075        synchronized(this) {
6076            int count = mMainStack.mHistory.size();
6077            if (DEBUG_SWITCH) Slog.d(
6078                TAG, "Performing unhandledBack(): stack size = " + count);
6079            if (count > 1) {
6080                final long origId = Binder.clearCallingIdentity();
6081                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6082                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6083                Binder.restoreCallingIdentity(origId);
6084            }
6085        }
6086    }
6087
6088    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6089        String name = uri.getAuthority();
6090        ContentProviderHolder cph = getContentProviderExternal(name);
6091        ParcelFileDescriptor pfd = null;
6092        if (cph != null) {
6093            // We record the binder invoker's uid in thread-local storage before
6094            // going to the content provider to open the file.  Later, in the code
6095            // that handles all permissions checks, we look for this uid and use
6096            // that rather than the Activity Manager's own uid.  The effect is that
6097            // we do the check against the caller's permissions even though it looks
6098            // to the content provider like the Activity Manager itself is making
6099            // the request.
6100            sCallerIdentity.set(new Identity(
6101                    Binder.getCallingPid(), Binder.getCallingUid()));
6102            try {
6103                pfd = cph.provider.openFile(uri, "r");
6104            } catch (FileNotFoundException e) {
6105                // do nothing; pfd will be returned null
6106            } finally {
6107                // Ensure that whatever happens, we clean up the identity state
6108                sCallerIdentity.remove();
6109            }
6110
6111            // We've got the fd now, so we're done with the provider.
6112            removeContentProviderExternal(name);
6113        } else {
6114            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6115        }
6116        return pfd;
6117    }
6118
6119    // Actually is sleeping or shutting down or whatever else in the future
6120    // is an inactive state.
6121    public boolean isSleeping() {
6122        return mSleeping || mShuttingDown;
6123    }
6124
6125    public void goingToSleep() {
6126        synchronized(this) {
6127            mSleeping = true;
6128            mWindowManager.setEventDispatching(false);
6129
6130            mMainStack.stopIfSleepingLocked();
6131
6132            // Initialize the wake times of all processes.
6133            checkExcessivePowerUsageLocked(false);
6134            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6135            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6136            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6137        }
6138    }
6139
6140    public boolean shutdown(int timeout) {
6141        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6142                != PackageManager.PERMISSION_GRANTED) {
6143            throw new SecurityException("Requires permission "
6144                    + android.Manifest.permission.SHUTDOWN);
6145        }
6146
6147        boolean timedout = false;
6148
6149        synchronized(this) {
6150            mShuttingDown = true;
6151            mWindowManager.setEventDispatching(false);
6152
6153            if (mMainStack.mResumedActivity != null) {
6154                mMainStack.stopIfSleepingLocked();
6155                final long endTime = System.currentTimeMillis() + timeout;
6156                while (mMainStack.mResumedActivity != null
6157                        || mMainStack.mPausingActivity != null) {
6158                    long delay = endTime - System.currentTimeMillis();
6159                    if (delay <= 0) {
6160                        Slog.w(TAG, "Activity manager shutdown timed out");
6161                        timedout = true;
6162                        break;
6163                    }
6164                    try {
6165                        this.wait();
6166                    } catch (InterruptedException e) {
6167                    }
6168                }
6169            }
6170        }
6171
6172        mUsageStatsService.shutdown();
6173        mBatteryStatsService.shutdown();
6174
6175        return timedout;
6176    }
6177
6178    public final void activitySlept(IBinder token) {
6179        if (localLOGV) Slog.v(
6180            TAG, "Activity slept: token=" + token);
6181
6182        ActivityRecord r = null;
6183
6184        final long origId = Binder.clearCallingIdentity();
6185
6186        synchronized (this) {
6187            int index = mMainStack.indexOfTokenLocked(token);
6188            if (index >= 0) {
6189                r = (ActivityRecord)mMainStack.mHistory.get(index);
6190                mMainStack.activitySleptLocked(r);
6191            }
6192        }
6193
6194        Binder.restoreCallingIdentity(origId);
6195    }
6196
6197    public void wakingUp() {
6198        synchronized(this) {
6199            mWindowManager.setEventDispatching(true);
6200            mSleeping = false;
6201            mMainStack.awakeFromSleepingLocked();
6202            mMainStack.resumeTopActivityLocked(null);
6203        }
6204    }
6205
6206    public void stopAppSwitches() {
6207        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6208                != PackageManager.PERMISSION_GRANTED) {
6209            throw new SecurityException("Requires permission "
6210                    + android.Manifest.permission.STOP_APP_SWITCHES);
6211        }
6212
6213        synchronized(this) {
6214            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6215                    + APP_SWITCH_DELAY_TIME;
6216            mDidAppSwitch = false;
6217            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6218            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6219            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6220        }
6221    }
6222
6223    public void resumeAppSwitches() {
6224        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6225                != PackageManager.PERMISSION_GRANTED) {
6226            throw new SecurityException("Requires permission "
6227                    + android.Manifest.permission.STOP_APP_SWITCHES);
6228        }
6229
6230        synchronized(this) {
6231            // Note that we don't execute any pending app switches... we will
6232            // let those wait until either the timeout, or the next start
6233            // activity request.
6234            mAppSwitchesAllowedTime = 0;
6235        }
6236    }
6237
6238    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6239            String name) {
6240        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6241            return true;
6242        }
6243
6244        final int perm = checkComponentPermission(
6245                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
6246                callingUid, -1, true);
6247        if (perm == PackageManager.PERMISSION_GRANTED) {
6248            return true;
6249        }
6250
6251        Slog.w(TAG, name + " request from " + callingUid + " stopped");
6252        return false;
6253    }
6254
6255    public void setDebugApp(String packageName, boolean waitForDebugger,
6256            boolean persistent) {
6257        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6258                "setDebugApp()");
6259
6260        // Note that this is not really thread safe if there are multiple
6261        // callers into it at the same time, but that's not a situation we
6262        // care about.
6263        if (persistent) {
6264            final ContentResolver resolver = mContext.getContentResolver();
6265            Settings.System.putString(
6266                resolver, Settings.System.DEBUG_APP,
6267                packageName);
6268            Settings.System.putInt(
6269                resolver, Settings.System.WAIT_FOR_DEBUGGER,
6270                waitForDebugger ? 1 : 0);
6271        }
6272
6273        synchronized (this) {
6274            if (!persistent) {
6275                mOrigDebugApp = mDebugApp;
6276                mOrigWaitForDebugger = mWaitForDebugger;
6277            }
6278            mDebugApp = packageName;
6279            mWaitForDebugger = waitForDebugger;
6280            mDebugTransient = !persistent;
6281            if (packageName != null) {
6282                final long origId = Binder.clearCallingIdentity();
6283                forceStopPackageLocked(packageName, -1, false, false, true);
6284                Binder.restoreCallingIdentity(origId);
6285            }
6286        }
6287    }
6288
6289    public void setAlwaysFinish(boolean enabled) {
6290        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6291                "setAlwaysFinish()");
6292
6293        Settings.System.putInt(
6294                mContext.getContentResolver(),
6295                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6296
6297        synchronized (this) {
6298            mAlwaysFinishActivities = enabled;
6299        }
6300    }
6301
6302    public void setActivityController(IActivityController controller) {
6303        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
6304                "setActivityController()");
6305        synchronized (this) {
6306            mController = controller;
6307        }
6308    }
6309
6310    public boolean isUserAMonkey() {
6311        // For now the fact that there is a controller implies
6312        // we have a monkey.
6313        synchronized (this) {
6314            return mController != null;
6315        }
6316    }
6317
6318    public void registerActivityWatcher(IActivityWatcher watcher) {
6319        synchronized (this) {
6320            mWatchers.register(watcher);
6321        }
6322    }
6323
6324    public void unregisterActivityWatcher(IActivityWatcher watcher) {
6325        synchronized (this) {
6326            mWatchers.unregister(watcher);
6327        }
6328    }
6329
6330    public void registerProcessObserver(IProcessObserver observer) {
6331        mProcessObservers.register(observer);
6332    }
6333
6334    public void unregisterProcessObserver(IProcessObserver observer) {
6335        mProcessObservers.unregister(observer);
6336    }
6337
6338    public void setImmersive(IBinder token, boolean immersive) {
6339        synchronized(this) {
6340            int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
6341            if (index < 0) {
6342                throw new IllegalArgumentException();
6343            }
6344            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
6345            r.immersive = immersive;
6346        }
6347    }
6348
6349    public boolean isImmersive(IBinder token) {
6350        synchronized (this) {
6351            int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
6352            if (index < 0) {
6353                throw new IllegalArgumentException();
6354            }
6355            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
6356            return r.immersive;
6357        }
6358    }
6359
6360    public boolean isTopActivityImmersive() {
6361        synchronized (this) {
6362            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
6363            return (r != null) ? r.immersive : false;
6364        }
6365    }
6366
6367    public final void enterSafeMode() {
6368        synchronized(this) {
6369            // It only makes sense to do this before the system is ready
6370            // and started launching other packages.
6371            if (!mSystemReady) {
6372                try {
6373                    AppGlobals.getPackageManager().enterSafeMode();
6374                } catch (RemoteException e) {
6375                }
6376            }
6377        }
6378    }
6379
6380    public final void showSafeModeOverlay() {
6381        View v = LayoutInflater.from(mContext).inflate(
6382                com.android.internal.R.layout.safe_mode, null);
6383        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6384        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6385        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6386        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6387        lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6388        lp.format = v.getBackground().getOpacity();
6389        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6390                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6391        ((WindowManager)mContext.getSystemService(
6392                Context.WINDOW_SERVICE)).addView(v, lp);
6393    }
6394
6395    public void noteWakeupAlarm(IIntentSender sender) {
6396        if (!(sender instanceof PendingIntentRecord)) {
6397            return;
6398        }
6399        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6400        synchronized (stats) {
6401            if (mBatteryStatsService.isOnBattery()) {
6402                mBatteryStatsService.enforceCallingPermission();
6403                PendingIntentRecord rec = (PendingIntentRecord)sender;
6404                int MY_UID = Binder.getCallingUid();
6405                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6406                BatteryStatsImpl.Uid.Pkg pkg =
6407                    stats.getPackageStatsLocked(uid, rec.key.packageName);
6408                pkg.incWakeupsLocked();
6409            }
6410        }
6411    }
6412
6413    public boolean killPids(int[] pids, String pReason, boolean secure) {
6414        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
6415            throw new SecurityException("killPids only available to the system");
6416        }
6417        String reason = (pReason == null) ? "Unknown" : pReason;
6418        // XXX Note: don't acquire main activity lock here, because the window
6419        // manager calls in with its locks held.
6420
6421        boolean killed = false;
6422        synchronized (mPidsSelfLocked) {
6423            int[] types = new int[pids.length];
6424            int worstType = 0;
6425            for (int i=0; i<pids.length; i++) {
6426                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6427                if (proc != null) {
6428                    int type = proc.setAdj;
6429                    types[i] = type;
6430                    if (type > worstType) {
6431                        worstType = type;
6432                    }
6433                }
6434            }
6435
6436            // If the worst oom_adj is somewhere in the hidden proc LRU range,
6437            // then constrain it so we will kill all hidden procs.
6438            if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
6439                worstType = HIDDEN_APP_MIN_ADJ;
6440            }
6441
6442            // If this is not a secure call, don't let it kill processes that
6443            // are important.
6444            if (!secure && worstType < SECONDARY_SERVER_ADJ) {
6445                worstType = SECONDARY_SERVER_ADJ;
6446            }
6447
6448            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
6449            for (int i=0; i<pids.length; i++) {
6450                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6451                if (proc == null) {
6452                    continue;
6453                }
6454                int adj = proc.setAdj;
6455                if (adj >= worstType && !proc.killedBackground) {
6456                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
6457                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6458                            proc.processName, adj, reason);
6459                    killed = true;
6460                    proc.killedBackground = true;
6461                    Process.killProcessQuiet(pids[i]);
6462                }
6463            }
6464        }
6465        return killed;
6466    }
6467
6468    public final void startRunning(String pkg, String cls, String action,
6469            String data) {
6470        synchronized(this) {
6471            if (mStartRunning) {
6472                return;
6473            }
6474            mStartRunning = true;
6475            mTopComponent = pkg != null && cls != null
6476                    ? new ComponentName(pkg, cls) : null;
6477            mTopAction = action != null ? action : Intent.ACTION_MAIN;
6478            mTopData = data;
6479            if (!mSystemReady) {
6480                return;
6481            }
6482        }
6483
6484        systemReady(null);
6485    }
6486
6487    private void retrieveSettings() {
6488        final ContentResolver resolver = mContext.getContentResolver();
6489        String debugApp = Settings.System.getString(
6490            resolver, Settings.System.DEBUG_APP);
6491        boolean waitForDebugger = Settings.System.getInt(
6492            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6493        boolean alwaysFinishActivities = Settings.System.getInt(
6494            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6495
6496        Configuration configuration = new Configuration();
6497        Settings.System.getConfiguration(resolver, configuration);
6498
6499        synchronized (this) {
6500            mDebugApp = mOrigDebugApp = debugApp;
6501            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6502            mAlwaysFinishActivities = alwaysFinishActivities;
6503            // This happens before any activities are started, so we can
6504            // change mConfiguration in-place.
6505            mConfiguration.updateFrom(configuration);
6506            mConfigurationSeq = mConfiguration.seq = 1;
6507            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
6508        }
6509    }
6510
6511    public boolean testIsSystemReady() {
6512        // no need to synchronize(this) just to read & return the value
6513        return mSystemReady;
6514    }
6515
6516    private static File getCalledPreBootReceiversFile() {
6517        File dataDir = Environment.getDataDirectory();
6518        File systemDir = new File(dataDir, "system");
6519        File fname = new File(systemDir, "called_pre_boots.dat");
6520        return fname;
6521    }
6522
6523    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6524        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6525        File file = getCalledPreBootReceiversFile();
6526        FileInputStream fis = null;
6527        try {
6528            fis = new FileInputStream(file);
6529            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6530            int vers = dis.readInt();
6531            String codename = dis.readUTF();
6532            if (vers == android.os.Build.VERSION.SDK_INT
6533                    && codename.equals(android.os.Build.VERSION.CODENAME)) {
6534                int num = dis.readInt();
6535                while (num > 0) {
6536                    num--;
6537                    String pkg = dis.readUTF();
6538                    String cls = dis.readUTF();
6539                    lastDoneReceivers.add(new ComponentName(pkg, cls));
6540                }
6541            }
6542        } catch (FileNotFoundException e) {
6543        } catch (IOException e) {
6544            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6545        } finally {
6546            if (fis != null) {
6547                try {
6548                    fis.close();
6549                } catch (IOException e) {
6550                }
6551            }
6552        }
6553        return lastDoneReceivers;
6554    }
6555
6556    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6557        File file = getCalledPreBootReceiversFile();
6558        FileOutputStream fos = null;
6559        DataOutputStream dos = null;
6560        try {
6561            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6562            fos = new FileOutputStream(file);
6563            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6564            dos.writeInt(android.os.Build.VERSION.SDK_INT);
6565            dos.writeUTF(android.os.Build.VERSION.CODENAME);
6566            dos.writeInt(list.size());
6567            for (int i=0; i<list.size(); i++) {
6568                dos.writeUTF(list.get(i).getPackageName());
6569                dos.writeUTF(list.get(i).getClassName());
6570            }
6571        } catch (IOException e) {
6572            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6573            file.delete();
6574        } finally {
6575            FileUtils.sync(fos);
6576            if (dos != null) {
6577                try {
6578                    dos.close();
6579                } catch (IOException e) {
6580                    // TODO Auto-generated catch block
6581                    e.printStackTrace();
6582                }
6583            }
6584        }
6585    }
6586
6587    public void systemReady(final Runnable goingCallback) {
6588        // In the simulator, startRunning will never have been called, which
6589        // normally sets a few crucial variables. Do it here instead.
6590        if (!Process.supportsProcesses()) {
6591            mStartRunning = true;
6592            mTopAction = Intent.ACTION_MAIN;
6593        }
6594
6595        synchronized(this) {
6596            if (mSystemReady) {
6597                if (goingCallback != null) goingCallback.run();
6598                return;
6599            }
6600
6601            // Check to see if there are any update receivers to run.
6602            if (!mDidUpdate) {
6603                if (mWaitingUpdate) {
6604                    return;
6605                }
6606                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6607                List<ResolveInfo> ris = null;
6608                try {
6609                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
6610                                intent, null, 0);
6611                } catch (RemoteException e) {
6612                }
6613                if (ris != null) {
6614                    for (int i=ris.size()-1; i>=0; i--) {
6615                        if ((ris.get(i).activityInfo.applicationInfo.flags
6616                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
6617                            ris.remove(i);
6618                        }
6619                    }
6620                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
6621
6622                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6623
6624                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
6625                    for (int i=0; i<ris.size(); i++) {
6626                        ActivityInfo ai = ris.get(i).activityInfo;
6627                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
6628                        if (lastDoneReceivers.contains(comp)) {
6629                            ris.remove(i);
6630                            i--;
6631                        }
6632                    }
6633
6634                    for (int i=0; i<ris.size(); i++) {
6635                        ActivityInfo ai = ris.get(i).activityInfo;
6636                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
6637                        doneReceivers.add(comp);
6638                        intent.setComponent(comp);
6639                        IIntentReceiver finisher = null;
6640                        if (i == ris.size()-1) {
6641                            finisher = new IIntentReceiver.Stub() {
6642                                public void performReceive(Intent intent, int resultCode,
6643                                        String data, Bundle extras, boolean ordered,
6644                                        boolean sticky) {
6645                                    // The raw IIntentReceiver interface is called
6646                                    // with the AM lock held, so redispatch to
6647                                    // execute our code without the lock.
6648                                    mHandler.post(new Runnable() {
6649                                        public void run() {
6650                                            synchronized (ActivityManagerService.this) {
6651                                                mDidUpdate = true;
6652                                            }
6653                                            writeLastDonePreBootReceivers(doneReceivers);
6654                                            systemReady(goingCallback);
6655                                        }
6656                                    });
6657                                }
6658                            };
6659                        }
6660                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
6661                        broadcastIntentLocked(null, null, intent, null, finisher,
6662                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
6663                        if (finisher != null) {
6664                            mWaitingUpdate = true;
6665                        }
6666                    }
6667                }
6668                if (mWaitingUpdate) {
6669                    return;
6670                }
6671                mDidUpdate = true;
6672            }
6673
6674            mSystemReady = true;
6675            if (!mStartRunning) {
6676                return;
6677            }
6678        }
6679
6680        ArrayList<ProcessRecord> procsToKill = null;
6681        synchronized(mPidsSelfLocked) {
6682            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6683                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6684                if (!isAllowedWhileBooting(proc.info)){
6685                    if (procsToKill == null) {
6686                        procsToKill = new ArrayList<ProcessRecord>();
6687                    }
6688                    procsToKill.add(proc);
6689                }
6690            }
6691        }
6692
6693        synchronized(this) {
6694            if (procsToKill != null) {
6695                for (int i=procsToKill.size()-1; i>=0; i--) {
6696                    ProcessRecord proc = procsToKill.get(i);
6697                    Slog.i(TAG, "Removing system update proc: " + proc);
6698                    removeProcessLocked(proc, true);
6699                }
6700            }
6701
6702            // Now that we have cleaned up any update processes, we
6703            // are ready to start launching real processes and know that
6704            // we won't trample on them any more.
6705            mProcessesReady = true;
6706        }
6707
6708        Slog.i(TAG, "System now ready");
6709        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
6710            SystemClock.uptimeMillis());
6711
6712        synchronized(this) {
6713            // Make sure we have no pre-ready processes sitting around.
6714
6715            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6716                ResolveInfo ri = mContext.getPackageManager()
6717                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
6718                                STOCK_PM_FLAGS);
6719                CharSequence errorMsg = null;
6720                if (ri != null) {
6721                    ActivityInfo ai = ri.activityInfo;
6722                    ApplicationInfo app = ai.applicationInfo;
6723                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6724                        mTopAction = Intent.ACTION_FACTORY_TEST;
6725                        mTopData = null;
6726                        mTopComponent = new ComponentName(app.packageName,
6727                                ai.name);
6728                    } else {
6729                        errorMsg = mContext.getResources().getText(
6730                                com.android.internal.R.string.factorytest_not_system);
6731                    }
6732                } else {
6733                    errorMsg = mContext.getResources().getText(
6734                            com.android.internal.R.string.factorytest_no_action);
6735                }
6736                if (errorMsg != null) {
6737                    mTopAction = null;
6738                    mTopData = null;
6739                    mTopComponent = null;
6740                    Message msg = Message.obtain();
6741                    msg.what = SHOW_FACTORY_ERROR_MSG;
6742                    msg.getData().putCharSequence("msg", errorMsg);
6743                    mHandler.sendMessage(msg);
6744                }
6745            }
6746        }
6747
6748        retrieveSettings();
6749
6750        if (goingCallback != null) goingCallback.run();
6751
6752        synchronized (this) {
6753            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6754                try {
6755                    List apps = AppGlobals.getPackageManager().
6756                        getPersistentApplications(STOCK_PM_FLAGS);
6757                    if (apps != null) {
6758                        int N = apps.size();
6759                        int i;
6760                        for (i=0; i<N; i++) {
6761                            ApplicationInfo info
6762                                = (ApplicationInfo)apps.get(i);
6763                            if (info != null &&
6764                                    !info.packageName.equals("android")) {
6765                                addAppLocked(info);
6766                            }
6767                        }
6768                    }
6769                } catch (RemoteException ex) {
6770                    // pm is in same process, this will never happen.
6771                }
6772            }
6773
6774            // Start up initial activity.
6775            mBooting = true;
6776
6777            try {
6778                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
6779                    Message msg = Message.obtain();
6780                    msg.what = SHOW_UID_ERROR_MSG;
6781                    mHandler.sendMessage(msg);
6782                }
6783            } catch (RemoteException e) {
6784            }
6785
6786            mMainStack.resumeTopActivityLocked(null);
6787        }
6788    }
6789
6790    private boolean makeAppCrashingLocked(ProcessRecord app,
6791            String shortMsg, String longMsg, String stackTrace) {
6792        app.crashing = true;
6793        app.crashingReport = generateProcessError(app,
6794                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
6795        startAppProblemLocked(app);
6796        app.stopFreezingAllLocked();
6797        return handleAppCrashLocked(app);
6798    }
6799
6800    private void makeAppNotRespondingLocked(ProcessRecord app,
6801            String activity, String shortMsg, String longMsg) {
6802        app.notResponding = true;
6803        app.notRespondingReport = generateProcessError(app,
6804                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6805                activity, shortMsg, longMsg, null);
6806        startAppProblemLocked(app);
6807        app.stopFreezingAllLocked();
6808    }
6809
6810    /**
6811     * Generate a process error record, suitable for attachment to a ProcessRecord.
6812     *
6813     * @param app The ProcessRecord in which the error occurred.
6814     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
6815     *                      ActivityManager.AppErrorStateInfo
6816     * @param activity The activity associated with the crash, if known.
6817     * @param shortMsg Short message describing the crash.
6818     * @param longMsg Long message describing the crash.
6819     * @param stackTrace Full crash stack trace, may be null.
6820     *
6821     * @return Returns a fully-formed AppErrorStateInfo record.
6822     */
6823    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
6824            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
6825        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
6826
6827        report.condition = condition;
6828        report.processName = app.processName;
6829        report.pid = app.pid;
6830        report.uid = app.info.uid;
6831        report.tag = activity;
6832        report.shortMsg = shortMsg;
6833        report.longMsg = longMsg;
6834        report.stackTrace = stackTrace;
6835
6836        return report;
6837    }
6838
6839    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
6840        synchronized (this) {
6841            app.crashing = false;
6842            app.crashingReport = null;
6843            app.notResponding = false;
6844            app.notRespondingReport = null;
6845            if (app.anrDialog == fromDialog) {
6846                app.anrDialog = null;
6847            }
6848            if (app.waitDialog == fromDialog) {
6849                app.waitDialog = null;
6850            }
6851            if (app.pid > 0 && app.pid != MY_PID) {
6852                handleAppCrashLocked(app);
6853                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
6854                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6855                        app.processName, app.setAdj, "user's request after error");
6856                Process.killProcessQuiet(app.pid);
6857            }
6858        }
6859    }
6860
6861    private boolean handleAppCrashLocked(ProcessRecord app) {
6862        long now = SystemClock.uptimeMillis();
6863
6864        Long crashTime = mProcessCrashTimes.get(app.info.processName,
6865                app.info.uid);
6866        if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
6867            // This process loses!
6868            Slog.w(TAG, "Process " + app.info.processName
6869                    + " has crashed too many times: killing!");
6870            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
6871                    app.info.processName, app.info.uid);
6872            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6873                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6874                if (r.app == app) {
6875                    Slog.w(TAG, "  Force finishing activity "
6876                        + r.intent.getComponent().flattenToShortString());
6877                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
6878                }
6879            }
6880            if (!app.persistent) {
6881                // Don't let services in this process be restarted and potentially
6882                // annoy the user repeatedly.  Unless it is persistent, since those
6883                // processes run critical code.
6884                killServicesLocked(app, false);
6885                // We don't want to start this process again until the user
6886                // explicitly does so...  but for persistent process, we really
6887                // need to keep it running.  If a persistent process is actually
6888                // repeatedly crashing, then badness for everyone.
6889                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
6890                        app.info.processName);
6891                mBadProcesses.put(app.info.processName, app.info.uid, now);
6892                app.bad = true;
6893                mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6894                app.removed = true;
6895                removeProcessLocked(app, false);
6896                mMainStack.resumeTopActivityLocked(null);
6897                return false;
6898            }
6899            mMainStack.resumeTopActivityLocked(null);
6900        } else {
6901            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
6902            if (r.app == app) {
6903                // If the top running activity is from this crashing
6904                // process, then terminate it to avoid getting in a loop.
6905                Slog.w(TAG, "  Force finishing activity "
6906                        + r.intent.getComponent().flattenToShortString());
6907                int index = mMainStack.indexOfTokenLocked(r);
6908                r.stack.finishActivityLocked(r, index,
6909                        Activity.RESULT_CANCELED, null, "crashed");
6910                // Also terminate any activities below it that aren't yet
6911                // stopped, to avoid a situation where one will get
6912                // re-start our crashing activity once it gets resumed again.
6913                index--;
6914                if (index >= 0) {
6915                    r = (ActivityRecord)mMainStack.mHistory.get(index);
6916                    if (r.state == ActivityState.RESUMED
6917                            || r.state == ActivityState.PAUSING
6918                            || r.state == ActivityState.PAUSED) {
6919                        if (!r.isHomeActivity || mHomeProcess != r.app) {
6920                            Slog.w(TAG, "  Force finishing activity "
6921                                    + r.intent.getComponent().flattenToShortString());
6922                            r.stack.finishActivityLocked(r, index,
6923                                    Activity.RESULT_CANCELED, null, "crashed");
6924                        }
6925                    }
6926                }
6927            }
6928        }
6929
6930        // Bump up the crash count of any services currently running in the proc.
6931        if (app.services.size() != 0) {
6932            // Any services running in the application need to be placed
6933            // back in the pending list.
6934            Iterator<ServiceRecord> it = app.services.iterator();
6935            while (it.hasNext()) {
6936                ServiceRecord sr = it.next();
6937                sr.crashCount++;
6938            }
6939        }
6940
6941        // If the crashing process is what we consider to be the "home process" and it has been
6942        // replaced by a third-party app, clear the package preferred activities from packages
6943        // with a home activity running in the process to prevent a repeatedly crashing app
6944        // from blocking the user to manually clear the list.
6945        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6946                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6947            Iterator it = mHomeProcess.activities.iterator();
6948            while (it.hasNext()) {
6949                ActivityRecord r = (ActivityRecord)it.next();
6950                if (r.isHomeActivity) {
6951                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6952                    try {
6953                        ActivityThread.getPackageManager()
6954                                .clearPackagePreferredActivities(r.packageName);
6955                    } catch (RemoteException c) {
6956                        // pm is in same process, this will never happen.
6957                    }
6958                }
6959            }
6960        }
6961
6962        mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6963        return true;
6964    }
6965
6966    void startAppProblemLocked(ProcessRecord app) {
6967        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6968                mContext, app.info.packageName, app.info.flags);
6969        skipCurrentReceiverLocked(app);
6970    }
6971
6972    void skipCurrentReceiverLocked(ProcessRecord app) {
6973        boolean reschedule = false;
6974        BroadcastRecord r = app.curReceiver;
6975        if (r != null) {
6976            // The current broadcast is waiting for this app's receiver
6977            // to be finished.  Looks like that's not going to happen, so
6978            // let the broadcast continue.
6979            logBroadcastReceiverDiscardLocked(r);
6980            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6981                    r.resultExtras, r.resultAbort, true);
6982            reschedule = true;
6983        }
6984        r = mPendingBroadcast;
6985        if (r != null && r.curApp == app) {
6986            if (DEBUG_BROADCAST) Slog.v(TAG,
6987                    "skip & discard pending app " + r);
6988            logBroadcastReceiverDiscardLocked(r);
6989            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6990                    r.resultExtras, r.resultAbort, true);
6991            reschedule = true;
6992        }
6993        if (reschedule) {
6994            scheduleBroadcastsLocked();
6995        }
6996    }
6997
6998    /**
6999     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7000     * The application process will exit immediately after this call returns.
7001     * @param app object of the crashing app, null for the system server
7002     * @param crashInfo describing the exception
7003     */
7004    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7005        ProcessRecord r = findAppProcess(app, "Crash");
7006
7007        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7008                app == null ? "system" : (r == null ? "unknown" : r.processName),
7009                r == null ? -1 : r.info.flags,
7010                crashInfo.exceptionClassName,
7011                crashInfo.exceptionMessage,
7012                crashInfo.throwFileName,
7013                crashInfo.throwLineNumber);
7014
7015        addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
7016
7017        crashApplication(r, crashInfo);
7018    }
7019
7020    public void handleApplicationStrictModeViolation(
7021            IBinder app,
7022            int violationMask,
7023            StrictMode.ViolationInfo info) {
7024        ProcessRecord r = findAppProcess(app, "StrictMode");
7025        if (r == null) {
7026            return;
7027        }
7028
7029        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7030            Integer stackFingerprint = info.hashCode();
7031            boolean logIt = true;
7032            synchronized (mAlreadyLoggedViolatedStacks) {
7033                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7034                    logIt = false;
7035                    // TODO: sub-sample into EventLog for these, with
7036                    // the info.durationMillis?  Then we'd get
7037                    // the relative pain numbers, without logging all
7038                    // the stack traces repeatedly.  We'd want to do
7039                    // likewise in the client code, which also does
7040                    // dup suppression, before the Binder call.
7041                } else {
7042                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7043                        mAlreadyLoggedViolatedStacks.clear();
7044                    }
7045                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7046                }
7047            }
7048            if (logIt) {
7049                logStrictModeViolationToDropBox(r, info);
7050            }
7051        }
7052
7053        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7054            AppErrorResult result = new AppErrorResult();
7055            synchronized (this) {
7056                final long origId = Binder.clearCallingIdentity();
7057
7058                Message msg = Message.obtain();
7059                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7060                HashMap<String, Object> data = new HashMap<String, Object>();
7061                data.put("result", result);
7062                data.put("app", r);
7063                data.put("violationMask", violationMask);
7064                data.put("info", info);
7065                msg.obj = data;
7066                mHandler.sendMessage(msg);
7067
7068                Binder.restoreCallingIdentity(origId);
7069            }
7070            int res = result.get();
7071            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7072        }
7073    }
7074
7075    // Depending on the policy in effect, there could be a bunch of
7076    // these in quick succession so we try to batch these together to
7077    // minimize disk writes, number of dropbox entries, and maximize
7078    // compression, by having more fewer, larger records.
7079    private void logStrictModeViolationToDropBox(
7080            ProcessRecord process,
7081            StrictMode.ViolationInfo info) {
7082        if (info == null) {
7083            return;
7084        }
7085        final boolean isSystemApp = process == null ||
7086                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7087                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7088        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7089        final DropBoxManager dbox = (DropBoxManager)
7090                mContext.getSystemService(Context.DROPBOX_SERVICE);
7091
7092        // Exit early if the dropbox isn't configured to accept this report type.
7093        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7094
7095        boolean bufferWasEmpty;
7096        boolean needsFlush;
7097        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7098        synchronized (sb) {
7099            bufferWasEmpty = sb.length() == 0;
7100            appendDropBoxProcessHeaders(process, sb);
7101            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7102            sb.append("System-App: ").append(isSystemApp).append("\n");
7103            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7104            if (info.violationNumThisLoop != 0) {
7105                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7106            }
7107            if (info.numAnimationsRunning != 0) {
7108                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7109            }
7110            if (info.broadcastIntentAction != null) {
7111                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7112            }
7113            if (info.durationMillis != -1) {
7114                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
7115            }
7116            if (info.numInstances != -1) {
7117                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7118            }
7119            if (info.tags != null) {
7120                for (String tag : info.tags) {
7121                    sb.append("Span-Tag: ").append(tag).append("\n");
7122                }
7123            }
7124            sb.append("\n");
7125            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7126                sb.append(info.crashInfo.stackTrace);
7127            }
7128            sb.append("\n");
7129
7130            // Only buffer up to ~64k.  Various logging bits truncate
7131            // things at 128k.
7132            needsFlush = (sb.length() > 64 * 1024);
7133        }
7134
7135        // Flush immediately if the buffer's grown too large, or this
7136        // is a non-system app.  Non-system apps are isolated with a
7137        // different tag & policy and not batched.
7138        //
7139        // Batching is useful during internal testing with
7140        // StrictMode settings turned up high.  Without batching,
7141        // thousands of separate files could be created on boot.
7142        if (!isSystemApp || needsFlush) {
7143            new Thread("Error dump: " + dropboxTag) {
7144                @Override
7145                public void run() {
7146                    String report;
7147                    synchronized (sb) {
7148                        report = sb.toString();
7149                        sb.delete(0, sb.length());
7150                        sb.trimToSize();
7151                    }
7152                    if (report.length() != 0) {
7153                        dbox.addText(dropboxTag, report);
7154                    }
7155                }
7156            }.start();
7157            return;
7158        }
7159
7160        // System app batching:
7161        if (!bufferWasEmpty) {
7162            // An existing dropbox-writing thread is outstanding, so
7163            // we don't need to start it up.  The existing thread will
7164            // catch the buffer appends we just did.
7165            return;
7166        }
7167
7168        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7169        // (After this point, we shouldn't access AMS internal data structures.)
7170        new Thread("Error dump: " + dropboxTag) {
7171            @Override
7172            public void run() {
7173                // 5 second sleep to let stacks arrive and be batched together
7174                try {
7175                    Thread.sleep(5000);  // 5 seconds
7176                } catch (InterruptedException e) {}
7177
7178                String errorReport;
7179                synchronized (mStrictModeBuffer) {
7180                    errorReport = mStrictModeBuffer.toString();
7181                    if (errorReport.length() == 0) {
7182                        return;
7183                    }
7184                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7185                    mStrictModeBuffer.trimToSize();
7186                }
7187                dbox.addText(dropboxTag, errorReport);
7188            }
7189        }.start();
7190    }
7191
7192    /**
7193     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7194     * @param app object of the crashing app, null for the system server
7195     * @param tag reported by the caller
7196     * @param crashInfo describing the context of the error
7197     * @return true if the process should exit immediately (WTF is fatal)
7198     */
7199    public boolean handleApplicationWtf(IBinder app, String tag,
7200            ApplicationErrorReport.CrashInfo crashInfo) {
7201        ProcessRecord r = findAppProcess(app, "WTF");
7202
7203        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7204                app == null ? "system" : (r == null ? "unknown" : r.processName),
7205                r == null ? -1 : r.info.flags,
7206                tag, crashInfo.exceptionMessage);
7207
7208        addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
7209
7210        if (r != null && r.pid != Process.myPid() &&
7211                Settings.Secure.getInt(mContext.getContentResolver(),
7212                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
7213            crashApplication(r, crashInfo);
7214            return true;
7215        } else {
7216            return false;
7217        }
7218    }
7219
7220    /**
7221     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7222     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7223     */
7224    private ProcessRecord findAppProcess(IBinder app, String reason) {
7225        if (app == null) {
7226            return null;
7227        }
7228
7229        synchronized (this) {
7230            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7231                final int NA = apps.size();
7232                for (int ia=0; ia<NA; ia++) {
7233                    ProcessRecord p = apps.valueAt(ia);
7234                    if (p.thread != null && p.thread.asBinder() == app) {
7235                        return p;
7236                    }
7237                }
7238            }
7239
7240            Slog.w(TAG, "Can't find mystery application for " + reason
7241                    + " from pid=" + Binder.getCallingPid()
7242                    + " uid=" + Binder.getCallingUid() + ": " + app);
7243            return null;
7244        }
7245    }
7246
7247    /**
7248     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7249     * to append various headers to the dropbox log text.
7250     */
7251    private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
7252        // Watchdog thread ends up invoking this function (with
7253        // a null ProcessRecord) to add the stack file to dropbox.
7254        // Do not acquire a lock on this (am) in such cases, as it
7255        // could cause a potential deadlock, if and when watchdog
7256        // is invoked due to unavailability of lock on am and it
7257        // would prevent watchdog from killing system_server.
7258        if (process == null) {
7259            sb.append("Process: system_server\n");
7260            return;
7261        }
7262        // Note: ProcessRecord 'process' is guarded by the service
7263        // instance.  (notably process.pkgList, which could otherwise change
7264        // concurrently during execution of this method)
7265        synchronized (this) {
7266            if (process.pid == MY_PID) {
7267                sb.append("Process: system_server\n");
7268            } else {
7269                sb.append("Process: ").append(process.processName).append("\n");
7270            }
7271            int flags = process.info.flags;
7272            IPackageManager pm = AppGlobals.getPackageManager();
7273            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7274            for (String pkg : process.pkgList) {
7275                sb.append("Package: ").append(pkg);
7276                try {
7277                    PackageInfo pi = pm.getPackageInfo(pkg, 0);
7278                    if (pi != null) {
7279                        sb.append(" v").append(pi.versionCode);
7280                        if (pi.versionName != null) {
7281                            sb.append(" (").append(pi.versionName).append(")");
7282                        }
7283                    }
7284                } catch (RemoteException e) {
7285                    Slog.e(TAG, "Error getting package info: " + pkg, e);
7286                }
7287                sb.append("\n");
7288            }
7289        }
7290    }
7291
7292    private static String processClass(ProcessRecord process) {
7293        if (process == null || process.pid == MY_PID) {
7294            return "system_server";
7295        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7296            return "system_app";
7297        } else {
7298            return "data_app";
7299        }
7300    }
7301
7302    /**
7303     * Write a description of an error (crash, WTF, ANR) to the drop box.
7304     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7305     * @param process which caused the error, null means the system server
7306     * @param activity which triggered the error, null if unknown
7307     * @param parent activity related to the error, null if unknown
7308     * @param subject line related to the error, null if absent
7309     * @param report in long form describing the error, null if absent
7310     * @param logFile to include in the report, null if none
7311     * @param crashInfo giving an application stack trace, null if absent
7312     */
7313    public void addErrorToDropBox(String eventType,
7314            ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7315            final String report, final File logFile,
7316            final ApplicationErrorReport.CrashInfo crashInfo) {
7317        // NOTE -- this must never acquire the ActivityManagerService lock,
7318        // otherwise the watchdog may be prevented from resetting the system.
7319
7320        final String dropboxTag = processClass(process) + "_" + eventType;
7321        final DropBoxManager dbox = (DropBoxManager)
7322                mContext.getSystemService(Context.DROPBOX_SERVICE);
7323
7324        // Exit early if the dropbox isn't configured to accept this report type.
7325        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7326
7327        final StringBuilder sb = new StringBuilder(1024);
7328        appendDropBoxProcessHeaders(process, sb);
7329        if (activity != null) {
7330            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7331        }
7332        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7333            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7334        }
7335        if (parent != null && parent != activity) {
7336            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7337        }
7338        if (subject != null) {
7339            sb.append("Subject: ").append(subject).append("\n");
7340        }
7341        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7342        if (Debug.isDebuggerConnected()) {
7343            sb.append("Debugger: Connected\n");
7344        }
7345        sb.append("\n");
7346
7347        // Do the rest in a worker thread to avoid blocking the caller on I/O
7348        // (After this point, we shouldn't access AMS internal data structures.)
7349        Thread worker = new Thread("Error dump: " + dropboxTag) {
7350            @Override
7351            public void run() {
7352                if (report != null) {
7353                    sb.append(report);
7354                }
7355                if (logFile != null) {
7356                    try {
7357                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7358                    } catch (IOException e) {
7359                        Slog.e(TAG, "Error reading " + logFile, e);
7360                    }
7361                }
7362                if (crashInfo != null && crashInfo.stackTrace != null) {
7363                    sb.append(crashInfo.stackTrace);
7364                }
7365
7366                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7367                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7368                if (lines > 0) {
7369                    sb.append("\n");
7370
7371                    // Merge several logcat streams, and take the last N lines
7372                    InputStreamReader input = null;
7373                    try {
7374                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7375                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7376                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7377
7378                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
7379                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
7380                        input = new InputStreamReader(logcat.getInputStream());
7381
7382                        int num;
7383                        char[] buf = new char[8192];
7384                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7385                    } catch (IOException e) {
7386                        Slog.e(TAG, "Error running logcat", e);
7387                    } finally {
7388                        if (input != null) try { input.close(); } catch (IOException e) {}
7389                    }
7390                }
7391
7392                dbox.addText(dropboxTag, sb.toString());
7393            }
7394        };
7395
7396        if (process == null || process.pid == MY_PID) {
7397            worker.run();  // We may be about to die -- need to run this synchronously
7398        } else {
7399            worker.start();
7400        }
7401    }
7402
7403    /**
7404     * Bring up the "unexpected error" dialog box for a crashing app.
7405     * Deal with edge cases (intercepts from instrumented applications,
7406     * ActivityController, error intent receivers, that sort of thing).
7407     * @param r the application crashing
7408     * @param crashInfo describing the failure
7409     */
7410    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
7411        long timeMillis = System.currentTimeMillis();
7412        String shortMsg = crashInfo.exceptionClassName;
7413        String longMsg = crashInfo.exceptionMessage;
7414        String stackTrace = crashInfo.stackTrace;
7415        if (shortMsg != null && longMsg != null) {
7416            longMsg = shortMsg + ": " + longMsg;
7417        } else if (shortMsg != null) {
7418            longMsg = shortMsg;
7419        }
7420
7421        AppErrorResult result = new AppErrorResult();
7422        synchronized (this) {
7423            if (mController != null) {
7424                try {
7425                    String name = r != null ? r.processName : null;
7426                    int pid = r != null ? r.pid : Binder.getCallingPid();
7427                    if (!mController.appCrashed(name, pid,
7428                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
7429                        Slog.w(TAG, "Force-killing crashed app " + name
7430                                + " at watcher's request");
7431                        Process.killProcess(pid);
7432                        return;
7433                    }
7434                } catch (RemoteException e) {
7435                    mController = null;
7436                }
7437            }
7438
7439            final long origId = Binder.clearCallingIdentity();
7440
7441            // If this process is running instrumentation, finish it.
7442            if (r != null && r.instrumentationClass != null) {
7443                Slog.w(TAG, "Error in app " + r.processName
7444                      + " running instrumentation " + r.instrumentationClass + ":");
7445                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
7446                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
7447                Bundle info = new Bundle();
7448                info.putString("shortMsg", shortMsg);
7449                info.putString("longMsg", longMsg);
7450                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7451                Binder.restoreCallingIdentity(origId);
7452                return;
7453            }
7454
7455            // If we can't identify the process or it's already exceeded its crash quota,
7456            // quit right away without showing a crash dialog.
7457            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
7458                Binder.restoreCallingIdentity(origId);
7459                return;
7460            }
7461
7462            Message msg = Message.obtain();
7463            msg.what = SHOW_ERROR_MSG;
7464            HashMap data = new HashMap();
7465            data.put("result", result);
7466            data.put("app", r);
7467            msg.obj = data;
7468            mHandler.sendMessage(msg);
7469
7470            Binder.restoreCallingIdentity(origId);
7471        }
7472
7473        int res = result.get();
7474
7475        Intent appErrorIntent = null;
7476        synchronized (this) {
7477            if (r != null) {
7478                mProcessCrashTimes.put(r.info.processName, r.info.uid,
7479                        SystemClock.uptimeMillis());
7480            }
7481            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
7482                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
7483            }
7484        }
7485
7486        if (appErrorIntent != null) {
7487            try {
7488                mContext.startActivity(appErrorIntent);
7489            } catch (ActivityNotFoundException e) {
7490                Slog.w(TAG, "bug report receiver dissappeared", e);
7491            }
7492        }
7493    }
7494
7495    Intent createAppErrorIntentLocked(ProcessRecord r,
7496            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7497        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
7498        if (report == null) {
7499            return null;
7500        }
7501        Intent result = new Intent(Intent.ACTION_APP_ERROR);
7502        result.setComponent(r.errorReportReceiver);
7503        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7504        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7505        return result;
7506    }
7507
7508    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7509            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7510        if (r.errorReportReceiver == null) {
7511            return null;
7512        }
7513
7514        if (!r.crashing && !r.notResponding) {
7515            return null;
7516        }
7517
7518        ApplicationErrorReport report = new ApplicationErrorReport();
7519        report.packageName = r.info.packageName;
7520        report.installerPackageName = r.errorReportReceiver.getPackageName();
7521        report.processName = r.processName;
7522        report.time = timeMillis;
7523        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
7524
7525        if (r.crashing) {
7526            report.type = ApplicationErrorReport.TYPE_CRASH;
7527            report.crashInfo = crashInfo;
7528        } else if (r.notResponding) {
7529            report.type = ApplicationErrorReport.TYPE_ANR;
7530            report.anrInfo = new ApplicationErrorReport.AnrInfo();
7531
7532            report.anrInfo.activity = r.notRespondingReport.tag;
7533            report.anrInfo.cause = r.notRespondingReport.shortMsg;
7534            report.anrInfo.info = r.notRespondingReport.longMsg;
7535        }
7536
7537        return report;
7538    }
7539
7540    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7541        // assume our apps are happy - lazy create the list
7542        List<ActivityManager.ProcessErrorStateInfo> errList = null;
7543
7544        synchronized (this) {
7545
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                    // This one's in trouble, so we'll generate a report for it
7551                    // crashes are higher priority (in case there's a crash *and* an anr)
7552                    ActivityManager.ProcessErrorStateInfo report = null;
7553                    if (app.crashing) {
7554                        report = app.crashingReport;
7555                    } else if (app.notResponding) {
7556                        report = app.notRespondingReport;
7557                    }
7558
7559                    if (report != null) {
7560                        if (errList == null) {
7561                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7562                        }
7563                        errList.add(report);
7564                    } else {
7565                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
7566                                " crashing = " + app.crashing +
7567                                " notResponding = " + app.notResponding);
7568                    }
7569                }
7570            }
7571        }
7572
7573        return errList;
7574    }
7575
7576    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7577        // Lazy instantiation of list
7578        List<ActivityManager.RunningAppProcessInfo> runList = null;
7579        synchronized (this) {
7580            // Iterate across all processes
7581            for (int i=mLruProcesses.size()-1; i>=0; i--) {
7582                ProcessRecord app = mLruProcesses.get(i);
7583                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7584                    // Generate process state info for running application
7585                    ActivityManager.RunningAppProcessInfo currApp =
7586                        new ActivityManager.RunningAppProcessInfo(app.processName,
7587                                app.pid, app.getPackageList());
7588                    currApp.uid = app.info.uid;
7589                    if (mHeavyWeightProcess == app) {
7590                        currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
7591                    }
7592                    if (app.persistent) {
7593                        currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7594                    }
7595                    int adj = app.curAdj;
7596                    if (adj >= EMPTY_APP_ADJ) {
7597                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7598                    } else if (adj >= HIDDEN_APP_MIN_ADJ) {
7599                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7600                        currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
7601                    } else if (adj >= HOME_APP_ADJ) {
7602                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7603                        currApp.lru = 0;
7604                    } else if (adj >= SECONDARY_SERVER_ADJ) {
7605                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7606                    } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
7607                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7608                    } else if (adj >= PERCEPTIBLE_APP_ADJ) {
7609                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7610                    } else if (adj >= VISIBLE_APP_ADJ) {
7611                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7612                    } else {
7613                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7614                    }
7615                    currApp.importanceReasonCode = app.adjTypeCode;
7616                    if (app.adjSource instanceof ProcessRecord) {
7617                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
7618                    } else if (app.adjSource instanceof ActivityRecord) {
7619                        ActivityRecord r = (ActivityRecord)app.adjSource;
7620                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7621                    }
7622                    if (app.adjTarget instanceof ComponentName) {
7623                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7624                    }
7625                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
7626                    //        + " lru=" + currApp.lru);
7627                    if (runList == null) {
7628                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7629                    }
7630                    runList.add(currApp);
7631                }
7632            }
7633        }
7634        return runList;
7635    }
7636
7637    public List<ApplicationInfo> getRunningExternalApplications() {
7638        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7639        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7640        if (runningApps != null && runningApps.size() > 0) {
7641            Set<String> extList = new HashSet<String>();
7642            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7643                if (app.pkgList != null) {
7644                    for (String pkg : app.pkgList) {
7645                        extList.add(pkg);
7646                    }
7647                }
7648            }
7649            IPackageManager pm = AppGlobals.getPackageManager();
7650            for (String pkg : extList) {
7651                try {
7652                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7653                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7654                        retList.add(info);
7655                    }
7656                } catch (RemoteException e) {
7657                }
7658            }
7659        }
7660        return retList;
7661    }
7662
7663    @Override
7664    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
7665        if (checkCallingPermission(android.Manifest.permission.DUMP)
7666                != PackageManager.PERMISSION_GRANTED) {
7667            pw.println("Permission Denial: can't dump ActivityManager from from pid="
7668                    + Binder.getCallingPid()
7669                    + ", uid=" + Binder.getCallingUid()
7670                    + " without permission "
7671                    + android.Manifest.permission.DUMP);
7672            return;
7673        }
7674
7675        boolean dumpAll = false;
7676        boolean dumpClient = false;
7677
7678        int opti = 0;
7679        while (opti < args.length) {
7680            String opt = args[opti];
7681            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7682                break;
7683            }
7684            opti++;
7685            if ("-a".equals(opt)) {
7686                dumpAll = true;
7687            } else if ("-c".equals(opt)) {
7688                dumpClient = true;
7689            } else if ("-h".equals(opt)) {
7690                pw.println("Activity manager dump options:");
7691                pw.println("  [-a] [-c] [-h] [cmd] ...");
7692                pw.println("  cmd may be one of:");
7693                pw.println("    a[ctivities]: activity stack state");
7694                pw.println("    b[roadcasts]: broadcast state");
7695                pw.println("    i[ntents]: pending intent state");
7696                pw.println("    p[rocesses]: process state");
7697                pw.println("    o[om]: out of memory management");
7698                pw.println("    prov[iders]: content provider state");
7699                pw.println("    s[ervices]: service state");
7700                pw.println("    service [COMP_SPEC]: service client-side state");
7701                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
7702                pw.println("  COMP_SPEC may also be a component name (com.foo/.myApp),");
7703                pw.println("    a partial substring in a component name, an");
7704                pw.println("    ActivityRecord hex object identifier, or");
7705                pw.println("    \"all\" for all objects, or");
7706                pw.println("    \"top\" for the top activity.");
7707                pw.println("  -a: include all available server state.");
7708                pw.println("  -c: include client state.");
7709                return;
7710            } else {
7711                pw.println("Unknown argument: " + opt + "; use -h for help");
7712            }
7713        }
7714
7715        // Is the caller requesting to dump a particular piece of data?
7716        if (opti < args.length) {
7717            String cmd = args[opti];
7718            opti++;
7719            if ("activities".equals(cmd) || "a".equals(cmd)) {
7720                synchronized (this) {
7721                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
7722                }
7723                return;
7724            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7725                synchronized (this) {
7726                    dumpBroadcastsLocked(fd, pw, args, opti, true);
7727                }
7728                return;
7729            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7730                synchronized (this) {
7731                    dumpPendingIntentsLocked(fd, pw, args, opti, true);
7732                }
7733                return;
7734            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7735                synchronized (this) {
7736                    dumpProcessesLocked(fd, pw, args, opti, true);
7737                }
7738                return;
7739            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7740                synchronized (this) {
7741                    dumpOomLocked(fd, pw, args, opti, true);
7742                }
7743                return;
7744            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7745                synchronized (this) {
7746                    dumpProvidersLocked(fd, pw, args, opti, true);
7747                }
7748                return;
7749            } else if ("service".equals(cmd)) {
7750                String[] newArgs;
7751                String name;
7752                if (opti >= args.length) {
7753                    name = null;
7754                    newArgs = EMPTY_STRING_ARRAY;
7755                } else {
7756                    name = args[opti];
7757                    opti++;
7758                    newArgs = new String[args.length - opti];
7759                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7760                }
7761                if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7762                    pw.println("No services match: " + name);
7763                    pw.println("Use -h for help.");
7764                }
7765                return;
7766            } else if ("services".equals(cmd) || "s".equals(cmd)) {
7767                synchronized (this) {
7768                    dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
7769                }
7770                return;
7771            } else {
7772                // Dumping a single activity?
7773                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7774                    pw.println("Bad activity command, or no activities match: " + cmd);
7775                    pw.println("Use -h for help.");
7776                }
7777                return;
7778            }
7779        }
7780
7781        // No piece of data specified, dump everything.
7782        synchronized (this) {
7783            boolean needSep;
7784            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
7785            if (needSep) {
7786                pw.println(" ");
7787            }
7788            if (dumpAll) {
7789                pw.println("-------------------------------------------------------------------------------");
7790            }
7791            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7792            if (needSep) {
7793                pw.println(" ");
7794            }
7795            if (dumpAll) {
7796                pw.println("-------------------------------------------------------------------------------");
7797            }
7798            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
7799            if (needSep) {
7800                pw.println(" ");
7801            }
7802            if (dumpAll) {
7803                pw.println("-------------------------------------------------------------------------------");
7804            }
7805            needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
7806            if (needSep) {
7807                pw.println(" ");
7808            }
7809            if (dumpAll) {
7810                pw.println("-------------------------------------------------------------------------------");
7811            }
7812            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
7813            if (needSep) {
7814                pw.println(" ");
7815            }
7816            if (dumpAll) {
7817                pw.println("-------------------------------------------------------------------------------");
7818            }
7819            dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7820        }
7821    }
7822
7823    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7824            int opti, boolean dumpAll, boolean dumpClient) {
7825        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7826        pw.println("  Main stack:");
7827        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient);
7828        pw.println(" ");
7829        pw.println("  Running activities (most recent first):");
7830        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false);
7831        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
7832            pw.println(" ");
7833            pw.println("  Activities waiting for another to become visible:");
7834            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
7835                    !dumpAll, false);
7836        }
7837        if (mMainStack.mStoppingActivities.size() > 0) {
7838            pw.println(" ");
7839            pw.println("  Activities waiting to stop:");
7840            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
7841                    !dumpAll, false);
7842        }
7843        if (mMainStack.mGoingToSleepActivities.size() > 0) {
7844            pw.println(" ");
7845            pw.println("  Activities waiting to sleep:");
7846            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
7847                    !dumpAll, false);
7848        }
7849        if (mMainStack.mFinishingActivities.size() > 0) {
7850            pw.println(" ");
7851            pw.println("  Activities waiting to finish:");
7852            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
7853                    !dumpAll, false);
7854        }
7855
7856        pw.println(" ");
7857        if (mMainStack.mPausingActivity != null) {
7858            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
7859        }
7860        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
7861        pw.println("  mFocusedActivity: " + mFocusedActivity);
7862        if (dumpAll) {
7863            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7864            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
7865        }
7866
7867        if (mRecentTasks.size() > 0) {
7868            pw.println();
7869            pw.println("  Recent tasks:");
7870
7871            final int N = mRecentTasks.size();
7872            for (int i=0; i<N; i++) {
7873                TaskRecord tr = mRecentTasks.get(i);
7874                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
7875                        pw.println(tr);
7876                if (dumpAll) {
7877                    mRecentTasks.get(i).dump(pw, "    ");
7878                }
7879            }
7880        }
7881
7882        if (dumpAll) {
7883            pw.println(" ");
7884            pw.println("  mCurTask: " + mCurTask);
7885        }
7886
7887        return true;
7888    }
7889
7890    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7891            int opti, boolean dumpAll) {
7892        boolean needSep = false;
7893        int numPers = 0;
7894
7895        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7896
7897        if (dumpAll) {
7898            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7899                final int NA = procs.size();
7900                for (int ia=0; ia<NA; ia++) {
7901                    if (!needSep) {
7902                        pw.println("  All known processes:");
7903                        needSep = true;
7904                    }
7905                    ProcessRecord r = procs.valueAt(ia);
7906                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
7907                        pw.print(" UID "); pw.print(procs.keyAt(ia));
7908                        pw.print(" "); pw.println(r);
7909                    r.dump(pw, "    ");
7910                    if (r.persistent) {
7911                        numPers++;
7912                    }
7913                }
7914            }
7915        }
7916
7917        if (mLruProcesses.size() > 0) {
7918            if (needSep) pw.println(" ");
7919            needSep = true;
7920            pw.println("  Process LRU list (most recent first):");
7921            dumpProcessOomList(pw, this, mLruProcesses, "    ",
7922                    "Proc", "PERS", false);
7923            needSep = true;
7924        }
7925
7926        if (dumpAll) {
7927            synchronized (mPidsSelfLocked) {
7928                if (mPidsSelfLocked.size() > 0) {
7929                    if (needSep) pw.println(" ");
7930                    needSep = true;
7931                    pw.println("  PID mappings:");
7932                    for (int i=0; i<mPidsSelfLocked.size(); i++) {
7933                        pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7934                            pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7935                    }
7936                }
7937            }
7938        }
7939
7940        if (mForegroundProcesses.size() > 0) {
7941            if (needSep) pw.println(" ");
7942            needSep = true;
7943            pw.println("  Foreground Processes:");
7944            for (int i=0; i<mForegroundProcesses.size(); i++) {
7945                pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
7946                        pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
7947            }
7948        }
7949
7950        if (mPersistentStartingProcesses.size() > 0) {
7951            if (needSep) pw.println(" ");
7952            needSep = true;
7953            pw.println("  Persisent processes that are starting:");
7954            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
7955                    "Starting Norm", "Restarting PERS");
7956        }
7957
7958        if (mStartingProcesses.size() > 0) {
7959            if (needSep) pw.println(" ");
7960            needSep = true;
7961            pw.println("  Processes that are starting:");
7962            dumpProcessList(pw, this, mStartingProcesses, "    ",
7963                    "Starting Norm", "Starting PERS");
7964        }
7965
7966        if (mRemovedProcesses.size() > 0) {
7967            if (needSep) pw.println(" ");
7968            needSep = true;
7969            pw.println("  Processes that are being removed:");
7970            dumpProcessList(pw, this, mRemovedProcesses, "    ",
7971                    "Removed Norm", "Removed PERS");
7972        }
7973
7974        if (mProcessesOnHold.size() > 0) {
7975            if (needSep) pw.println(" ");
7976            needSep = true;
7977            pw.println("  Processes that are on old until the system is ready:");
7978            dumpProcessList(pw, this, mProcessesOnHold, "    ",
7979                    "OnHold Norm", "OnHold PERS");
7980        }
7981
7982        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
7983
7984        if (mProcessCrashTimes.getMap().size() > 0) {
7985            if (needSep) pw.println(" ");
7986            needSep = true;
7987            pw.println("  Time since processes crashed:");
7988            long now = SystemClock.uptimeMillis();
7989            for (Map.Entry<String, SparseArray<Long>> procs
7990                    : mProcessCrashTimes.getMap().entrySet()) {
7991                SparseArray<Long> uids = procs.getValue();
7992                final int N = uids.size();
7993                for (int i=0; i<N; i++) {
7994                    pw.print("    Process "); pw.print(procs.getKey());
7995                            pw.print(" uid "); pw.print(uids.keyAt(i));
7996                            pw.print(": last crashed ");
7997                            pw.print((now-uids.valueAt(i)));
7998                            pw.println(" ms ago");
7999                }
8000            }
8001        }
8002
8003        if (mBadProcesses.getMap().size() > 0) {
8004            if (needSep) pw.println(" ");
8005            needSep = true;
8006            pw.println("  Bad processes:");
8007            for (Map.Entry<String, SparseArray<Long>> procs
8008                    : mBadProcesses.getMap().entrySet()) {
8009                SparseArray<Long> uids = procs.getValue();
8010                final int N = uids.size();
8011                for (int i=0; i<N; i++) {
8012                    pw.print("    Bad process "); pw.print(procs.getKey());
8013                            pw.print(" uid "); pw.print(uids.keyAt(i));
8014                            pw.print(": crashed at time ");
8015                            pw.println(uids.valueAt(i));
8016                }
8017            }
8018        }
8019
8020        pw.println();
8021        pw.println("  mHomeProcess: " + mHomeProcess);
8022        if (mHeavyWeightProcess != null) {
8023            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
8024        }
8025        pw.println("  mConfiguration: " + mConfiguration);
8026        if (dumpAll) {
8027            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
8028            if (mCompatModePackages.getPackages().size() > 0) {
8029                pw.println("  mScreenCompatPackages:");
8030                for (Map.Entry<String, Integer> entry
8031                        : mCompatModePackages.getPackages().entrySet()) {
8032                    String pkg = entry.getKey();
8033                    int mode = entry.getValue();
8034                    pw.print("    "); pw.print(pkg); pw.print(": ");
8035                            pw.print(mode); pw.println();
8036                }
8037            }
8038        }
8039        pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8040        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8041                || mOrigWaitForDebugger) {
8042            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8043                    + " mDebugTransient=" + mDebugTransient
8044                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8045        }
8046        if (mAlwaysFinishActivities || mController != null) {
8047            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
8048                    + " mController=" + mController);
8049        }
8050        if (dumpAll) {
8051            pw.println("  Total persistent processes: " + numPers);
8052            pw.println("  mStartRunning=" + mStartRunning
8053                    + " mProcessesReady=" + mProcessesReady
8054                    + " mSystemReady=" + mSystemReady);
8055            pw.println("  mBooting=" + mBooting
8056                    + " mBooted=" + mBooted
8057                    + " mFactoryTest=" + mFactoryTest);
8058            pw.print("  mLastPowerCheckRealtime=");
8059                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8060                    pw.println("");
8061            pw.print("  mLastPowerCheckUptime=");
8062                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8063                    pw.println("");
8064            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
8065            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
8066            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
8067        }
8068
8069        return true;
8070    }
8071
8072    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8073            int opti, boolean needSep, boolean dumpAll) {
8074        if (mProcessesToGc.size() > 0) {
8075            if (needSep) pw.println(" ");
8076            needSep = true;
8077            pw.println("  Processes that are waiting to GC:");
8078            long now = SystemClock.uptimeMillis();
8079            for (int i=0; i<mProcessesToGc.size(); i++) {
8080                ProcessRecord proc = mProcessesToGc.get(i);
8081                pw.print("    Process "); pw.println(proc);
8082                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
8083                        pw.print(", last gced=");
8084                        pw.print(now-proc.lastRequestedGc);
8085                        pw.print(" ms ago, last lowMem=");
8086                        pw.print(now-proc.lastLowMemory);
8087                        pw.println(" ms ago");
8088
8089            }
8090        }
8091        return needSep;
8092    }
8093
8094    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8095            int opti, boolean dumpAll) {
8096        boolean needSep = false;
8097
8098        if (mLruProcesses.size() > 0) {
8099            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
8100
8101            Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
8102                @Override
8103                public int compare(ProcessRecord object1, ProcessRecord object2) {
8104                    if (object1.setAdj != object2.setAdj) {
8105                        return object1.setAdj > object2.setAdj ? -1 : 1;
8106                    }
8107                    if (object1.setSchedGroup != object2.setSchedGroup) {
8108                        return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
8109                    }
8110                    if (object1.keeping != object2.keeping) {
8111                        return object1.keeping ? -1 : 1;
8112                    }
8113                    if (object1.pid != object2.pid) {
8114                        return object1.pid > object2.pid ? -1 : 1;
8115                    }
8116                    return 0;
8117                }
8118            };
8119
8120            Collections.sort(procs, comparator);
8121
8122            if (needSep) pw.println(" ");
8123            needSep = true;
8124            pw.println("  Process OOM control:");
8125            dumpProcessOomList(pw, this, procs, "    ",
8126                    "Proc", "PERS", true);
8127            needSep = true;
8128        }
8129
8130        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8131
8132        pw.println();
8133        pw.println("  mHomeProcess: " + mHomeProcess);
8134        if (mHeavyWeightProcess != null) {
8135            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
8136        }
8137
8138        return true;
8139    }
8140
8141    /**
8142     * There are three ways to call this:
8143     *  - no service specified: dump all the services
8144     *  - a flattened component name that matched an existing service was specified as the
8145     *    first arg: dump that one service
8146     *  - the first arg isn't the flattened component name of an existing service:
8147     *    dump all services whose component contains the first arg as a substring
8148     */
8149    protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8150            int opti, boolean dumpAll) {
8151        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
8152
8153        if ("all".equals(name)) {
8154            synchronized (this) {
8155                for (ServiceRecord r1 : mServices.values()) {
8156                    services.add(r1);
8157                }
8158            }
8159        } else {
8160            ComponentName componentName = name != null
8161                    ? ComponentName.unflattenFromString(name) : null;
8162            int objectId = 0;
8163            if (componentName == null) {
8164                // Not a '/' separated full component name; maybe an object ID?
8165                try {
8166                    objectId = Integer.parseInt(name, 16);
8167                    name = null;
8168                    componentName = null;
8169                } catch (RuntimeException e) {
8170                }
8171            }
8172
8173            synchronized (this) {
8174                for (ServiceRecord r1 : mServices.values()) {
8175                    if (componentName != null) {
8176                        if (r1.name.equals(componentName)) {
8177                            services.add(r1);
8178                        }
8179                    } else if (name != null) {
8180                        if (r1.name.flattenToString().contains(name)) {
8181                            services.add(r1);
8182                        }
8183                    } else if (System.identityHashCode(r1) == objectId) {
8184                        services.add(r1);
8185                    }
8186                }
8187            }
8188        }
8189
8190        if (services.size() <= 0) {
8191            return false;
8192        }
8193
8194        boolean needSep = false;
8195        for (int i=0; i<services.size(); i++) {
8196            if (needSep) {
8197                pw.println();
8198            }
8199            needSep = true;
8200            dumpService("", fd, pw, services.get(i), args, dumpAll);
8201        }
8202        return true;
8203    }
8204
8205    /**
8206     * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8207     * there is a thread associated with the service.
8208     */
8209    private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8210            final ServiceRecord r, String[] args, boolean dumpAll) {
8211        String innerPrefix = prefix + "  ";
8212        synchronized (this) {
8213            pw.print(prefix); pw.print("SERVICE ");
8214                    pw.print(r.shortName); pw.print(" ");
8215                    pw.print(Integer.toHexString(System.identityHashCode(r)));
8216                    pw.print(" pid=");
8217                    if (r.app != null) pw.println(r.app.pid);
8218                    else pw.println("(not running)");
8219            if (dumpAll) {
8220                r.dump(pw, innerPrefix);
8221            }
8222        }
8223        if (r.app != null && r.app.thread != null) {
8224            pw.print(prefix); pw.println("  Client:");
8225            pw.flush();
8226            try {
8227                TransferPipe tp = new TransferPipe();
8228                try {
8229                    r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8230                    tp.setBufferPrefix(prefix + "    ");
8231                    tp.go(fd);
8232                } finally {
8233                    tp.kill();
8234                }
8235            } catch (IOException e) {
8236                pw.println(prefix + "    Failure while dumping the service: " + e);
8237            } catch (RemoteException e) {
8238                pw.println(prefix + "    Got a RemoteException while dumping the service");
8239            }
8240        }
8241    }
8242
8243    /**
8244     * There are three things that cmd can be:
8245     *  - a flattened component name that matched an existing activity
8246     *  - the cmd arg isn't the flattened component name of an existing activity:
8247     *    dump all activity whose component contains the cmd as a substring
8248     *  - A hex number of the ActivityRecord object instance.
8249     */
8250    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8251            int opti, boolean dumpAll) {
8252        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
8253
8254        if ("all".equals(name)) {
8255            synchronized (this) {
8256                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8257                    activities.add(r1);
8258                }
8259            }
8260        } else if ("top".equals(name)) {
8261            synchronized (this) {
8262                final int N = mMainStack.mHistory.size();
8263                if (N > 0) {
8264                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8265                }
8266            }
8267        } else {
8268            ComponentName componentName = ComponentName.unflattenFromString(name);
8269            int objectId = 0;
8270            if (componentName == null) {
8271                // Not a '/' separated full component name; maybe an object ID?
8272                try {
8273                    objectId = Integer.parseInt(name, 16);
8274                    name = null;
8275                    componentName = null;
8276                } catch (RuntimeException e) {
8277                }
8278            }
8279
8280            synchronized (this) {
8281                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8282                    if (componentName != null) {
8283                        if (r1.intent.getComponent().equals(componentName)) {
8284                            activities.add(r1);
8285                        }
8286                    } else if (name != null) {
8287                        if (r1.intent.getComponent().flattenToString().contains(name)) {
8288                            activities.add(r1);
8289                        }
8290                    } else if (System.identityHashCode(r1) == objectId) {
8291                        activities.add(r1);
8292                    }
8293                }
8294            }
8295        }
8296
8297        if (activities.size() <= 0) {
8298            return false;
8299        }
8300
8301        String[] newArgs = new String[args.length - opti];
8302        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8303
8304        TaskRecord lastTask = null;
8305        boolean needSep = false;
8306        for (int i=activities.size()-1; i>=0; i--) {
8307            ActivityRecord r = (ActivityRecord)activities.get(i);
8308            if (needSep) {
8309                pw.println();
8310            }
8311            needSep = true;
8312            synchronized (this) {
8313                if (lastTask != r.task) {
8314                    lastTask = r.task;
8315                    pw.print("TASK "); pw.print(lastTask.affinity);
8316                            pw.print(" id="); pw.println(lastTask.taskId);
8317                    if (dumpAll) {
8318                        lastTask.dump(pw, "  ");
8319                    }
8320                }
8321            }
8322            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
8323        }
8324        return true;
8325    }
8326
8327    /**
8328     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8329     * there is a thread associated with the activity.
8330     */
8331    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
8332            final ActivityRecord r, String[] args, boolean dumpAll) {
8333        String innerPrefix = prefix + "  ";
8334        synchronized (this) {
8335            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8336                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8337                    pw.print(" pid=");
8338                    if (r.app != null) pw.println(r.app.pid);
8339                    else pw.println("(not running)");
8340            if (dumpAll) {
8341                r.dump(pw, innerPrefix);
8342            }
8343        }
8344        if (r.app != null && r.app.thread != null) {
8345            // flush anything that is already in the PrintWriter since the thread is going
8346            // to write to the file descriptor directly
8347            pw.flush();
8348            try {
8349                TransferPipe tp = new TransferPipe();
8350                try {
8351                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8352                            innerPrefix, args);
8353                    tp.go(fd);
8354                } finally {
8355                    tp.kill();
8356                }
8357            } catch (IOException e) {
8358                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8359            } catch (RemoteException e) {
8360                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8361            }
8362        }
8363    }
8364
8365    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8366            int opti, boolean dumpAll) {
8367        boolean needSep = false;
8368
8369        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
8370        if (dumpAll) {
8371            if (mRegisteredReceivers.size() > 0) {
8372                pw.println("  Registered Receivers:");
8373                Iterator it = mRegisteredReceivers.values().iterator();
8374                while (it.hasNext()) {
8375                    ReceiverList r = (ReceiverList)it.next();
8376                    pw.print("  * "); pw.println(r);
8377                    r.dump(pw, "    ");
8378                }
8379            }
8380
8381            pw.println();
8382            pw.println("  Receiver Resolver Table:");
8383            mReceiverResolver.dump(pw, null, "    ", null, false);
8384            needSep = true;
8385        }
8386
8387        if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8388                || mPendingBroadcast != null) {
8389            if (mParallelBroadcasts.size() > 0) {
8390                pw.println();
8391                pw.println("  Active broadcasts:");
8392            }
8393            for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8394                pw.println("  Broadcast #" + i + ":");
8395                mParallelBroadcasts.get(i).dump(pw, "    ");
8396            }
8397            if (mOrderedBroadcasts.size() > 0) {
8398                pw.println();
8399                pw.println("  Active ordered broadcasts:");
8400            }
8401            for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8402                pw.println("  Serialized Broadcast #" + i + ":");
8403                mOrderedBroadcasts.get(i).dump(pw, "    ");
8404            }
8405            pw.println();
8406            pw.println("  Pending broadcast:");
8407            if (mPendingBroadcast != null) {
8408                mPendingBroadcast.dump(pw, "    ");
8409            } else {
8410                pw.println("    (null)");
8411            }
8412            needSep = true;
8413        }
8414
8415        if (needSep) {
8416            pw.println();
8417        }
8418        pw.println("  Historical broadcasts:");
8419        for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8420            BroadcastRecord r = mBroadcastHistory[i];
8421            if (r == null) {
8422                break;
8423            }
8424            if (dumpAll) {
8425                pw.print("  Historical Broadcast #"); pw.print(i); pw.println(":");
8426                r.dump(pw, "    ");
8427            } else {
8428                if (i >= 50) {
8429                    pw.println("  ...");
8430                    break;
8431                }
8432                pw.print("  #"); pw.print(i); pw.print(": "); pw.println(r);
8433            }
8434        }
8435        needSep = true;
8436
8437        if (mStickyBroadcasts != null) {
8438            pw.println();
8439            pw.println("  Sticky broadcasts:");
8440            StringBuilder sb = new StringBuilder(128);
8441            for (Map.Entry<String, ArrayList<Intent>> ent
8442                    : mStickyBroadcasts.entrySet()) {
8443                pw.print("  * Sticky action "); pw.print(ent.getKey());
8444                if (dumpAll) {
8445                    pw.println(":");
8446                    ArrayList<Intent> intents = ent.getValue();
8447                    final int N = intents.size();
8448                    for (int i=0; i<N; i++) {
8449                        sb.setLength(0);
8450                        sb.append("    Intent: ");
8451                        intents.get(i).toShortString(sb, true, false);
8452                        pw.println(sb.toString());
8453                        Bundle bundle = intents.get(i).getExtras();
8454                        if (bundle != null) {
8455                            pw.print("      ");
8456                            pw.println(bundle.toString());
8457                        }
8458                    }
8459                } else {
8460                    pw.println("");
8461                }
8462            }
8463            needSep = true;
8464        }
8465
8466        if (dumpAll) {
8467            pw.println();
8468            pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
8469            pw.println("  mHandler:");
8470            mHandler.dump(new PrintWriterPrinter(pw), "    ");
8471            needSep = true;
8472        }
8473
8474        return needSep;
8475    }
8476
8477    boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8478            int opti, boolean dumpAll, boolean dumpClient) {
8479        boolean needSep = false;
8480
8481        pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8482        if (mServices.size() > 0) {
8483            pw.println("  Active services:");
8484            long nowReal = SystemClock.elapsedRealtime();
8485            Iterator<ServiceRecord> it = mServices.values().iterator();
8486            needSep = false;
8487            while (it.hasNext()) {
8488                ServiceRecord r = it.next();
8489                if (needSep) {
8490                    pw.println();
8491                }
8492                pw.print("  * "); pw.println(r);
8493                if (dumpAll) {
8494                    r.dump(pw, "    ");
8495                    needSep = true;
8496                } else {
8497                    pw.print("    app="); pw.println(r.app);
8498                    pw.print("    created=");
8499                        TimeUtils.formatDuration(r.createTime, nowReal, pw);
8500                        pw.print(" started="); pw.print(r.startRequested);
8501                        pw.print(" connections="); pw.println(r.connections.size());
8502                }
8503                if (dumpClient && r.app != null && r.app.thread != null) {
8504                    pw.println("    Client:");
8505                    pw.flush();
8506                    try {
8507                        TransferPipe tp = new TransferPipe();
8508                        try {
8509                            r.app.thread.dumpService(
8510                                    tp.getWriteFd().getFileDescriptor(), r, args);
8511                            tp.setBufferPrefix("      ");
8512                            // Short timeout, since blocking here can
8513                            // deadlock with the application.
8514                            tp.go(fd, 2000);
8515                        } finally {
8516                            tp.kill();
8517                        }
8518                    } catch (IOException e) {
8519                        pw.println("      Failure while dumping the service: " + e);
8520                    } catch (RemoteException e) {
8521                        pw.println("      Got a RemoteException while dumping the service");
8522                    }
8523                    needSep = true;
8524                }
8525            }
8526            needSep = true;
8527        }
8528
8529        if (mPendingServices.size() > 0) {
8530            if (needSep) pw.println(" ");
8531            pw.println("  Pending services:");
8532            for (int i=0; i<mPendingServices.size(); i++) {
8533                ServiceRecord r = mPendingServices.get(i);
8534                pw.print("  * Pending "); pw.println(r);
8535                r.dump(pw, "    ");
8536            }
8537            needSep = true;
8538        }
8539
8540        if (mRestartingServices.size() > 0) {
8541            if (needSep) pw.println(" ");
8542            pw.println("  Restarting services:");
8543            for (int i=0; i<mRestartingServices.size(); i++) {
8544                ServiceRecord r = mRestartingServices.get(i);
8545                pw.print("  * Restarting "); pw.println(r);
8546                r.dump(pw, "    ");
8547            }
8548            needSep = true;
8549        }
8550
8551        if (mStoppingServices.size() > 0) {
8552            if (needSep) pw.println(" ");
8553            pw.println("  Stopping services:");
8554            for (int i=0; i<mStoppingServices.size(); i++) {
8555                ServiceRecord r = mStoppingServices.get(i);
8556                pw.print("  * Stopping "); pw.println(r);
8557                r.dump(pw, "    ");
8558            }
8559            needSep = true;
8560        }
8561
8562        if (dumpAll) {
8563            if (mServiceConnections.size() > 0) {
8564                if (needSep) pw.println(" ");
8565                pw.println("  Connection bindings to services:");
8566                Iterator<ArrayList<ConnectionRecord>> it
8567                        = mServiceConnections.values().iterator();
8568                while (it.hasNext()) {
8569                    ArrayList<ConnectionRecord> r = it.next();
8570                    for (int i=0; i<r.size(); i++) {
8571                        pw.print("  * "); pw.println(r.get(i));
8572                        r.get(i).dump(pw, "    ");
8573                    }
8574                }
8575                needSep = true;
8576            }
8577        }
8578
8579        return needSep;
8580    }
8581
8582    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8583            int opti, boolean dumpAll) {
8584        boolean needSep = false;
8585
8586        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8587        if (mProvidersByClass.size() > 0) {
8588            if (needSep) pw.println(" ");
8589            pw.println("  Published content providers (by class):");
8590            Iterator<Map.Entry<String, ContentProviderRecord>> it
8591                    = mProvidersByClass.entrySet().iterator();
8592            while (it.hasNext()) {
8593                Map.Entry<String, ContentProviderRecord> e = it.next();
8594                ContentProviderRecord r = e.getValue();
8595                if (dumpAll) {
8596                    pw.print("  * "); pw.println(r);
8597                    r.dump(pw, "    ");
8598                } else {
8599                    pw.print("  * "); pw.print(r.name.toShortString());
8600                    if (r.app != null) {
8601                        pw.println(":");
8602                        pw.print("      "); pw.println(r.app);
8603                    } else {
8604                        pw.println();
8605                    }
8606                }
8607            }
8608            needSep = true;
8609        }
8610
8611        if (dumpAll) {
8612            if (mProvidersByName.size() > 0) {
8613                pw.println(" ");
8614                pw.println("  Authority to provider mappings:");
8615                Iterator<Map.Entry<String, ContentProviderRecord>> it
8616                        = mProvidersByName.entrySet().iterator();
8617                while (it.hasNext()) {
8618                    Map.Entry<String, ContentProviderRecord> e = it.next();
8619                    ContentProviderRecord r = e.getValue();
8620                    pw.print("  "); pw.print(e.getKey()); pw.print(": ");
8621                            pw.println(r);
8622                }
8623                needSep = true;
8624            }
8625        }
8626
8627        if (mLaunchingProviders.size() > 0) {
8628            if (needSep) pw.println(" ");
8629            pw.println("  Launching content providers:");
8630            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8631                pw.print("  Launching #"); pw.print(i); pw.print(": ");
8632                        pw.println(mLaunchingProviders.get(i));
8633            }
8634            needSep = true;
8635        }
8636
8637        if (mGrantedUriPermissions.size() > 0) {
8638            pw.println();
8639            pw.println("Granted Uri Permissions:");
8640            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8641                int uid = mGrantedUriPermissions.keyAt(i);
8642                HashMap<Uri, UriPermission> perms
8643                        = mGrantedUriPermissions.valueAt(i);
8644                pw.print("  * UID "); pw.print(uid);
8645                        pw.println(" holds:");
8646                for (UriPermission perm : perms.values()) {
8647                    pw.print("    "); pw.println(perm);
8648                    if (dumpAll) {
8649                        perm.dump(pw, "      ");
8650                    }
8651                }
8652            }
8653            needSep = true;
8654        }
8655
8656        return needSep;
8657    }
8658
8659    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8660            int opti, boolean dumpAll) {
8661        boolean needSep = false;
8662
8663        if (this.mIntentSenderRecords.size() > 0) {
8664            pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8665            Iterator<WeakReference<PendingIntentRecord>> it
8666                    = mIntentSenderRecords.values().iterator();
8667            while (it.hasNext()) {
8668                WeakReference<PendingIntentRecord> ref = it.next();
8669                PendingIntentRecord rec = ref != null ? ref.get(): null;
8670                needSep = true;
8671                if (rec != null) {
8672                    pw.print("  * "); pw.println(rec);
8673                    if (dumpAll) {
8674                        rec.dump(pw, "    ");
8675                    }
8676                } else {
8677                    pw.print("  * "); pw.println(ref);
8678                }
8679            }
8680        }
8681
8682        return needSep;
8683    }
8684
8685    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8686            String prefix, String label, boolean complete, boolean brief, boolean client) {
8687        TaskRecord lastTask = null;
8688        boolean needNL = false;
8689        final String innerPrefix = prefix + "      ";
8690        final String[] args = new String[0];
8691        for (int i=list.size()-1; i>=0; i--) {
8692            final ActivityRecord r = (ActivityRecord)list.get(i);
8693            final boolean full = !brief && (complete || !r.isInHistory());
8694            if (needNL) {
8695                pw.println(" ");
8696                needNL = false;
8697            }
8698            if (lastTask != r.task) {
8699                lastTask = r.task;
8700                pw.print(prefix);
8701                pw.print(full ? "* " : "  ");
8702                pw.println(lastTask);
8703                if (full) {
8704                    lastTask.dump(pw, prefix + "  ");
8705                } else if (complete) {
8706                    // Complete + brief == give a summary.  Isn't that obvious?!?
8707                    if (lastTask.intent != null) {
8708                        pw.print(prefix); pw.print("  "); pw.println(lastTask.intent);
8709                    }
8710                }
8711            }
8712            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
8713            pw.print(" #"); pw.print(i); pw.print(": ");
8714            pw.println(r);
8715            if (full) {
8716                r.dump(pw, innerPrefix);
8717            } else if (complete) {
8718                // Complete + brief == give a summary.  Isn't that obvious?!?
8719                pw.print(innerPrefix); pw.println(r.intent);
8720                if (r.app != null) {
8721                    pw.print(innerPrefix); pw.println(r.app);
8722                }
8723            }
8724            if (client && r.app != null && r.app.thread != null) {
8725                // flush anything that is already in the PrintWriter since the thread is going
8726                // to write to the file descriptor directly
8727                pw.flush();
8728                try {
8729                    TransferPipe tp = new TransferPipe();
8730                    try {
8731                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8732                                innerPrefix, args);
8733                        // Short timeout, since blocking here can
8734                        // deadlock with the application.
8735                        tp.go(fd, 2000);
8736                    } finally {
8737                        tp.kill();
8738                    }
8739                } catch (IOException e) {
8740                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8741                } catch (RemoteException e) {
8742                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8743                }
8744                needNL = true;
8745            }
8746        }
8747    }
8748
8749    private static String buildOomTag(String prefix, String space, int val, int base) {
8750        if (val == base) {
8751            if (space == null) return prefix;
8752            return prefix + "  ";
8753        }
8754        return prefix + "+" + Integer.toString(val-base);
8755    }
8756
8757    private static final int dumpProcessList(PrintWriter pw,
8758            ActivityManagerService service, List list,
8759            String prefix, String normalLabel, String persistentLabel) {
8760        int numPers = 0;
8761        final int N = list.size()-1;
8762        for (int i=N; i>=0; i--) {
8763            ProcessRecord r = (ProcessRecord)list.get(i);
8764            pw.println(String.format("%s%s #%2d: %s",
8765                    prefix, (r.persistent ? persistentLabel : normalLabel),
8766                    i, r.toString()));
8767            if (r.persistent) {
8768                numPers++;
8769            }
8770        }
8771        return numPers;
8772    }
8773
8774    private static final void dumpProcessOomList(PrintWriter pw,
8775            ActivityManagerService service, List<ProcessRecord> list,
8776            String prefix, String normalLabel, String persistentLabel,
8777            boolean inclDetails) {
8778
8779        final long curRealtime = SystemClock.elapsedRealtime();
8780        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8781        final long curUptime = SystemClock.uptimeMillis();
8782        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8783
8784        final int N = list.size()-1;
8785        for (int i=N; i>=0; i--) {
8786            ProcessRecord r = list.get(i);
8787            String oomAdj;
8788            if (r.setAdj >= EMPTY_APP_ADJ) {
8789                oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
8790            } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
8791                oomAdj = buildOomTag("bak", "  ", r.setAdj, HIDDEN_APP_MIN_ADJ);
8792            } else if (r.setAdj >= HOME_APP_ADJ) {
8793                oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
8794            } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
8795                oomAdj = buildOomTag("svc", "  ", r.setAdj, SECONDARY_SERVER_ADJ);
8796            } else if (r.setAdj >= BACKUP_APP_ADJ) {
8797                oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
8798            } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
8799                oomAdj = buildOomTag("hvy  ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
8800            } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
8801                oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
8802            } else if (r.setAdj >= VISIBLE_APP_ADJ) {
8803                oomAdj = buildOomTag("vis  ", null, r.setAdj, VISIBLE_APP_ADJ);
8804            } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
8805                oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
8806            } else if (r.setAdj >= CORE_SERVER_ADJ) {
8807                oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
8808            } else if (r.setAdj >= SYSTEM_ADJ) {
8809                oomAdj = buildOomTag("sys  ", null, r.setAdj, SYSTEM_ADJ);
8810            } else {
8811                oomAdj = Integer.toString(r.setAdj);
8812            }
8813            String schedGroup;
8814            switch (r.setSchedGroup) {
8815                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8816                    schedGroup = "B";
8817                    break;
8818                case Process.THREAD_GROUP_DEFAULT:
8819                    schedGroup = "F";
8820                    break;
8821                default:
8822                    schedGroup = Integer.toString(r.setSchedGroup);
8823                    break;
8824            }
8825            String foreground;
8826            if (r.foregroundActivities) {
8827                foreground = "A";
8828            } else if (r.foregroundServices) {
8829                foreground = "S";
8830            } else {
8831                foreground = " ";
8832            }
8833            pw.println(String.format("%s%s #%2d: adj=%s/%s%s %s (%s)",
8834                    prefix, (r.persistent ? persistentLabel : normalLabel),
8835                    N-i, oomAdj, schedGroup, foreground, r.toShortString(), r.adjType));
8836            if (r.adjSource != null || r.adjTarget != null) {
8837                pw.print(prefix);
8838                pw.print("    ");
8839                if (r.adjTarget instanceof ComponentName) {
8840                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8841                } else if (r.adjTarget != null) {
8842                    pw.print(r.adjTarget.toString());
8843                } else {
8844                    pw.print("{null}");
8845                }
8846                pw.print("<=");
8847                if (r.adjSource instanceof ProcessRecord) {
8848                    pw.print("Proc{");
8849                    pw.print(((ProcessRecord)r.adjSource).toShortString());
8850                    pw.println("}");
8851                } else if (r.adjSource != null) {
8852                    pw.println(r.adjSource.toString());
8853                } else {
8854                    pw.println("{null}");
8855                }
8856            }
8857            if (inclDetails) {
8858                pw.print(prefix);
8859                pw.print("    ");
8860                pw.print("oom: max="); pw.print(r.maxAdj);
8861                pw.print(" hidden="); pw.print(r.hiddenAdj);
8862                pw.print(" curRaw="); pw.print(r.curRawAdj);
8863                pw.print(" setRaw="); pw.print(r.setRawAdj);
8864                pw.print(" cur="); pw.print(r.curAdj);
8865                pw.print(" set="); pw.println(r.setAdj);
8866                pw.print(prefix);
8867                pw.print("    ");
8868                pw.print("keeping="); pw.print(r.keeping);
8869                pw.print(" hidden="); pw.print(r.hidden);
8870                pw.print(" empty="); pw.println(r.empty);
8871
8872                if (!r.keeping) {
8873                    if (r.lastWakeTime != 0) {
8874                        long wtime;
8875                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8876                        synchronized (stats) {
8877                            wtime = stats.getProcessWakeTime(r.info.uid,
8878                                    r.pid, curRealtime);
8879                        }
8880                        long timeUsed = wtime - r.lastWakeTime;
8881                        pw.print(prefix);
8882                        pw.print("    ");
8883                        pw.print("keep awake over ");
8884                        TimeUtils.formatDuration(realtimeSince, pw);
8885                        pw.print(" used ");
8886                        TimeUtils.formatDuration(timeUsed, pw);
8887                        pw.print(" (");
8888                        pw.print((timeUsed*100)/realtimeSince);
8889                        pw.println("%)");
8890                    }
8891                    if (r.lastCpuTime != 0) {
8892                        long timeUsed = r.curCpuTime - r.lastCpuTime;
8893                        pw.print(prefix);
8894                        pw.print("    ");
8895                        pw.print("run cpu over ");
8896                        TimeUtils.formatDuration(uptimeSince, pw);
8897                        pw.print(" used ");
8898                        TimeUtils.formatDuration(timeUsed, pw);
8899                        pw.print(" (");
8900                        pw.print((timeUsed*100)/uptimeSince);
8901                        pw.println("%)");
8902                    }
8903                }
8904            }
8905        }
8906    }
8907
8908    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, String[] args) {
8909        ArrayList<ProcessRecord> procs;
8910        synchronized (this) {
8911            if (args != null && args.length > 0
8912                    && args[0].charAt(0) != '-') {
8913                procs = new ArrayList<ProcessRecord>();
8914                int pid = -1;
8915                try {
8916                    pid = Integer.parseInt(args[0]);
8917                } catch (NumberFormatException e) {
8918
8919                }
8920                for (int i=mLruProcesses.size()-1; i>=0; i--) {
8921                    ProcessRecord proc = mLruProcesses.get(i);
8922                    if (proc.pid == pid) {
8923                        procs.add(proc);
8924                    } else if (proc.processName.equals(args[0])) {
8925                        procs.add(proc);
8926                    }
8927                }
8928                if (procs.size() <= 0) {
8929                    pw.println("No process found for: " + args[0]);
8930                    return null;
8931                }
8932            } else {
8933                procs = new ArrayList<ProcessRecord>(mLruProcesses);
8934            }
8935        }
8936        return procs;
8937    }
8938
8939    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
8940            PrintWriter pw, String[] args) {
8941        ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
8942        if (procs == null) {
8943            return;
8944        }
8945
8946        long uptime = SystemClock.uptimeMillis();
8947        long realtime = SystemClock.elapsedRealtime();
8948        pw.println("Applications Graphics Acceleration Info:");
8949        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8950
8951        String callArgs[] = {"graphics"};
8952        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8953            ProcessRecord r = procs.get(i);
8954            if (r.thread != null) {
8955                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
8956                pw.flush();
8957                try {
8958                    TransferPipe.goDump(r.thread.asBinder(), fd, callArgs);
8959                } catch (IOException e) {
8960                    pw.println("Failure: " + e);
8961                    pw.flush();
8962                } catch (RemoteException e) {
8963                    pw.println("Got RemoteException!");
8964                    pw.flush();
8965                }
8966            }
8967        }
8968    }
8969
8970    final void dumpApplicationMemoryUsage(FileDescriptor fd,
8971            PrintWriter pw, String prefix, String[] args) {
8972        ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
8973        if (procs == null) {
8974            return;
8975        }
8976
8977        final boolean isCheckinRequest = scanArgs(args, "--checkin");
8978        long uptime = SystemClock.uptimeMillis();
8979        long realtime = SystemClock.elapsedRealtime();
8980
8981        if (isCheckinRequest) {
8982            // short checkin version
8983            pw.println(uptime + "," + realtime);
8984            pw.flush();
8985        } else {
8986            pw.println("Applications Memory Usage (kB):");
8987            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8988        }
8989        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8990            ProcessRecord r = procs.get(i);
8991            if (r.thread != null) {
8992                if (!isCheckinRequest) {
8993                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
8994                    pw.flush();
8995                }
8996                try {
8997                    TransferPipe.goDump(r.thread.asBinder(), fd, args);
8998                } catch (IOException e) {
8999                    pw.println("Failure: " + e);
9000                    pw.flush();
9001                } catch (RemoteException e) {
9002                    if (!isCheckinRequest) {
9003                        pw.println("Got RemoteException!");
9004                        pw.flush();
9005                    }
9006                }
9007            }
9008        }
9009    }
9010
9011    /**
9012     * Searches array of arguments for the specified string
9013     * @param args array of argument strings
9014     * @param value value to search for
9015     * @return true if the value is contained in the array
9016     */
9017    private static boolean scanArgs(String[] args, String value) {
9018        if (args != null) {
9019            for (String arg : args) {
9020                if (value.equals(arg)) {
9021                    return true;
9022                }
9023            }
9024        }
9025        return false;
9026    }
9027
9028    private final void killServicesLocked(ProcessRecord app,
9029            boolean allowRestart) {
9030        // Report disconnected services.
9031        if (false) {
9032            // XXX we are letting the client link to the service for
9033            // death notifications.
9034            if (app.services.size() > 0) {
9035                Iterator<ServiceRecord> it = app.services.iterator();
9036                while (it.hasNext()) {
9037                    ServiceRecord r = it.next();
9038                    if (r.connections.size() > 0) {
9039                        Iterator<ArrayList<ConnectionRecord>> jt
9040                                = r.connections.values().iterator();
9041                        while (jt.hasNext()) {
9042                            ArrayList<ConnectionRecord> cl = jt.next();
9043                            for (int i=0; i<cl.size(); i++) {
9044                                ConnectionRecord c = cl.get(i);
9045                                if (c.binding.client != app) {
9046                                    try {
9047                                        //c.conn.connected(r.className, null);
9048                                    } catch (Exception e) {
9049                                        // todo: this should be asynchronous!
9050                                        Slog.w(TAG, "Exception thrown disconnected servce "
9051                                              + r.shortName
9052                                              + " from app " + app.processName, e);
9053                                    }
9054                                }
9055                            }
9056                        }
9057                    }
9058                }
9059            }
9060        }
9061
9062        // Clean up any connections this application has to other services.
9063        if (app.connections.size() > 0) {
9064            Iterator<ConnectionRecord> it = app.connections.iterator();
9065            while (it.hasNext()) {
9066                ConnectionRecord r = it.next();
9067                removeConnectionLocked(r, app, null);
9068            }
9069        }
9070        app.connections.clear();
9071
9072        if (app.services.size() != 0) {
9073            // Any services running in the application need to be placed
9074            // back in the pending list.
9075            Iterator<ServiceRecord> it = app.services.iterator();
9076            while (it.hasNext()) {
9077                ServiceRecord sr = it.next();
9078                synchronized (sr.stats.getBatteryStats()) {
9079                    sr.stats.stopLaunchedLocked();
9080                }
9081                sr.app = null;
9082                sr.executeNesting = 0;
9083                if (mStoppingServices.remove(sr)) {
9084                    if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9085                }
9086
9087                boolean hasClients = sr.bindings.size() > 0;
9088                if (hasClients) {
9089                    Iterator<IntentBindRecord> bindings
9090                            = sr.bindings.values().iterator();
9091                    while (bindings.hasNext()) {
9092                        IntentBindRecord b = bindings.next();
9093                        if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
9094                                + ": shouldUnbind=" + b.hasBound);
9095                        b.binder = null;
9096                        b.requested = b.received = b.hasBound = false;
9097                    }
9098                }
9099
9100                if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9101                        &ApplicationInfo.FLAG_PERSISTENT) == 0) {
9102                    Slog.w(TAG, "Service crashed " + sr.crashCount
9103                            + " times, stopping: " + sr);
9104                    EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
9105                            sr.crashCount, sr.shortName, app.pid);
9106                    bringDownServiceLocked(sr, true);
9107                } else if (!allowRestart) {
9108                    bringDownServiceLocked(sr, true);
9109                } else {
9110                    boolean canceled = scheduleServiceRestartLocked(sr, true);
9111
9112                    // Should the service remain running?  Note that in the
9113                    // extreme case of so many attempts to deliver a command
9114                    // that it failed, that we also will stop it here.
9115                    if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9116                        if (sr.pendingStarts.size() == 0) {
9117                            sr.startRequested = false;
9118                            if (!hasClients) {
9119                                // Whoops, no reason to restart!
9120                                bringDownServiceLocked(sr, true);
9121                            }
9122                        }
9123                    }
9124                }
9125            }
9126
9127            if (!allowRestart) {
9128                app.services.clear();
9129            }
9130        }
9131
9132        // Make sure we have no more records on the stopping list.
9133        int i = mStoppingServices.size();
9134        while (i > 0) {
9135            i--;
9136            ServiceRecord sr = mStoppingServices.get(i);
9137            if (sr.app == app) {
9138                mStoppingServices.remove(i);
9139                if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9140            }
9141        }
9142
9143        app.executingServices.clear();
9144    }
9145
9146    private final void removeDyingProviderLocked(ProcessRecord proc,
9147            ContentProviderRecord cpr) {
9148        synchronized (cpr) {
9149            cpr.launchingApp = null;
9150            cpr.notifyAll();
9151        }
9152
9153        mProvidersByClass.remove(cpr.info.name);
9154        String names[] = cpr.info.authority.split(";");
9155        for (int j = 0; j < names.length; j++) {
9156            mProvidersByName.remove(names[j]);
9157        }
9158
9159        Iterator<ProcessRecord> cit = cpr.clients.iterator();
9160        while (cit.hasNext()) {
9161            ProcessRecord capp = cit.next();
9162            if (!capp.persistent && capp.thread != null
9163                    && capp.pid != 0
9164                    && capp.pid != MY_PID) {
9165                Slog.i(TAG, "Kill " + capp.processName
9166                        + " (pid " + capp.pid + "): provider " + cpr.info.name
9167                        + " in dying process " + proc.processName);
9168                EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
9169                        capp.processName, capp.setAdj, "dying provider " + proc.processName);
9170                Process.killProcessQuiet(capp.pid);
9171            }
9172        }
9173
9174        mLaunchingProviders.remove(cpr);
9175    }
9176
9177    /**
9178     * Main code for cleaning up a process when it has gone away.  This is
9179     * called both as a result of the process dying, or directly when stopping
9180     * a process when running in single process mode.
9181     */
9182    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
9183            boolean restarting, int index) {
9184        if (index >= 0) {
9185            mLruProcesses.remove(index);
9186        }
9187
9188        mProcessesToGc.remove(app);
9189
9190        // Dismiss any open dialogs.
9191        if (app.crashDialog != null) {
9192            app.crashDialog.dismiss();
9193            app.crashDialog = null;
9194        }
9195        if (app.anrDialog != null) {
9196            app.anrDialog.dismiss();
9197            app.anrDialog = null;
9198        }
9199        if (app.waitDialog != null) {
9200            app.waitDialog.dismiss();
9201            app.waitDialog = null;
9202        }
9203
9204        app.crashing = false;
9205        app.notResponding = false;
9206
9207        app.resetPackageList();
9208        app.thread = null;
9209        app.forcingToForeground = null;
9210        app.foregroundServices = false;
9211        app.foregroundActivities = false;
9212
9213        killServicesLocked(app, true);
9214
9215        boolean restart = false;
9216
9217        int NL = mLaunchingProviders.size();
9218
9219        // Remove published content providers.
9220        if (!app.pubProviders.isEmpty()) {
9221            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
9222            while (it.hasNext()) {
9223                ContentProviderRecord cpr = it.next();
9224                cpr.provider = null;
9225                cpr.app = null;
9226
9227                // See if someone is waiting for this provider...  in which
9228                // case we don't remove it, but just let it restart.
9229                int i = 0;
9230                if (!app.bad) {
9231                    for (; i<NL; i++) {
9232                        if (mLaunchingProviders.get(i) == cpr) {
9233                            restart = true;
9234                            break;
9235                        }
9236                    }
9237                } else {
9238                    i = NL;
9239                }
9240
9241                if (i >= NL) {
9242                    removeDyingProviderLocked(app, cpr);
9243                    NL = mLaunchingProviders.size();
9244                }
9245            }
9246            app.pubProviders.clear();
9247        }
9248
9249        // Take care of any launching providers waiting for this process.
9250        if (checkAppInLaunchingProvidersLocked(app, false)) {
9251            restart = true;
9252        }
9253
9254        // Unregister from connected content providers.
9255        if (!app.conProviders.isEmpty()) {
9256            Iterator it = app.conProviders.keySet().iterator();
9257            while (it.hasNext()) {
9258                ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9259                cpr.clients.remove(app);
9260            }
9261            app.conProviders.clear();
9262        }
9263
9264        // At this point there may be remaining entries in mLaunchingProviders
9265        // where we were the only one waiting, so they are no longer of use.
9266        // Look for these and clean up if found.
9267        // XXX Commented out for now.  Trying to figure out a way to reproduce
9268        // the actual situation to identify what is actually going on.
9269        if (false) {
9270            for (int i=0; i<NL; i++) {
9271                ContentProviderRecord cpr = (ContentProviderRecord)
9272                        mLaunchingProviders.get(i);
9273                if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9274                    synchronized (cpr) {
9275                        cpr.launchingApp = null;
9276                        cpr.notifyAll();
9277                    }
9278                }
9279            }
9280        }
9281
9282        skipCurrentReceiverLocked(app);
9283
9284        // Unregister any receivers.
9285        if (app.receivers.size() > 0) {
9286            Iterator<ReceiverList> it = app.receivers.iterator();
9287            while (it.hasNext()) {
9288                removeReceiverLocked(it.next());
9289            }
9290            app.receivers.clear();
9291        }
9292
9293        // If the app is undergoing backup, tell the backup manager about it
9294        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
9295            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
9296            try {
9297                IBackupManager bm = IBackupManager.Stub.asInterface(
9298                        ServiceManager.getService(Context.BACKUP_SERVICE));
9299                bm.agentDisconnected(app.info.packageName);
9300            } catch (RemoteException e) {
9301                // can't happen; backup manager is local
9302            }
9303        }
9304
9305        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
9306
9307        // If the caller is restarting this app, then leave it in its
9308        // current lists and let the caller take care of it.
9309        if (restarting) {
9310            return;
9311        }
9312
9313        if (!app.persistent) {
9314            if (DEBUG_PROCESSES) Slog.v(TAG,
9315                    "Removing non-persistent process during cleanup: " + app);
9316            mProcessNames.remove(app.processName, app.info.uid);
9317            if (mHeavyWeightProcess == app) {
9318                mHeavyWeightProcess = null;
9319                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9320            }
9321        } else if (!app.removed) {
9322            // This app is persistent, so we need to keep its record around.
9323            // If it is not already on the pending app list, add it there
9324            // and start a new process for it.
9325            app.thread = null;
9326            app.forcingToForeground = null;
9327            app.foregroundServices = false;
9328            if (mPersistentStartingProcesses.indexOf(app) < 0) {
9329                mPersistentStartingProcesses.add(app);
9330                restart = true;
9331            }
9332        }
9333        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9334                "Clean-up removing on hold: " + app);
9335        mProcessesOnHold.remove(app);
9336
9337        if (app == mHomeProcess) {
9338            mHomeProcess = null;
9339        }
9340
9341        if (restart) {
9342            // We have components that still need to be running in the
9343            // process, so re-launch it.
9344            mProcessNames.put(app.processName, app.info.uid, app);
9345            startProcessLocked(app, "restart", app.processName);
9346        } else if (app.pid > 0 && app.pid != MY_PID) {
9347            // Goodbye!
9348            synchronized (mPidsSelfLocked) {
9349                mPidsSelfLocked.remove(app.pid);
9350                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9351            }
9352            app.setPid(0);
9353        }
9354    }
9355
9356    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9357        // Look through the content providers we are waiting to have launched,
9358        // and if any run in this process then either schedule a restart of
9359        // the process or kill the client waiting for it if this process has
9360        // gone bad.
9361        int NL = mLaunchingProviders.size();
9362        boolean restart = false;
9363        for (int i=0; i<NL; i++) {
9364            ContentProviderRecord cpr = mLaunchingProviders.get(i);
9365            if (cpr.launchingApp == app) {
9366                if (!alwaysBad && !app.bad) {
9367                    restart = true;
9368                } else {
9369                    removeDyingProviderLocked(app, cpr);
9370                    NL = mLaunchingProviders.size();
9371                }
9372            }
9373        }
9374        return restart;
9375    }
9376
9377    // =========================================================
9378    // SERVICES
9379    // =========================================================
9380
9381    ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9382        ActivityManager.RunningServiceInfo info =
9383            new ActivityManager.RunningServiceInfo();
9384        info.service = r.name;
9385        if (r.app != null) {
9386            info.pid = r.app.pid;
9387        }
9388        info.uid = r.appInfo.uid;
9389        info.process = r.processName;
9390        info.foreground = r.isForeground;
9391        info.activeSince = r.createTime;
9392        info.started = r.startRequested;
9393        info.clientCount = r.connections.size();
9394        info.crashCount = r.crashCount;
9395        info.lastActivityTime = r.lastActivity;
9396        if (r.isForeground) {
9397            info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9398        }
9399        if (r.startRequested) {
9400            info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9401        }
9402        if (r.app != null && r.app.pid == MY_PID) {
9403            info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9404        }
9405        if (r.app != null && r.app.persistent) {
9406            info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9407        }
9408
9409        for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9410            for (int i=0; i<connl.size(); i++) {
9411                ConnectionRecord conn = connl.get(i);
9412                if (conn.clientLabel != 0) {
9413                    info.clientPackage = conn.binding.client.info.packageName;
9414                    info.clientLabel = conn.clientLabel;
9415                    return info;
9416                }
9417            }
9418        }
9419        return info;
9420    }
9421
9422    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9423            int flags) {
9424        synchronized (this) {
9425            ArrayList<ActivityManager.RunningServiceInfo> res
9426                    = new ArrayList<ActivityManager.RunningServiceInfo>();
9427
9428            if (mServices.size() > 0) {
9429                Iterator<ServiceRecord> it = mServices.values().iterator();
9430                while (it.hasNext() && res.size() < maxNum) {
9431                    res.add(makeRunningServiceInfoLocked(it.next()));
9432                }
9433            }
9434
9435            for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9436                ServiceRecord r = mRestartingServices.get(i);
9437                ActivityManager.RunningServiceInfo info =
9438                        makeRunningServiceInfoLocked(r);
9439                info.restarting = r.nextRestartTime;
9440                res.add(info);
9441            }
9442
9443            return res;
9444        }
9445    }
9446
9447    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9448        synchronized (this) {
9449            ServiceRecord r = mServices.get(name);
9450            if (r != null) {
9451                for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9452                    for (int i=0; i<conn.size(); i++) {
9453                        if (conn.get(i).clientIntent != null) {
9454                            return conn.get(i).clientIntent;
9455                        }
9456                    }
9457                }
9458            }
9459        }
9460        return null;
9461    }
9462
9463    private final ServiceRecord findServiceLocked(ComponentName name,
9464            IBinder token) {
9465        ServiceRecord r = mServices.get(name);
9466        return r == token ? r : null;
9467    }
9468
9469    private final class ServiceLookupResult {
9470        final ServiceRecord record;
9471        final String permission;
9472
9473        ServiceLookupResult(ServiceRecord _record, String _permission) {
9474            record = _record;
9475            permission = _permission;
9476        }
9477    };
9478
9479    private ServiceLookupResult findServiceLocked(Intent service,
9480            String resolvedType) {
9481        ServiceRecord r = null;
9482        if (service.getComponent() != null) {
9483            r = mServices.get(service.getComponent());
9484        }
9485        if (r == null) {
9486            Intent.FilterComparison filter = new Intent.FilterComparison(service);
9487            r = mServicesByIntent.get(filter);
9488        }
9489
9490        if (r == null) {
9491            try {
9492                ResolveInfo rInfo =
9493                    AppGlobals.getPackageManager().resolveService(
9494                            service, resolvedType, 0);
9495                ServiceInfo sInfo =
9496                    rInfo != null ? rInfo.serviceInfo : null;
9497                if (sInfo == null) {
9498                    return null;
9499                }
9500
9501                ComponentName name = new ComponentName(
9502                        sInfo.applicationInfo.packageName, sInfo.name);
9503                r = mServices.get(name);
9504            } catch (RemoteException ex) {
9505                // pm is in same process, this will never happen.
9506            }
9507        }
9508        if (r != null) {
9509            int callingPid = Binder.getCallingPid();
9510            int callingUid = Binder.getCallingUid();
9511            if (checkComponentPermission(r.permission,
9512                    callingPid, callingUid, r.appInfo.uid, r.exported)
9513                    != PackageManager.PERMISSION_GRANTED) {
9514                if (!r.exported) {
9515                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9516                            + " from pid=" + callingPid
9517                            + ", uid=" + callingUid
9518                            + " that is not exported from uid " + r.appInfo.uid);
9519                    return new ServiceLookupResult(null, "not exported from uid "
9520                            + r.appInfo.uid);
9521                }
9522                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9523                        + " from pid=" + callingPid
9524                        + ", uid=" + callingUid
9525                        + " requires " + r.permission);
9526                return new ServiceLookupResult(null, r.permission);
9527            }
9528            return new ServiceLookupResult(r, null);
9529        }
9530        return null;
9531    }
9532
9533    private class ServiceRestarter implements Runnable {
9534        private ServiceRecord mService;
9535
9536        void setService(ServiceRecord service) {
9537            mService = service;
9538        }
9539
9540        public void run() {
9541            synchronized(ActivityManagerService.this) {
9542                performServiceRestartLocked(mService);
9543            }
9544        }
9545    }
9546
9547    private ServiceLookupResult retrieveServiceLocked(Intent service,
9548            String resolvedType, int callingPid, int callingUid) {
9549        ServiceRecord r = null;
9550        if (service.getComponent() != null) {
9551            r = mServices.get(service.getComponent());
9552        }
9553        Intent.FilterComparison filter = new Intent.FilterComparison(service);
9554        r = mServicesByIntent.get(filter);
9555        if (r == null) {
9556            try {
9557                ResolveInfo rInfo =
9558                    AppGlobals.getPackageManager().resolveService(
9559                            service, resolvedType, STOCK_PM_FLAGS);
9560                ServiceInfo sInfo =
9561                    rInfo != null ? rInfo.serviceInfo : null;
9562                if (sInfo == null) {
9563                    Slog.w(TAG, "Unable to start service " + service +
9564                          ": not found");
9565                    return null;
9566                }
9567
9568                ComponentName name = new ComponentName(
9569                        sInfo.applicationInfo.packageName, sInfo.name);
9570                r = mServices.get(name);
9571                if (r == null) {
9572                    filter = new Intent.FilterComparison(service.cloneFilter());
9573                    ServiceRestarter res = new ServiceRestarter();
9574                    BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9575                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9576                    synchronized (stats) {
9577                        ss = stats.getServiceStatsLocked(
9578                                sInfo.applicationInfo.uid, sInfo.packageName,
9579                                sInfo.name);
9580                    }
9581                    r = new ServiceRecord(this, ss, name, filter, sInfo, res);
9582                    res.setService(r);
9583                    mServices.put(name, r);
9584                    mServicesByIntent.put(filter, r);
9585
9586                    // Make sure this component isn't in the pending list.
9587                    int N = mPendingServices.size();
9588                    for (int i=0; i<N; i++) {
9589                        ServiceRecord pr = mPendingServices.get(i);
9590                        if (pr.name.equals(name)) {
9591                            mPendingServices.remove(i);
9592                            i--;
9593                            N--;
9594                        }
9595                    }
9596                }
9597            } catch (RemoteException ex) {
9598                // pm is in same process, this will never happen.
9599            }
9600        }
9601        if (r != null) {
9602            if (checkComponentPermission(r.permission,
9603                    callingPid, callingUid, r.appInfo.uid, r.exported)
9604                    != PackageManager.PERMISSION_GRANTED) {
9605                if (!r.exported) {
9606                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9607                            + " from pid=" + callingPid
9608                            + ", uid=" + callingUid
9609                            + " that is not exported from uid " + r.appInfo.uid);
9610                    return new ServiceLookupResult(null, "not exported from uid "
9611                            + r.appInfo.uid);
9612                }
9613                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9614                        + " from pid=" + callingPid
9615                        + ", uid=" + callingUid
9616                        + " requires " + r.permission);
9617                return new ServiceLookupResult(null, r.permission);
9618            }
9619            return new ServiceLookupResult(r, null);
9620        }
9621        return null;
9622    }
9623
9624    private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9625        if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9626                + why + " of " + r + " in app " + r.app);
9627        else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9628                + why + " of " + r.shortName);
9629        long now = SystemClock.uptimeMillis();
9630        if (r.executeNesting == 0 && r.app != null) {
9631            if (r.app.executingServices.size() == 0) {
9632                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9633                msg.obj = r.app;
9634                mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9635            }
9636            r.app.executingServices.add(r);
9637        }
9638        r.executeNesting++;
9639        r.executingStart = now;
9640    }
9641
9642    private final void sendServiceArgsLocked(ServiceRecord r,
9643            boolean oomAdjusted) {
9644        final int N = r.pendingStarts.size();
9645        if (N == 0) {
9646            return;
9647        }
9648
9649        while (r.pendingStarts.size() > 0) {
9650            try {
9651                ServiceRecord.StartItem si = r.pendingStarts.remove(0);
9652                if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9653                        + r + " " + r.intent + " args=" + si.intent);
9654                if (si.intent == null && N > 1) {
9655                    // If somehow we got a dummy null intent in the middle,
9656                    // then skip it.  DO NOT skip a null intent when it is
9657                    // the only one in the list -- this is to support the
9658                    // onStartCommand(null) case.
9659                    continue;
9660                }
9661                si.deliveredTime = SystemClock.uptimeMillis();
9662                r.deliveredStarts.add(si);
9663                si.deliveryCount++;
9664                if (si.targetPermissionUid >= 0 && si.intent != null) {
9665                    grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
9666                            r.packageName, si.intent, si.getUriPermissionsLocked());
9667                }
9668                bumpServiceExecutingLocked(r, "start");
9669                if (!oomAdjusted) {
9670                    oomAdjusted = true;
9671                    updateOomAdjLocked(r.app);
9672                }
9673                int flags = 0;
9674                if (si.deliveryCount > 0) {
9675                    flags |= Service.START_FLAG_RETRY;
9676                }
9677                if (si.doneExecutingCount > 0) {
9678                    flags |= Service.START_FLAG_REDELIVERY;
9679                }
9680                r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
9681            } catch (RemoteException e) {
9682                // Remote process gone...  we'll let the normal cleanup take
9683                // care of this.
9684                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
9685                break;
9686            } catch (Exception e) {
9687                Slog.w(TAG, "Unexpected exception", e);
9688                break;
9689            }
9690        }
9691    }
9692
9693    private final boolean requestServiceBindingLocked(ServiceRecord r,
9694            IntentBindRecord i, boolean rebind) {
9695        if (r.app == null || r.app.thread == null) {
9696            // If service is not currently running, can't yet bind.
9697            return false;
9698        }
9699        if ((!i.requested || rebind) && i.apps.size() > 0) {
9700            try {
9701                bumpServiceExecutingLocked(r, "bind");
9702                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9703                if (!rebind) {
9704                    i.requested = true;
9705                }
9706                i.hasBound = true;
9707                i.doRebind = false;
9708            } catch (RemoteException e) {
9709                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
9710                return false;
9711            }
9712        }
9713        return true;
9714    }
9715
9716    private final void requestServiceBindingsLocked(ServiceRecord r) {
9717        Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9718        while (bindings.hasNext()) {
9719            IntentBindRecord i = bindings.next();
9720            if (!requestServiceBindingLocked(r, i, false)) {
9721                break;
9722            }
9723        }
9724    }
9725
9726    private final void realStartServiceLocked(ServiceRecord r,
9727            ProcessRecord app) throws RemoteException {
9728        if (app.thread == null) {
9729            throw new RemoteException();
9730        }
9731
9732        r.app = app;
9733        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
9734
9735        app.services.add(r);
9736        bumpServiceExecutingLocked(r, "create");
9737        updateLruProcessLocked(app, true, true);
9738
9739        boolean created = false;
9740        try {
9741            mStringBuilder.setLength(0);
9742            r.intent.getIntent().toShortString(mStringBuilder, false, true);
9743            EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
9744                    System.identityHashCode(r), r.shortName,
9745                    mStringBuilder.toString(), r.app.pid);
9746            synchronized (r.stats.getBatteryStats()) {
9747                r.stats.startLaunchedLocked();
9748            }
9749            ensurePackageDexOpt(r.serviceInfo.packageName);
9750            app.thread.scheduleCreateService(r, r.serviceInfo,
9751                    compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
9752            r.postNotification();
9753            created = true;
9754        } finally {
9755            if (!created) {
9756                app.services.remove(r);
9757                scheduleServiceRestartLocked(r, false);
9758            }
9759        }
9760
9761        requestServiceBindingsLocked(r);
9762
9763        // If the service is in the started state, and there are no
9764        // pending arguments, then fake up one so its onStartCommand() will
9765        // be called.
9766        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
9767            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
9768                    null, -1));
9769        }
9770
9771        sendServiceArgsLocked(r, true);
9772    }
9773
9774    private final boolean scheduleServiceRestartLocked(ServiceRecord r,
9775            boolean allowCancel) {
9776        boolean canceled = false;
9777
9778        final long now = SystemClock.uptimeMillis();
9779        long minDuration = SERVICE_RESTART_DURATION;
9780        long resetTime = SERVICE_RESET_RUN_DURATION;
9781
9782        if ((r.serviceInfo.applicationInfo.flags
9783                &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9784            minDuration /= 4;
9785        }
9786
9787        // Any delivered but not yet finished starts should be put back
9788        // on the pending list.
9789        final int N = r.deliveredStarts.size();
9790        if (N > 0) {
9791            for (int i=N-1; i>=0; i--) {
9792                ServiceRecord.StartItem si = r.deliveredStarts.get(i);
9793                si.removeUriPermissionsLocked();
9794                if (si.intent == null) {
9795                    // We'll generate this again if needed.
9796                } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
9797                        && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
9798                    r.pendingStarts.add(0, si);
9799                    long dur = SystemClock.uptimeMillis() - si.deliveredTime;
9800                    dur *= 2;
9801                    if (minDuration < dur) minDuration = dur;
9802                    if (resetTime < dur) resetTime = dur;
9803                } else {
9804                    Slog.w(TAG, "Canceling start item " + si.intent + " in service "
9805                            + r.name);
9806                    canceled = true;
9807                }
9808            }
9809            r.deliveredStarts.clear();
9810        }
9811
9812        r.totalRestartCount++;
9813        if (r.restartDelay == 0) {
9814            r.restartCount++;
9815            r.restartDelay = minDuration;
9816        } else {
9817            // If it has been a "reasonably long time" since the service
9818            // was started, then reset our restart duration back to
9819            // the beginning, so we don't infinitely increase the duration
9820            // on a service that just occasionally gets killed (which is
9821            // a normal case, due to process being killed to reclaim memory).
9822            if (now > (r.restartTime+resetTime)) {
9823                r.restartCount = 1;
9824                r.restartDelay = minDuration;
9825            } else {
9826                if ((r.serviceInfo.applicationInfo.flags
9827                        &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9828                    // Services in peristent processes will restart much more
9829                    // quickly, since they are pretty important.  (Think SystemUI).
9830                    r.restartDelay += minDuration/2;
9831                } else {
9832                    r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
9833                    if (r.restartDelay < minDuration) {
9834                        r.restartDelay = minDuration;
9835                    }
9836                }
9837            }
9838        }
9839
9840        r.nextRestartTime = now + r.restartDelay;
9841
9842        // Make sure that we don't end up restarting a bunch of services
9843        // all at the same time.
9844        boolean repeat;
9845        do {
9846            repeat = false;
9847            for (int i=mRestartingServices.size()-1; i>=0; i--) {
9848                ServiceRecord r2 = mRestartingServices.get(i);
9849                if (r2 != r && r.nextRestartTime
9850                        >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
9851                        && r.nextRestartTime
9852                        < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
9853                    r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
9854                    r.restartDelay = r.nextRestartTime - now;
9855                    repeat = true;
9856                    break;
9857                }
9858            }
9859        } while (repeat);
9860
9861        if (!mRestartingServices.contains(r)) {
9862            mRestartingServices.add(r);
9863        }
9864
9865        r.cancelNotification();
9866
9867        mHandler.removeCallbacks(r.restarter);
9868        mHandler.postAtTime(r.restarter, r.nextRestartTime);
9869        r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
9870        Slog.w(TAG, "Scheduling restart of crashed service "
9871                + r.shortName + " in " + r.restartDelay + "ms");
9872        EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
9873                r.shortName, r.restartDelay);
9874
9875        return canceled;
9876    }
9877
9878    final void performServiceRestartLocked(ServiceRecord r) {
9879        if (!mRestartingServices.contains(r)) {
9880            return;
9881        }
9882        bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9883    }
9884
9885    private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9886        if (r.restartDelay == 0) {
9887            return false;
9888        }
9889        r.resetRestartCounter();
9890        mRestartingServices.remove(r);
9891        mHandler.removeCallbacks(r.restarter);
9892        return true;
9893    }
9894
9895    private final boolean bringUpServiceLocked(ServiceRecord r,
9896            int intentFlags, boolean whileRestarting) {
9897        //Slog.i(TAG, "Bring up service:");
9898        //r.dump("  ");
9899
9900        if (r.app != null && r.app.thread != null) {
9901            sendServiceArgsLocked(r, false);
9902            return true;
9903        }
9904
9905        if (!whileRestarting && r.restartDelay > 0) {
9906            // If waiting for a restart, then do nothing.
9907            return true;
9908        }
9909
9910        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
9911
9912        // We are now bringing the service up, so no longer in the
9913        // restarting state.
9914        mRestartingServices.remove(r);
9915
9916        // Service is now being launched, its package can't be stopped.
9917        try {
9918            AppGlobals.getPackageManager().setPackageStoppedState(
9919                    r.packageName, false);
9920        } catch (RemoteException e) {
9921        } catch (IllegalArgumentException e) {
9922            Slog.w(TAG, "Failed trying to unstop package "
9923                    + r.packageName + ": " + e);
9924        }
9925
9926        final String appName = r.processName;
9927        ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
9928        if (app != null && app.thread != null) {
9929            try {
9930                app.addPackage(r.appInfo.packageName);
9931                realStartServiceLocked(r, app);
9932                return true;
9933            } catch (RemoteException e) {
9934                Slog.w(TAG, "Exception when starting service " + r.shortName, e);
9935            }
9936
9937            // If a dead object exception was thrown -- fall through to
9938            // restart the application.
9939        }
9940
9941        // Not running -- get it started, and enqueue this service record
9942        // to be executed when the app comes up.
9943        if (startProcessLocked(appName, r.appInfo, true, intentFlags,
9944                "service", r.name, false) == null) {
9945            Slog.w(TAG, "Unable to launch app "
9946                    + r.appInfo.packageName + "/"
9947                    + r.appInfo.uid + " for service "
9948                    + r.intent.getIntent() + ": process is bad");
9949            bringDownServiceLocked(r, true);
9950            return false;
9951        }
9952
9953        if (!mPendingServices.contains(r)) {
9954            mPendingServices.add(r);
9955        }
9956
9957        return true;
9958    }
9959
9960    private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
9961        //Slog.i(TAG, "Bring down service:");
9962        //r.dump("  ");
9963
9964        // Does it still need to run?
9965        if (!force && r.startRequested) {
9966            return;
9967        }
9968        if (r.connections.size() > 0) {
9969            if (!force) {
9970                // XXX should probably keep a count of the number of auto-create
9971                // connections directly in the service.
9972                Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
9973                while (it.hasNext()) {
9974                    ArrayList<ConnectionRecord> cr = it.next();
9975                    for (int i=0; i<cr.size(); i++) {
9976                        if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
9977                            return;
9978                        }
9979                    }
9980                }
9981            }
9982
9983            // Report to all of the connections that the service is no longer
9984            // available.
9985            Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
9986            while (it.hasNext()) {
9987                ArrayList<ConnectionRecord> c = it.next();
9988                for (int i=0; i<c.size(); i++) {
9989                    try {
9990                        c.get(i).conn.connected(r.name, null);
9991                    } catch (Exception e) {
9992                        Slog.w(TAG, "Failure disconnecting service " + r.name +
9993                              " to connection " + c.get(i).conn.asBinder() +
9994                              " (in " + c.get(i).binding.client.processName + ")", e);
9995                    }
9996                }
9997            }
9998        }
9999
10000        // Tell the service that it has been unbound.
10001        if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10002            Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10003            while (it.hasNext()) {
10004                IntentBindRecord ibr = it.next();
10005                if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
10006                        + ": hasBound=" + ibr.hasBound);
10007                if (r.app != null && r.app.thread != null && ibr.hasBound) {
10008                    try {
10009                        bumpServiceExecutingLocked(r, "bring down unbind");
10010                        updateOomAdjLocked(r.app);
10011                        ibr.hasBound = false;
10012                        r.app.thread.scheduleUnbindService(r,
10013                                ibr.intent.getIntent());
10014                    } catch (Exception e) {
10015                        Slog.w(TAG, "Exception when unbinding service "
10016                                + r.shortName, e);
10017                        serviceDoneExecutingLocked(r, true);
10018                    }
10019                }
10020            }
10021        }
10022
10023        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
10024        EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
10025                System.identityHashCode(r), r.shortName,
10026                (r.app != null) ? r.app.pid : -1);
10027
10028        mServices.remove(r.name);
10029        mServicesByIntent.remove(r.intent);
10030        r.totalRestartCount = 0;
10031        unscheduleServiceRestartLocked(r);
10032
10033        // Also make sure it is not on the pending list.
10034        int N = mPendingServices.size();
10035        for (int i=0; i<N; i++) {
10036            if (mPendingServices.get(i) == r) {
10037                mPendingServices.remove(i);
10038                if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
10039                i--;
10040                N--;
10041            }
10042        }
10043
10044        r.cancelNotification();
10045        r.isForeground = false;
10046        r.foregroundId = 0;
10047        r.foregroundNoti = null;
10048
10049        // Clear start entries.
10050        r.clearDeliveredStartsLocked();
10051        r.pendingStarts.clear();
10052
10053        if (r.app != null) {
10054            synchronized (r.stats.getBatteryStats()) {
10055                r.stats.stopLaunchedLocked();
10056            }
10057            r.app.services.remove(r);
10058            if (r.app.thread != null) {
10059                try {
10060                    bumpServiceExecutingLocked(r, "stop");
10061                    mStoppingServices.add(r);
10062                    updateOomAdjLocked(r.app);
10063                    r.app.thread.scheduleStopService(r);
10064                } catch (Exception e) {
10065                    Slog.w(TAG, "Exception when stopping service "
10066                            + r.shortName, e);
10067                    serviceDoneExecutingLocked(r, true);
10068                }
10069                updateServiceForegroundLocked(r.app, false);
10070            } else {
10071                if (DEBUG_SERVICE) Slog.v(
10072                    TAG, "Removed service that has no process: " + r);
10073            }
10074        } else {
10075            if (DEBUG_SERVICE) Slog.v(
10076                TAG, "Removed service that is not running: " + r);
10077        }
10078
10079        if (r.bindings.size() > 0) {
10080            r.bindings.clear();
10081        }
10082
10083        if (r.restarter instanceof ServiceRestarter) {
10084           ((ServiceRestarter)r.restarter).setService(null);
10085        }
10086    }
10087
10088    ComponentName startServiceLocked(IApplicationThread caller,
10089            Intent service, String resolvedType,
10090            int callingPid, int callingUid) {
10091        synchronized(this) {
10092            if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
10093                    + " type=" + resolvedType + " args=" + service.getExtras());
10094
10095            if (caller != null) {
10096                final ProcessRecord callerApp = getRecordForAppLocked(caller);
10097                if (callerApp == null) {
10098                    throw new SecurityException(
10099                            "Unable to find app for caller " + caller
10100                            + " (pid=" + Binder.getCallingPid()
10101                            + ") when starting service " + service);
10102                }
10103            }
10104
10105            ServiceLookupResult res =
10106                retrieveServiceLocked(service, resolvedType,
10107                        callingPid, callingUid);
10108            if (res == null) {
10109                return null;
10110            }
10111            if (res.record == null) {
10112                return new ComponentName("!", res.permission != null
10113                        ? res.permission : "private to package");
10114            }
10115            ServiceRecord r = res.record;
10116            int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10117                    callingUid, r.packageName, service);
10118            if (unscheduleServiceRestartLocked(r)) {
10119                if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
10120            }
10121            r.startRequested = true;
10122            r.callStart = false;
10123            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10124                    service, targetPermissionUid));
10125            r.lastActivity = SystemClock.uptimeMillis();
10126            synchronized (r.stats.getBatteryStats()) {
10127                r.stats.startRunningLocked();
10128            }
10129            if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10130                return new ComponentName("!", "Service process is bad");
10131            }
10132            return r.name;
10133        }
10134    }
10135
10136    public ComponentName startService(IApplicationThread caller, Intent service,
10137            String resolvedType) {
10138        // Refuse possible leaked file descriptors
10139        if (service != null && service.hasFileDescriptors() == true) {
10140            throw new IllegalArgumentException("File descriptors passed in Intent");
10141        }
10142
10143        synchronized(this) {
10144            final int callingPid = Binder.getCallingPid();
10145            final int callingUid = Binder.getCallingUid();
10146            final long origId = Binder.clearCallingIdentity();
10147            ComponentName res = startServiceLocked(caller, service,
10148                    resolvedType, callingPid, callingUid);
10149            Binder.restoreCallingIdentity(origId);
10150            return res;
10151        }
10152    }
10153
10154    ComponentName startServiceInPackage(int uid,
10155            Intent service, String resolvedType) {
10156        synchronized(this) {
10157            final long origId = Binder.clearCallingIdentity();
10158            ComponentName res = startServiceLocked(null, service,
10159                    resolvedType, -1, uid);
10160            Binder.restoreCallingIdentity(origId);
10161            return res;
10162        }
10163    }
10164
10165    private void stopServiceLocked(ServiceRecord service) {
10166        synchronized (service.stats.getBatteryStats()) {
10167            service.stats.stopRunningLocked();
10168        }
10169        service.startRequested = false;
10170        service.callStart = false;
10171        bringDownServiceLocked(service, false);
10172    }
10173
10174    public int stopService(IApplicationThread caller, Intent service,
10175            String resolvedType) {
10176        // Refuse possible leaked file descriptors
10177        if (service != null && service.hasFileDescriptors() == true) {
10178            throw new IllegalArgumentException("File descriptors passed in Intent");
10179        }
10180
10181        synchronized(this) {
10182            if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
10183                    + " type=" + resolvedType);
10184
10185            final ProcessRecord callerApp = getRecordForAppLocked(caller);
10186            if (caller != null && callerApp == null) {
10187                throw new SecurityException(
10188                        "Unable to find app for caller " + caller
10189                        + " (pid=" + Binder.getCallingPid()
10190                        + ") when stopping service " + service);
10191            }
10192
10193            // If this service is active, make sure it is stopped.
10194            ServiceLookupResult r = findServiceLocked(service, resolvedType);
10195            if (r != null) {
10196                if (r.record != null) {
10197                    final long origId = Binder.clearCallingIdentity();
10198                    try {
10199                        stopServiceLocked(r.record);
10200                    } finally {
10201                        Binder.restoreCallingIdentity(origId);
10202                    }
10203                    return 1;
10204                }
10205                return -1;
10206            }
10207        }
10208
10209        return 0;
10210    }
10211
10212    public IBinder peekService(Intent service, String resolvedType) {
10213        // Refuse possible leaked file descriptors
10214        if (service != null && service.hasFileDescriptors() == true) {
10215            throw new IllegalArgumentException("File descriptors passed in Intent");
10216        }
10217
10218        IBinder ret = null;
10219
10220        synchronized(this) {
10221            ServiceLookupResult r = findServiceLocked(service, resolvedType);
10222
10223            if (r != null) {
10224                // r.record is null if findServiceLocked() failed the caller permission check
10225                if (r.record == null) {
10226                    throw new SecurityException(
10227                            "Permission Denial: Accessing service " + r.record.name
10228                            + " from pid=" + Binder.getCallingPid()
10229                            + ", uid=" + Binder.getCallingUid()
10230                            + " requires " + r.permission);
10231                }
10232                IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10233                if (ib != null) {
10234                    ret = ib.binder;
10235                }
10236            }
10237        }
10238
10239        return ret;
10240    }
10241
10242    public boolean stopServiceToken(ComponentName className, IBinder token,
10243            int startId) {
10244        synchronized(this) {
10245            if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
10246                    + " " + token + " startId=" + startId);
10247            ServiceRecord r = findServiceLocked(className, token);
10248            if (r != null) {
10249                if (startId >= 0) {
10250                    // Asked to only stop if done with all work.  Note that
10251                    // to avoid leaks, we will take this as dropping all
10252                    // start items up to and including this one.
10253                    ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10254                    if (si != null) {
10255                        while (r.deliveredStarts.size() > 0) {
10256                            ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10257                            cur.removeUriPermissionsLocked();
10258                            if (cur == si) {
10259                                break;
10260                            }
10261                        }
10262                    }
10263
10264                    if (r.getLastStartId() != startId) {
10265                        return false;
10266                    }
10267
10268                    if (r.deliveredStarts.size() > 0) {
10269                        Slog.w(TAG, "stopServiceToken startId " + startId
10270                                + " is last, but have " + r.deliveredStarts.size()
10271                                + " remaining args");
10272                    }
10273                }
10274
10275                synchronized (r.stats.getBatteryStats()) {
10276                    r.stats.stopRunningLocked();
10277                    r.startRequested = false;
10278                    r.callStart = false;
10279                }
10280                final long origId = Binder.clearCallingIdentity();
10281                bringDownServiceLocked(r, false);
10282                Binder.restoreCallingIdentity(origId);
10283                return true;
10284            }
10285        }
10286        return false;
10287    }
10288
10289    public void setServiceForeground(ComponentName className, IBinder token,
10290            int id, Notification notification, boolean removeNotification) {
10291        final long origId = Binder.clearCallingIdentity();
10292        try {
10293        synchronized(this) {
10294            ServiceRecord r = findServiceLocked(className, token);
10295            if (r != null) {
10296                if (id != 0) {
10297                    if (notification == null) {
10298                        throw new IllegalArgumentException("null notification");
10299                    }
10300                    if (r.foregroundId != id) {
10301                        r.cancelNotification();
10302                        r.foregroundId = id;
10303                    }
10304                    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10305                    r.foregroundNoti = notification;
10306                    r.isForeground = true;
10307                    r.postNotification();
10308                    if (r.app != null) {
10309                        updateServiceForegroundLocked(r.app, true);
10310                    }
10311                } else {
10312                    if (r.isForeground) {
10313                        r.isForeground = false;
10314                        if (r.app != null) {
10315                            updateLruProcessLocked(r.app, false, true);
10316                            updateServiceForegroundLocked(r.app, true);
10317                        }
10318                    }
10319                    if (removeNotification) {
10320                        r.cancelNotification();
10321                        r.foregroundId = 0;
10322                        r.foregroundNoti = null;
10323                    }
10324                }
10325            }
10326        }
10327        } finally {
10328            Binder.restoreCallingIdentity(origId);
10329        }
10330    }
10331
10332    public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10333        boolean anyForeground = false;
10334        for (ServiceRecord sr : proc.services) {
10335            if (sr.isForeground) {
10336                anyForeground = true;
10337                break;
10338            }
10339        }
10340        if (anyForeground != proc.foregroundServices) {
10341            proc.foregroundServices = anyForeground;
10342            if (oomAdj) {
10343                updateOomAdjLocked();
10344            }
10345        }
10346    }
10347
10348    public int bindService(IApplicationThread caller, IBinder token,
10349            Intent service, String resolvedType,
10350            IServiceConnection connection, int flags) {
10351        // Refuse possible leaked file descriptors
10352        if (service != null && service.hasFileDescriptors() == true) {
10353            throw new IllegalArgumentException("File descriptors passed in Intent");
10354        }
10355
10356        synchronized(this) {
10357            if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
10358                    + " type=" + resolvedType + " conn=" + connection.asBinder()
10359                    + " flags=0x" + Integer.toHexString(flags));
10360            final ProcessRecord callerApp = getRecordForAppLocked(caller);
10361            if (callerApp == null) {
10362                throw new SecurityException(
10363                        "Unable to find app for caller " + caller
10364                        + " (pid=" + Binder.getCallingPid()
10365                        + ") when binding service " + service);
10366            }
10367
10368            ActivityRecord activity = null;
10369            if (token != null) {
10370                int aindex = mMainStack.indexOfTokenLocked(token);
10371                if (aindex < 0) {
10372                    Slog.w(TAG, "Binding with unknown activity: " + token);
10373                    return 0;
10374                }
10375                activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
10376            }
10377
10378            int clientLabel = 0;
10379            PendingIntent clientIntent = null;
10380
10381            if (callerApp.info.uid == Process.SYSTEM_UID) {
10382                // Hacky kind of thing -- allow system stuff to tell us
10383                // what they are, so we can report this elsewhere for
10384                // others to know why certain services are running.
10385                try {
10386                    clientIntent = (PendingIntent)service.getParcelableExtra(
10387                            Intent.EXTRA_CLIENT_INTENT);
10388                } catch (RuntimeException e) {
10389                }
10390                if (clientIntent != null) {
10391                    clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10392                    if (clientLabel != 0) {
10393                        // There are no useful extras in the intent, trash them.
10394                        // System code calling with this stuff just needs to know
10395                        // this will happen.
10396                        service = service.cloneFilter();
10397                    }
10398                }
10399            }
10400
10401            ServiceLookupResult res =
10402                retrieveServiceLocked(service, resolvedType,
10403                        Binder.getCallingPid(), Binder.getCallingUid());
10404            if (res == null) {
10405                return 0;
10406            }
10407            if (res.record == null) {
10408                return -1;
10409            }
10410            ServiceRecord s = res.record;
10411
10412            final long origId = Binder.clearCallingIdentity();
10413
10414            if (unscheduleServiceRestartLocked(s)) {
10415                if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
10416                        + s);
10417            }
10418
10419            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10420            ConnectionRecord c = new ConnectionRecord(b, activity,
10421                    connection, flags, clientLabel, clientIntent);
10422
10423            IBinder binder = connection.asBinder();
10424            ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10425            if (clist == null) {
10426                clist = new ArrayList<ConnectionRecord>();
10427                s.connections.put(binder, clist);
10428            }
10429            clist.add(c);
10430            b.connections.add(c);
10431            if (activity != null) {
10432                if (activity.connections == null) {
10433                    activity.connections = new HashSet<ConnectionRecord>();
10434                }
10435                activity.connections.add(c);
10436            }
10437            b.client.connections.add(c);
10438            clist = mServiceConnections.get(binder);
10439            if (clist == null) {
10440                clist = new ArrayList<ConnectionRecord>();
10441                mServiceConnections.put(binder, clist);
10442            }
10443            clist.add(c);
10444
10445            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10446                s.lastActivity = SystemClock.uptimeMillis();
10447                if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10448                    return 0;
10449                }
10450            }
10451
10452            if (s.app != null) {
10453                // This could have made the service more important.
10454                updateOomAdjLocked(s.app);
10455            }
10456
10457            if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
10458                    + ": received=" + b.intent.received
10459                    + " apps=" + b.intent.apps.size()
10460                    + " doRebind=" + b.intent.doRebind);
10461
10462            if (s.app != null && b.intent.received) {
10463                // Service is already running, so we can immediately
10464                // publish the connection.
10465                try {
10466                    c.conn.connected(s.name, b.intent.binder);
10467                } catch (Exception e) {
10468                    Slog.w(TAG, "Failure sending service " + s.shortName
10469                            + " to connection " + c.conn.asBinder()
10470                            + " (in " + c.binding.client.processName + ")", e);
10471                }
10472
10473                // If this is the first app connected back to this binding,
10474                // and the service had previously asked to be told when
10475                // rebound, then do so.
10476                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10477                    requestServiceBindingLocked(s, b.intent, true);
10478                }
10479            } else if (!b.intent.requested) {
10480                requestServiceBindingLocked(s, b.intent, false);
10481            }
10482
10483            Binder.restoreCallingIdentity(origId);
10484        }
10485
10486        return 1;
10487    }
10488
10489    void removeConnectionLocked(
10490        ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
10491        IBinder binder = c.conn.asBinder();
10492        AppBindRecord b = c.binding;
10493        ServiceRecord s = b.service;
10494        ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10495        if (clist != null) {
10496            clist.remove(c);
10497            if (clist.size() == 0) {
10498                s.connections.remove(binder);
10499            }
10500        }
10501        b.connections.remove(c);
10502        if (c.activity != null && c.activity != skipAct) {
10503            if (c.activity.connections != null) {
10504                c.activity.connections.remove(c);
10505            }
10506        }
10507        if (b.client != skipApp) {
10508            b.client.connections.remove(c);
10509        }
10510        clist = mServiceConnections.get(binder);
10511        if (clist != null) {
10512            clist.remove(c);
10513            if (clist.size() == 0) {
10514                mServiceConnections.remove(binder);
10515            }
10516        }
10517
10518        if (b.connections.size() == 0) {
10519            b.intent.apps.remove(b.client);
10520        }
10521
10522        if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
10523                + ": shouldUnbind=" + b.intent.hasBound);
10524        if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10525                && b.intent.hasBound) {
10526            try {
10527                bumpServiceExecutingLocked(s, "unbind");
10528                updateOomAdjLocked(s.app);
10529                b.intent.hasBound = false;
10530                // Assume the client doesn't want to know about a rebind;
10531                // we will deal with that later if it asks for one.
10532                b.intent.doRebind = false;
10533                s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10534            } catch (Exception e) {
10535                Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
10536                serviceDoneExecutingLocked(s, true);
10537            }
10538        }
10539
10540        if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10541            bringDownServiceLocked(s, false);
10542        }
10543    }
10544
10545    public boolean unbindService(IServiceConnection connection) {
10546        synchronized (this) {
10547            IBinder binder = connection.asBinder();
10548            if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
10549            ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10550            if (clist == null) {
10551                Slog.w(TAG, "Unbind failed: could not find connection for "
10552                      + connection.asBinder());
10553                return false;
10554            }
10555
10556            final long origId = Binder.clearCallingIdentity();
10557
10558            while (clist.size() > 0) {
10559                ConnectionRecord r = clist.get(0);
10560                removeConnectionLocked(r, null, null);
10561
10562                if (r.binding.service.app != null) {
10563                    // This could have made the service less important.
10564                    updateOomAdjLocked(r.binding.service.app);
10565                }
10566            }
10567
10568            Binder.restoreCallingIdentity(origId);
10569        }
10570
10571        return true;
10572    }
10573
10574    public void publishService(IBinder token, Intent intent, IBinder service) {
10575        // Refuse possible leaked file descriptors
10576        if (intent != null && intent.hasFileDescriptors() == true) {
10577            throw new IllegalArgumentException("File descriptors passed in Intent");
10578        }
10579
10580        synchronized(this) {
10581            if (!(token instanceof ServiceRecord)) {
10582                throw new IllegalArgumentException("Invalid service token");
10583            }
10584            ServiceRecord r = (ServiceRecord)token;
10585
10586            final long origId = Binder.clearCallingIdentity();
10587
10588            if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
10589                    + " " + intent + ": " + service);
10590            if (r != null) {
10591                Intent.FilterComparison filter
10592                        = new Intent.FilterComparison(intent);
10593                IntentBindRecord b = r.bindings.get(filter);
10594                if (b != null && !b.received) {
10595                    b.binder = service;
10596                    b.requested = true;
10597                    b.received = true;
10598                    if (r.connections.size() > 0) {
10599                        Iterator<ArrayList<ConnectionRecord>> it
10600                                = r.connections.values().iterator();
10601                        while (it.hasNext()) {
10602                            ArrayList<ConnectionRecord> clist = it.next();
10603                            for (int i=0; i<clist.size(); i++) {
10604                                ConnectionRecord c = clist.get(i);
10605                                if (!filter.equals(c.binding.intent.intent)) {
10606                                    if (DEBUG_SERVICE) Slog.v(
10607                                            TAG, "Not publishing to: " + c);
10608                                    if (DEBUG_SERVICE) Slog.v(
10609                                            TAG, "Bound intent: " + c.binding.intent.intent);
10610                                    if (DEBUG_SERVICE) Slog.v(
10611                                            TAG, "Published intent: " + intent);
10612                                    continue;
10613                                }
10614                                if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10615                                try {
10616                                    c.conn.connected(r.name, service);
10617                                } catch (Exception e) {
10618                                    Slog.w(TAG, "Failure sending service " + r.name +
10619                                          " to connection " + c.conn.asBinder() +
10620                                          " (in " + c.binding.client.processName + ")", e);
10621                                }
10622                            }
10623                        }
10624                    }
10625                }
10626
10627                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10628
10629                Binder.restoreCallingIdentity(origId);
10630            }
10631        }
10632    }
10633
10634    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10635        // Refuse possible leaked file descriptors
10636        if (intent != null && intent.hasFileDescriptors() == true) {
10637            throw new IllegalArgumentException("File descriptors passed in Intent");
10638        }
10639
10640        synchronized(this) {
10641            if (!(token instanceof ServiceRecord)) {
10642                throw new IllegalArgumentException("Invalid service token");
10643            }
10644            ServiceRecord r = (ServiceRecord)token;
10645
10646            final long origId = Binder.clearCallingIdentity();
10647
10648            if (r != null) {
10649                Intent.FilterComparison filter
10650                        = new Intent.FilterComparison(intent);
10651                IntentBindRecord b = r.bindings.get(filter);
10652                if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
10653                        + " at " + b + ": apps="
10654                        + (b != null ? b.apps.size() : 0));
10655                if (b != null) {
10656                    if (b.apps.size() > 0) {
10657                        // Applications have already bound since the last
10658                        // unbind, so just rebind right here.
10659                        requestServiceBindingLocked(r, b, true);
10660                    } else {
10661                        // Note to tell the service the next time there is
10662                        // a new client.
10663                        b.doRebind = true;
10664                    }
10665                }
10666
10667                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10668
10669                Binder.restoreCallingIdentity(origId);
10670            }
10671        }
10672    }
10673
10674    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10675        synchronized(this) {
10676            if (!(token instanceof ServiceRecord)) {
10677                throw new IllegalArgumentException("Invalid service token");
10678            }
10679            ServiceRecord r = (ServiceRecord)token;
10680            boolean inStopping = mStoppingServices.contains(token);
10681            if (r != null) {
10682                if (r != token) {
10683                    Slog.w(TAG, "Done executing service " + r.name
10684                          + " with incorrect token: given " + token
10685                          + ", expected " + r);
10686                    return;
10687                }
10688
10689                if (type == 1) {
10690                    // This is a call from a service start...  take care of
10691                    // book-keeping.
10692                    r.callStart = true;
10693                    switch (res) {
10694                        case Service.START_STICKY_COMPATIBILITY:
10695                        case Service.START_STICKY: {
10696                            // We are done with the associated start arguments.
10697                            r.findDeliveredStart(startId, true);
10698                            // Don't stop if killed.
10699                            r.stopIfKilled = false;
10700                            break;
10701                        }
10702                        case Service.START_NOT_STICKY: {
10703                            // We are done with the associated start arguments.
10704                            r.findDeliveredStart(startId, true);
10705                            if (r.getLastStartId() == startId) {
10706                                // There is no more work, and this service
10707                                // doesn't want to hang around if killed.
10708                                r.stopIfKilled = true;
10709                            }
10710                            break;
10711                        }
10712                        case Service.START_REDELIVER_INTENT: {
10713                            // We'll keep this item until they explicitly
10714                            // call stop for it, but keep track of the fact
10715                            // that it was delivered.
10716                            ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10717                            if (si != null) {
10718                                si.deliveryCount = 0;
10719                                si.doneExecutingCount++;
10720                                // Don't stop if killed.
10721                                r.stopIfKilled = true;
10722                            }
10723                            break;
10724                        }
10725                        case Service.START_TASK_REMOVED_COMPLETE: {
10726                            // Special processing for onTaskRemoved().  Don't
10727                            // impact normal onStartCommand() processing.
10728                            r.findDeliveredStart(startId, true);
10729                            break;
10730                        }
10731                        default:
10732                            throw new IllegalArgumentException(
10733                                    "Unknown service start result: " + res);
10734                    }
10735                    if (res == Service.START_STICKY_COMPATIBILITY) {
10736                        r.callStart = false;
10737                    }
10738                }
10739
10740                final long origId = Binder.clearCallingIdentity();
10741                serviceDoneExecutingLocked(r, inStopping);
10742                Binder.restoreCallingIdentity(origId);
10743            } else {
10744                Slog.w(TAG, "Done executing unknown service from pid "
10745                        + Binder.getCallingPid());
10746            }
10747        }
10748    }
10749
10750    public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
10751        if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
10752                + ": nesting=" + r.executeNesting
10753                + ", inStopping=" + inStopping + ", app=" + r.app);
10754        else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
10755        r.executeNesting--;
10756        if (r.executeNesting <= 0 && r.app != null) {
10757            if (DEBUG_SERVICE) Slog.v(TAG,
10758                    "Nesting at 0 of " + r.shortName);
10759            r.app.executingServices.remove(r);
10760            if (r.app.executingServices.size() == 0) {
10761                if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
10762                        "No more executingServices of " + r.shortName);
10763                mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10764            }
10765            if (inStopping) {
10766                if (DEBUG_SERVICE) Slog.v(TAG,
10767                        "doneExecuting remove stopping " + r);
10768                mStoppingServices.remove(r);
10769                r.bindings.clear();
10770            }
10771            updateOomAdjLocked(r.app);
10772        }
10773    }
10774
10775    void serviceTimeout(ProcessRecord proc) {
10776        String anrMessage = null;
10777
10778        synchronized(this) {
10779            if (proc.executingServices.size() == 0 || proc.thread == null) {
10780                return;
10781            }
10782            long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
10783            Iterator<ServiceRecord> it = proc.executingServices.iterator();
10784            ServiceRecord timeout = null;
10785            long nextTime = 0;
10786            while (it.hasNext()) {
10787                ServiceRecord sr = it.next();
10788                if (sr.executingStart < maxTime) {
10789                    timeout = sr;
10790                    break;
10791                }
10792                if (sr.executingStart > nextTime) {
10793                    nextTime = sr.executingStart;
10794                }
10795            }
10796            if (timeout != null && mLruProcesses.contains(proc)) {
10797                Slog.w(TAG, "Timeout executing service: " + timeout);
10798                anrMessage = "Executing service " + timeout.shortName;
10799            } else {
10800                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10801                msg.obj = proc;
10802                mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
10803            }
10804        }
10805
10806        if (anrMessage != null) {
10807            appNotResponding(proc, null, null, anrMessage);
10808        }
10809    }
10810
10811    // =========================================================
10812    // BACKUP AND RESTORE
10813    // =========================================================
10814
10815    // Cause the target app to be launched if necessary and its backup agent
10816    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10817    // activity manager to announce its creation.
10818    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10819        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10820        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10821
10822        synchronized(this) {
10823            // !!! TODO: currently no check here that we're already bound
10824            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10825            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10826            synchronized (stats) {
10827                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10828            }
10829
10830            // Backup agent is now in use, its package can't be stopped.
10831            try {
10832                AppGlobals.getPackageManager().setPackageStoppedState(
10833                        app.packageName, false);
10834            } catch (RemoteException e) {
10835            } catch (IllegalArgumentException e) {
10836                Slog.w(TAG, "Failed trying to unstop package "
10837                        + app.packageName + ": " + e);
10838            }
10839
10840            BackupRecord r = new BackupRecord(ss, app, backupMode);
10841            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10842                    ? new ComponentName(app.packageName, app.backupAgentName)
10843                    : new ComponentName("android", "FullBackupAgent");
10844            // startProcessLocked() returns existing proc's record if it's already running
10845            ProcessRecord proc = startProcessLocked(app.processName, app,
10846                    false, 0, "backup", hostingName, false);
10847            if (proc == null) {
10848                Slog.e(TAG, "Unable to start backup agent process " + r);
10849                return false;
10850            }
10851
10852            r.app = proc;
10853            mBackupTarget = r;
10854            mBackupAppName = app.packageName;
10855
10856            // Try not to kill the process during backup
10857            updateOomAdjLocked(proc);
10858
10859            // If the process is already attached, schedule the creation of the backup agent now.
10860            // If it is not yet live, this will be done when it attaches to the framework.
10861            if (proc.thread != null) {
10862                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
10863                try {
10864                    proc.thread.scheduleCreateBackupAgent(app,
10865                            compatibilityInfoForPackageLocked(app), backupMode);
10866                } catch (RemoteException e) {
10867                    // Will time out on the backup manager side
10868                }
10869            } else {
10870                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
10871            }
10872            // Invariants: at this point, the target app process exists and the application
10873            // is either already running or in the process of coming up.  mBackupTarget and
10874            // mBackupAppName describe the app, so that when it binds back to the AM we
10875            // know that it's scheduled for a backup-agent operation.
10876        }
10877
10878        return true;
10879    }
10880
10881    // A backup agent has just come up
10882    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10883        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
10884                + " = " + agent);
10885
10886        synchronized(this) {
10887            if (!agentPackageName.equals(mBackupAppName)) {
10888                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10889                return;
10890            }
10891        }
10892
10893        long oldIdent = Binder.clearCallingIdentity();
10894        try {
10895            IBackupManager bm = IBackupManager.Stub.asInterface(
10896                    ServiceManager.getService(Context.BACKUP_SERVICE));
10897            bm.agentConnected(agentPackageName, agent);
10898        } catch (RemoteException e) {
10899            // can't happen; the backup manager service is local
10900        } catch (Exception e) {
10901            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10902            e.printStackTrace();
10903        } finally {
10904            Binder.restoreCallingIdentity(oldIdent);
10905        }
10906    }
10907
10908    // done with this agent
10909    public void unbindBackupAgent(ApplicationInfo appInfo) {
10910        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
10911        if (appInfo == null) {
10912            Slog.w(TAG, "unbind backup agent for null app");
10913            return;
10914        }
10915
10916        synchronized(this) {
10917            if (mBackupAppName == null) {
10918                Slog.w(TAG, "Unbinding backup agent with no active backup");
10919                return;
10920            }
10921
10922            if (!mBackupAppName.equals(appInfo.packageName)) {
10923                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
10924                return;
10925            }
10926
10927            ProcessRecord proc = mBackupTarget.app;
10928            mBackupTarget = null;
10929            mBackupAppName = null;
10930
10931            // Not backing this app up any more; reset its OOM adjustment
10932            updateOomAdjLocked(proc);
10933
10934            // If the app crashed during backup, 'thread' will be null here
10935            if (proc.thread != null) {
10936                try {
10937                    proc.thread.scheduleDestroyBackupAgent(appInfo,
10938                            compatibilityInfoForPackageLocked(appInfo));
10939                } catch (Exception e) {
10940                    Slog.e(TAG, "Exception when unbinding backup agent:");
10941                    e.printStackTrace();
10942                }
10943            }
10944        }
10945    }
10946    // =========================================================
10947    // BROADCASTS
10948    // =========================================================
10949
10950    private final List getStickiesLocked(String action, IntentFilter filter,
10951            List cur) {
10952        final ContentResolver resolver = mContext.getContentResolver();
10953        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10954        if (list == null) {
10955            return cur;
10956        }
10957        int N = list.size();
10958        for (int i=0; i<N; i++) {
10959            Intent intent = list.get(i);
10960            if (filter.match(resolver, intent, true, TAG) >= 0) {
10961                if (cur == null) {
10962                    cur = new ArrayList<Intent>();
10963                }
10964                cur.add(intent);
10965            }
10966        }
10967        return cur;
10968    }
10969
10970    private final void scheduleBroadcastsLocked() {
10971        if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
10972                + mBroadcastsScheduled);
10973
10974        if (mBroadcastsScheduled) {
10975            return;
10976        }
10977        mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
10978        mBroadcastsScheduled = true;
10979    }
10980
10981    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
10982            IIntentReceiver receiver, IntentFilter filter, String permission) {
10983        synchronized(this) {
10984            ProcessRecord callerApp = null;
10985            if (caller != null) {
10986                callerApp = getRecordForAppLocked(caller);
10987                if (callerApp == null) {
10988                    throw new SecurityException(
10989                            "Unable to find app for caller " + caller
10990                            + " (pid=" + Binder.getCallingPid()
10991                            + ") when registering receiver " + receiver);
10992                }
10993                if (callerApp.info.uid != Process.SYSTEM_UID &&
10994                        !callerApp.pkgList.contains(callerPackage)) {
10995                    throw new SecurityException("Given caller package " + callerPackage
10996                            + " is not running in process " + callerApp);
10997                }
10998            } else {
10999                callerPackage = null;
11000            }
11001
11002            List allSticky = null;
11003
11004            // Look for any matching sticky broadcasts...
11005            Iterator actions = filter.actionsIterator();
11006            if (actions != null) {
11007                while (actions.hasNext()) {
11008                    String action = (String)actions.next();
11009                    allSticky = getStickiesLocked(action, filter, allSticky);
11010                }
11011            } else {
11012                allSticky = getStickiesLocked(null, filter, allSticky);
11013            }
11014
11015            // The first sticky in the list is returned directly back to
11016            // the client.
11017            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11018
11019            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11020                    + ": " + sticky);
11021
11022            if (receiver == null) {
11023                return sticky;
11024            }
11025
11026            ReceiverList rl
11027                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11028            if (rl == null) {
11029                rl = new ReceiverList(this, callerApp,
11030                        Binder.getCallingPid(),
11031                        Binder.getCallingUid(), receiver);
11032                if (rl.app != null) {
11033                    rl.app.receivers.add(rl);
11034                } else {
11035                    try {
11036                        receiver.asBinder().linkToDeath(rl, 0);
11037                    } catch (RemoteException e) {
11038                        return sticky;
11039                    }
11040                    rl.linkedToDeath = true;
11041                }
11042                mRegisteredReceivers.put(receiver.asBinder(), rl);
11043            }
11044            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
11045            rl.add(bf);
11046            if (!bf.debugCheck()) {
11047                Slog.w(TAG, "==> For Dynamic broadast");
11048            }
11049            mReceiverResolver.addFilter(bf);
11050
11051            // Enqueue broadcasts for all existing stickies that match
11052            // this filter.
11053            if (allSticky != null) {
11054                ArrayList receivers = new ArrayList();
11055                receivers.add(bf);
11056
11057                int N = allSticky.size();
11058                for (int i=0; i<N; i++) {
11059                    Intent intent = (Intent)allSticky.get(i);
11060                    BroadcastRecord r = new BroadcastRecord(intent, null,
11061                            null, -1, -1, null, receivers, null, 0, null, null,
11062                            false, true, true);
11063                    if (mParallelBroadcasts.size() == 0) {
11064                        scheduleBroadcastsLocked();
11065                    }
11066                    mParallelBroadcasts.add(r);
11067                }
11068            }
11069
11070            return sticky;
11071        }
11072    }
11073
11074    public void unregisterReceiver(IIntentReceiver receiver) {
11075        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11076
11077        boolean doNext = false;
11078
11079        synchronized(this) {
11080            ReceiverList rl
11081                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11082            if (rl != null) {
11083                if (rl.curBroadcast != null) {
11084                    BroadcastRecord r = rl.curBroadcast;
11085                    doNext = finishReceiverLocked(
11086                        receiver.asBinder(), r.resultCode, r.resultData,
11087                        r.resultExtras, r.resultAbort, true);
11088                }
11089
11090                if (rl.app != null) {
11091                    rl.app.receivers.remove(rl);
11092                }
11093                removeReceiverLocked(rl);
11094                if (rl.linkedToDeath) {
11095                    rl.linkedToDeath = false;
11096                    rl.receiver.asBinder().unlinkToDeath(rl, 0);
11097                }
11098            }
11099        }
11100
11101        if (!doNext) {
11102            return;
11103        }
11104
11105        final long origId = Binder.clearCallingIdentity();
11106        processNextBroadcast(false);
11107        trimApplications();
11108        Binder.restoreCallingIdentity(origId);
11109    }
11110
11111    void removeReceiverLocked(ReceiverList rl) {
11112        mRegisteredReceivers.remove(rl.receiver.asBinder());
11113        int N = rl.size();
11114        for (int i=0; i<N; i++) {
11115            mReceiverResolver.removeFilter(rl.get(i));
11116        }
11117    }
11118
11119    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11120        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11121            ProcessRecord r = mLruProcesses.get(i);
11122            if (r.thread != null) {
11123                try {
11124                    r.thread.dispatchPackageBroadcast(cmd, packages);
11125                } catch (RemoteException ex) {
11126                }
11127            }
11128        }
11129    }
11130
11131    private final int broadcastIntentLocked(ProcessRecord callerApp,
11132            String callerPackage, Intent intent, String resolvedType,
11133            IIntentReceiver resultTo, int resultCode, String resultData,
11134            Bundle map, String requiredPermission,
11135            boolean ordered, boolean sticky, int callingPid, int callingUid) {
11136        intent = new Intent(intent);
11137
11138        // By default broadcasts do not go to stopped apps.
11139        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11140
11141        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11142            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11143            + " ordered=" + ordered);
11144        if ((resultTo != null) && !ordered) {
11145            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11146        }
11147
11148        // Handle special intents: if this broadcast is from the package
11149        // manager about a package being removed, we need to remove all of
11150        // its activities from the history stack.
11151        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11152                intent.getAction());
11153        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11154                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11155                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11156                || uidRemoved) {
11157            if (checkComponentPermission(
11158                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11159                    callingPid, callingUid, -1, true)
11160                    == PackageManager.PERMISSION_GRANTED) {
11161                if (uidRemoved) {
11162                    final Bundle intentExtras = intent.getExtras();
11163                    final int uid = intentExtras != null
11164                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11165                    if (uid >= 0) {
11166                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11167                        synchronized (bs) {
11168                            bs.removeUidStatsLocked(uid);
11169                        }
11170                    }
11171                } else {
11172                    // If resources are unvailble just force stop all
11173                    // those packages and flush the attribute cache as well.
11174                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11175                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11176                        if (list != null && (list.length > 0)) {
11177                            for (String pkg : list) {
11178                                forceStopPackageLocked(pkg, -1, false, true, true);
11179                            }
11180                            sendPackageBroadcastLocked(
11181                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
11182                        }
11183                    } else {
11184                        Uri data = intent.getData();
11185                        String ssp;
11186                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11187                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11188                                forceStopPackageLocked(ssp,
11189                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
11190                            }
11191                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11192                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11193                                        new String[] {ssp});
11194                            }
11195                        }
11196                    }
11197                }
11198            } else {
11199                String msg = "Permission Denial: " + intent.getAction()
11200                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11201                        + ", uid=" + callingUid + ")"
11202                        + " requires "
11203                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11204                Slog.w(TAG, msg);
11205                throw new SecurityException(msg);
11206            }
11207
11208        // Special case for adding a package: by default turn on compatibility
11209        // mode.
11210        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11211            Uri data = intent.getData();
11212            String ssp;
11213            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11214                mCompatModePackages.handlePackageAddedLocked(ssp,
11215                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11216            }
11217        }
11218
11219        /*
11220         * If this is the time zone changed action, queue up a message that will reset the timezone
11221         * of all currently running processes. This message will get queued up before the broadcast
11222         * happens.
11223         */
11224        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11225            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11226        }
11227
11228        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11229            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11230        }
11231
11232        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11233            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11234            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11235        }
11236
11237        /*
11238         * Prevent non-system code (defined here to be non-persistent
11239         * processes) from sending protected broadcasts.
11240         */
11241        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11242                || callingUid == Process.SHELL_UID || callingUid == 0) {
11243            // Always okay.
11244        } else if (callerApp == null || !callerApp.persistent) {
11245            try {
11246                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11247                        intent.getAction())) {
11248                    String msg = "Permission Denial: not allowed to send broadcast "
11249                            + intent.getAction() + " from pid="
11250                            + callingPid + ", uid=" + callingUid;
11251                    Slog.w(TAG, msg);
11252                    throw new SecurityException(msg);
11253                }
11254            } catch (RemoteException e) {
11255                Slog.w(TAG, "Remote exception", e);
11256                return BROADCAST_SUCCESS;
11257            }
11258        }
11259
11260        // Add to the sticky list if requested.
11261        if (sticky) {
11262            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11263                    callingPid, callingUid)
11264                    != PackageManager.PERMISSION_GRANTED) {
11265                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11266                        + callingPid + ", uid=" + callingUid
11267                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11268                Slog.w(TAG, msg);
11269                throw new SecurityException(msg);
11270            }
11271            if (requiredPermission != null) {
11272                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11273                        + " and enforce permission " + requiredPermission);
11274                return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11275            }
11276            if (intent.getComponent() != null) {
11277                throw new SecurityException(
11278                        "Sticky broadcasts can't target a specific component");
11279            }
11280            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11281            if (list == null) {
11282                list = new ArrayList<Intent>();
11283                mStickyBroadcasts.put(intent.getAction(), list);
11284            }
11285            int N = list.size();
11286            int i;
11287            for (i=0; i<N; i++) {
11288                if (intent.filterEquals(list.get(i))) {
11289                    // This sticky already exists, replace it.
11290                    list.set(i, new Intent(intent));
11291                    break;
11292                }
11293            }
11294            if (i >= N) {
11295                list.add(new Intent(intent));
11296            }
11297        }
11298
11299        // Figure out who all will receive this broadcast.
11300        List receivers = null;
11301        List<BroadcastFilter> registeredReceivers = null;
11302        try {
11303            if (intent.getComponent() != null) {
11304                // Broadcast is going to one specific receiver class...
11305                ActivityInfo ai = AppGlobals.getPackageManager().
11306                    getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
11307                if (ai != null) {
11308                    receivers = new ArrayList();
11309                    ResolveInfo ri = new ResolveInfo();
11310                    ri.activityInfo = ai;
11311                    receivers.add(ri);
11312                }
11313            } else {
11314                // Need to resolve the intent to interested receivers...
11315                if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11316                         == 0) {
11317                    receivers =
11318                        AppGlobals.getPackageManager().queryIntentReceivers(
11319                                intent, resolvedType, STOCK_PM_FLAGS);
11320                }
11321                registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
11322            }
11323        } catch (RemoteException ex) {
11324            // pm is in same process, this will never happen.
11325        }
11326
11327        final boolean replacePending =
11328                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11329
11330        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11331                + " replacePending=" + replacePending);
11332
11333        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11334        if (!ordered && NR > 0) {
11335            // If we are not serializing this broadcast, then send the
11336            // registered receivers separately so they don't wait for the
11337            // components to be launched.
11338            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11339                    callerPackage, callingPid, callingUid, requiredPermission,
11340                    registeredReceivers, resultTo, resultCode, resultData, map,
11341                    ordered, sticky, false);
11342            if (DEBUG_BROADCAST) Slog.v(
11343                    TAG, "Enqueueing parallel broadcast " + r
11344                    + ": prev had " + mParallelBroadcasts.size());
11345            boolean replaced = false;
11346            if (replacePending) {
11347                for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11348                    if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
11349                        if (DEBUG_BROADCAST) Slog.v(TAG,
11350                                "***** DROPPING PARALLEL: " + intent);
11351                        mParallelBroadcasts.set(i, r);
11352                        replaced = true;
11353                        break;
11354                    }
11355                }
11356            }
11357            if (!replaced) {
11358                mParallelBroadcasts.add(r);
11359                scheduleBroadcastsLocked();
11360            }
11361            registeredReceivers = null;
11362            NR = 0;
11363        }
11364
11365        // Merge into one list.
11366        int ir = 0;
11367        if (receivers != null) {
11368            // A special case for PACKAGE_ADDED: do not allow the package
11369            // being added to see this broadcast.  This prevents them from
11370            // using this as a back door to get run as soon as they are
11371            // installed.  Maybe in the future we want to have a special install
11372            // broadcast or such for apps, but we'd like to deliberately make
11373            // this decision.
11374            String skipPackages[] = null;
11375            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11376                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11377                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11378                Uri data = intent.getData();
11379                if (data != null) {
11380                    String pkgName = data.getSchemeSpecificPart();
11381                    if (pkgName != null) {
11382                        skipPackages = new String[] { pkgName };
11383                    }
11384                }
11385            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11386                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11387            }
11388            if (skipPackages != null && (skipPackages.length > 0)) {
11389                for (String skipPackage : skipPackages) {
11390                    if (skipPackage != null) {
11391                        int NT = receivers.size();
11392                        for (int it=0; it<NT; it++) {
11393                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11394                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11395                                receivers.remove(it);
11396                                it--;
11397                                NT--;
11398                            }
11399                        }
11400                    }
11401                }
11402            }
11403
11404            int NT = receivers != null ? receivers.size() : 0;
11405            int it = 0;
11406            ResolveInfo curt = null;
11407            BroadcastFilter curr = null;
11408            while (it < NT && ir < NR) {
11409                if (curt == null) {
11410                    curt = (ResolveInfo)receivers.get(it);
11411                }
11412                if (curr == null) {
11413                    curr = registeredReceivers.get(ir);
11414                }
11415                if (curr.getPriority() >= curt.priority) {
11416                    // Insert this broadcast record into the final list.
11417                    receivers.add(it, curr);
11418                    ir++;
11419                    curr = null;
11420                    it++;
11421                    NT++;
11422                } else {
11423                    // Skip to the next ResolveInfo in the final list.
11424                    it++;
11425                    curt = null;
11426                }
11427            }
11428        }
11429        while (ir < NR) {
11430            if (receivers == null) {
11431                receivers = new ArrayList();
11432            }
11433            receivers.add(registeredReceivers.get(ir));
11434            ir++;
11435        }
11436
11437        if ((receivers != null && receivers.size() > 0)
11438                || resultTo != null) {
11439            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11440                    callerPackage, callingPid, callingUid, requiredPermission,
11441                    receivers, resultTo, resultCode, resultData, map, ordered,
11442                    sticky, false);
11443            if (DEBUG_BROADCAST) Slog.v(
11444                    TAG, "Enqueueing ordered broadcast " + r
11445                    + ": prev had " + mOrderedBroadcasts.size());
11446            if (DEBUG_BROADCAST) {
11447                int seq = r.intent.getIntExtra("seq", -1);
11448                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11449            }
11450            boolean replaced = false;
11451            if (replacePending) {
11452                for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
11453                    if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
11454                        if (DEBUG_BROADCAST) Slog.v(TAG,
11455                                "***** DROPPING ORDERED: " + intent);
11456                        mOrderedBroadcasts.set(i, r);
11457                        replaced = true;
11458                        break;
11459                    }
11460                }
11461            }
11462            if (!replaced) {
11463                mOrderedBroadcasts.add(r);
11464                scheduleBroadcastsLocked();
11465            }
11466        }
11467
11468        return BROADCAST_SUCCESS;
11469    }
11470
11471    final Intent verifyBroadcastLocked(Intent intent) {
11472        // Refuse possible leaked file descriptors
11473        if (intent != null && intent.hasFileDescriptors() == true) {
11474            throw new IllegalArgumentException("File descriptors passed in Intent");
11475        }
11476
11477        int flags = intent.getFlags();
11478
11479        if (!mProcessesReady) {
11480            // if the caller really truly claims to know what they're doing, go
11481            // ahead and allow the broadcast without launching any receivers
11482            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11483                intent = new Intent(intent);
11484                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11485            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11486                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11487                        + " before boot completion");
11488                throw new IllegalStateException("Cannot broadcast before boot completed");
11489            }
11490        }
11491
11492        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11493            throw new IllegalArgumentException(
11494                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11495        }
11496
11497        return intent;
11498    }
11499
11500    public final int broadcastIntent(IApplicationThread caller,
11501            Intent intent, String resolvedType, IIntentReceiver resultTo,
11502            int resultCode, String resultData, Bundle map,
11503            String requiredPermission, boolean serialized, boolean sticky) {
11504        synchronized(this) {
11505            intent = verifyBroadcastLocked(intent);
11506
11507            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11508            final int callingPid = Binder.getCallingPid();
11509            final int callingUid = Binder.getCallingUid();
11510            final long origId = Binder.clearCallingIdentity();
11511            int res = broadcastIntentLocked(callerApp,
11512                    callerApp != null ? callerApp.info.packageName : null,
11513                    intent, resolvedType, resultTo,
11514                    resultCode, resultData, map, requiredPermission, serialized,
11515                    sticky, callingPid, callingUid);
11516            Binder.restoreCallingIdentity(origId);
11517            return res;
11518        }
11519    }
11520
11521    int broadcastIntentInPackage(String packageName, int uid,
11522            Intent intent, String resolvedType, IIntentReceiver resultTo,
11523            int resultCode, String resultData, Bundle map,
11524            String requiredPermission, boolean serialized, boolean sticky) {
11525        synchronized(this) {
11526            intent = verifyBroadcastLocked(intent);
11527
11528            final long origId = Binder.clearCallingIdentity();
11529            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11530                    resultTo, resultCode, resultData, map, requiredPermission,
11531                    serialized, sticky, -1, uid);
11532            Binder.restoreCallingIdentity(origId);
11533            return res;
11534        }
11535    }
11536
11537    public final void unbroadcastIntent(IApplicationThread caller,
11538            Intent intent) {
11539        // Refuse possible leaked file descriptors
11540        if (intent != null && intent.hasFileDescriptors() == true) {
11541            throw new IllegalArgumentException("File descriptors passed in Intent");
11542        }
11543
11544        synchronized(this) {
11545            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11546                    != PackageManager.PERMISSION_GRANTED) {
11547                String msg = "Permission Denial: unbroadcastIntent() from pid="
11548                        + Binder.getCallingPid()
11549                        + ", uid=" + Binder.getCallingUid()
11550                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11551                Slog.w(TAG, msg);
11552                throw new SecurityException(msg);
11553            }
11554            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11555            if (list != null) {
11556                int N = list.size();
11557                int i;
11558                for (i=0; i<N; i++) {
11559                    if (intent.filterEquals(list.get(i))) {
11560                        list.remove(i);
11561                        break;
11562                    }
11563                }
11564            }
11565        }
11566    }
11567
11568    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11569            String resultData, Bundle resultExtras, boolean resultAbort,
11570            boolean explicit) {
11571        if (mOrderedBroadcasts.size() == 0) {
11572            if (explicit) {
11573                Slog.w(TAG, "finishReceiver called but no pending broadcasts");
11574            }
11575            return false;
11576        }
11577        BroadcastRecord r = mOrderedBroadcasts.get(0);
11578        if (r.receiver == null) {
11579            if (explicit) {
11580                Slog.w(TAG, "finishReceiver called but none active");
11581            }
11582            return false;
11583        }
11584        if (r.receiver != receiver) {
11585            Slog.w(TAG, "finishReceiver called but active receiver is different");
11586            return false;
11587        }
11588        int state = r.state;
11589        r.state = r.IDLE;
11590        if (state == r.IDLE) {
11591            if (explicit) {
11592                Slog.w(TAG, "finishReceiver called but state is IDLE");
11593            }
11594        }
11595        r.receiver = null;
11596        r.intent.setComponent(null);
11597        if (r.curApp != null) {
11598            r.curApp.curReceiver = null;
11599        }
11600        if (r.curFilter != null) {
11601            r.curFilter.receiverList.curBroadcast = null;
11602        }
11603        r.curFilter = null;
11604        r.curApp = null;
11605        r.curComponent = null;
11606        r.curReceiver = null;
11607        mPendingBroadcast = null;
11608
11609        r.resultCode = resultCode;
11610        r.resultData = resultData;
11611        r.resultExtras = resultExtras;
11612        r.resultAbort = resultAbort;
11613
11614        // We will process the next receiver right now if this is finishing
11615        // an app receiver (which is always asynchronous) or after we have
11616        // come back from calling a receiver.
11617        return state == BroadcastRecord.APP_RECEIVE
11618                || state == BroadcastRecord.CALL_DONE_RECEIVE;
11619    }
11620
11621    public void finishReceiver(IBinder who, int resultCode, String resultData,
11622            Bundle resultExtras, boolean resultAbort) {
11623        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11624
11625        // Refuse possible leaked file descriptors
11626        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11627            throw new IllegalArgumentException("File descriptors passed in Bundle");
11628        }
11629
11630        boolean doNext;
11631
11632        final long origId = Binder.clearCallingIdentity();
11633
11634        synchronized(this) {
11635            doNext = finishReceiverLocked(
11636                who, resultCode, resultData, resultExtras, resultAbort, true);
11637        }
11638
11639        if (doNext) {
11640            processNextBroadcast(false);
11641        }
11642        trimApplications();
11643
11644        Binder.restoreCallingIdentity(origId);
11645    }
11646
11647    private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
11648        if (r.nextReceiver > 0) {
11649            Object curReceiver = r.receivers.get(r.nextReceiver-1);
11650            if (curReceiver instanceof BroadcastFilter) {
11651                BroadcastFilter bf = (BroadcastFilter) curReceiver;
11652                EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
11653                        System.identityHashCode(r),
11654                        r.intent.getAction(),
11655                        r.nextReceiver - 1,
11656                        System.identityHashCode(bf));
11657            } else {
11658                EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
11659                        System.identityHashCode(r),
11660                        r.intent.getAction(),
11661                        r.nextReceiver - 1,
11662                        ((ResolveInfo)curReceiver).toString());
11663            }
11664        } else {
11665            Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
11666                    + r);
11667            EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
11668                    System.identityHashCode(r),
11669                    r.intent.getAction(),
11670                    r.nextReceiver,
11671                    "NONE");
11672        }
11673    }
11674
11675    private final void setBroadcastTimeoutLocked(long timeoutTime) {
11676        if (! mPendingBroadcastTimeoutMessage) {
11677            Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11678            mHandler.sendMessageAtTime(msg, timeoutTime);
11679            mPendingBroadcastTimeoutMessage = true;
11680        }
11681    }
11682
11683    private final void cancelBroadcastTimeoutLocked() {
11684        if (mPendingBroadcastTimeoutMessage) {
11685            mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11686            mPendingBroadcastTimeoutMessage = false;
11687        }
11688    }
11689
11690    private final void broadcastTimeoutLocked(boolean fromMsg) {
11691        if (fromMsg) {
11692            mPendingBroadcastTimeoutMessage = false;
11693        }
11694
11695        if (mOrderedBroadcasts.size() == 0) {
11696            return;
11697        }
11698
11699        long now = SystemClock.uptimeMillis();
11700        BroadcastRecord r = mOrderedBroadcasts.get(0);
11701        if (fromMsg) {
11702            if (mDidDexOpt) {
11703                // Delay timeouts until dexopt finishes.
11704                mDidDexOpt = false;
11705                long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11706                setBroadcastTimeoutLocked(timeoutTime);
11707                return;
11708            }
11709            if (! mProcessesReady) {
11710                // Only process broadcast timeouts if the system is ready. That way
11711                // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11712                // to do heavy lifting for system up.
11713                return;
11714            }
11715
11716            long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11717            if (timeoutTime > now) {
11718                // We can observe premature timeouts because we do not cancel and reset the
11719                // broadcast timeout message after each receiver finishes.  Instead, we set up
11720                // an initial timeout then kick it down the road a little further as needed
11721                // when it expires.
11722                if (DEBUG_BROADCAST) Slog.v(TAG,
11723                        "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11724                        + timeoutTime);
11725                setBroadcastTimeoutLocked(timeoutTime);
11726                return;
11727            }
11728        }
11729
11730        Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11731                + ", started " + (now - r.receiverTime) + "ms ago");
11732        r.receiverTime = now;
11733        r.anrCount++;
11734
11735        // Current receiver has passed its expiration date.
11736        if (r.nextReceiver <= 0) {
11737            Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11738            return;
11739        }
11740
11741        ProcessRecord app = null;
11742        String anrMessage = null;
11743
11744        Object curReceiver = r.receivers.get(r.nextReceiver-1);
11745        Slog.w(TAG, "Receiver during timeout: " + curReceiver);
11746        logBroadcastReceiverDiscardLocked(r);
11747        if (curReceiver instanceof BroadcastFilter) {
11748            BroadcastFilter bf = (BroadcastFilter)curReceiver;
11749            if (bf.receiverList.pid != 0
11750                    && bf.receiverList.pid != MY_PID) {
11751                synchronized (this.mPidsSelfLocked) {
11752                    app = this.mPidsSelfLocked.get(
11753                            bf.receiverList.pid);
11754                }
11755            }
11756        } else {
11757            app = r.curApp;
11758        }
11759
11760        if (app != null) {
11761            anrMessage = "Broadcast of " + r.intent.toString();
11762        }
11763
11764        if (mPendingBroadcast == r) {
11765            mPendingBroadcast = null;
11766        }
11767
11768        // Move on to the next receiver.
11769        finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11770                r.resultExtras, r.resultAbort, true);
11771        scheduleBroadcastsLocked();
11772
11773        if (anrMessage != null) {
11774            // Post the ANR to the handler since we do not want to process ANRs while
11775            // potentially holding our lock.
11776            mHandler.post(new AppNotResponding(app, anrMessage));
11777        }
11778    }
11779
11780    private final void processCurBroadcastLocked(BroadcastRecord r,
11781            ProcessRecord app) throws RemoteException {
11782        if (DEBUG_BROADCAST)  Slog.v(TAG,
11783                "Process cur broadcast " + r + " for app " + app);
11784        if (app.thread == null) {
11785            throw new RemoteException();
11786        }
11787        r.receiver = app.thread.asBinder();
11788        r.curApp = app;
11789        app.curReceiver = r;
11790        updateLruProcessLocked(app, true, true);
11791
11792        // Tell the application to launch this receiver.
11793        r.intent.setComponent(r.curComponent);
11794
11795        boolean started = false;
11796        try {
11797            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
11798                    "Delivering to component " + r.curComponent
11799                    + ": " + r);
11800            ensurePackageDexOpt(r.intent.getComponent().getPackageName());
11801            app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
11802                    compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
11803                    r.resultCode, r.resultData, r.resultExtras, r.ordered);
11804            if (DEBUG_BROADCAST)  Slog.v(TAG,
11805                    "Process cur broadcast " + r + " DELIVERED for app " + app);
11806            started = true;
11807        } finally {
11808            if (!started) {
11809                if (DEBUG_BROADCAST)  Slog.v(TAG,
11810                        "Process cur broadcast " + r + ": NOT STARTED!");
11811                r.receiver = null;
11812                r.curApp = null;
11813                app.curReceiver = null;
11814            }
11815        }
11816
11817    }
11818
11819    static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
11820            Intent intent, int resultCode, String data, Bundle extras,
11821            boolean ordered, boolean sticky) throws RemoteException {
11822        // Send the intent to the receiver asynchronously using one-way binder calls.
11823        if (app != null && app.thread != null) {
11824            // If we have an app thread, do the call through that so it is
11825            // correctly ordered with other one-way calls.
11826            app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
11827                    data, extras, ordered, sticky);
11828        } else {
11829            receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
11830        }
11831    }
11832
11833    private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
11834            BroadcastFilter filter, boolean ordered) {
11835        boolean skip = false;
11836        if (filter.requiredPermission != null) {
11837            int perm = checkComponentPermission(filter.requiredPermission,
11838                    r.callingPid, r.callingUid, -1, true);
11839            if (perm != PackageManager.PERMISSION_GRANTED) {
11840                Slog.w(TAG, "Permission Denial: broadcasting "
11841                        + r.intent.toString()
11842                        + " from " + r.callerPackage + " (pid="
11843                        + r.callingPid + ", uid=" + r.callingUid + ")"
11844                        + " requires " + filter.requiredPermission
11845                        + " due to registered receiver " + filter);
11846                skip = true;
11847            }
11848        }
11849        if (r.requiredPermission != null) {
11850            int perm = checkComponentPermission(r.requiredPermission,
11851                    filter.receiverList.pid, filter.receiverList.uid, -1, true);
11852            if (perm != PackageManager.PERMISSION_GRANTED) {
11853                Slog.w(TAG, "Permission Denial: receiving "
11854                        + r.intent.toString()
11855                        + " to " + filter.receiverList.app
11856                        + " (pid=" + filter.receiverList.pid
11857                        + ", uid=" + filter.receiverList.uid + ")"
11858                        + " requires " + r.requiredPermission
11859                        + " due to sender " + r.callerPackage
11860                        + " (uid " + r.callingUid + ")");
11861                skip = true;
11862            }
11863        }
11864
11865        if (!skip) {
11866            // If this is not being sent as an ordered broadcast, then we
11867            // don't want to touch the fields that keep track of the current
11868            // state of ordered broadcasts.
11869            if (ordered) {
11870                r.receiver = filter.receiverList.receiver.asBinder();
11871                r.curFilter = filter;
11872                filter.receiverList.curBroadcast = r;
11873                r.state = BroadcastRecord.CALL_IN_RECEIVE;
11874                if (filter.receiverList.app != null) {
11875                    // Bump hosting application to no longer be in background
11876                    // scheduling class.  Note that we can't do that if there
11877                    // isn't an app...  but we can only be in that case for
11878                    // things that directly call the IActivityManager API, which
11879                    // are already core system stuff so don't matter for this.
11880                    r.curApp = filter.receiverList.app;
11881                    filter.receiverList.app.curReceiver = r;
11882                    updateOomAdjLocked();
11883                }
11884            }
11885            try {
11886                if (DEBUG_BROADCAST_LIGHT) {
11887                    int seq = r.intent.getIntExtra("seq", -1);
11888                    Slog.i(TAG, "Delivering to " + filter
11889                            + " (seq=" + seq + "): " + r);
11890                }
11891                performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
11892                    new Intent(r.intent), r.resultCode,
11893                    r.resultData, r.resultExtras, r.ordered, r.initialSticky);
11894                if (ordered) {
11895                    r.state = BroadcastRecord.CALL_DONE_RECEIVE;
11896                }
11897            } catch (RemoteException e) {
11898                Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
11899                if (ordered) {
11900                    r.receiver = null;
11901                    r.curFilter = null;
11902                    filter.receiverList.curBroadcast = null;
11903                    if (filter.receiverList.app != null) {
11904                        filter.receiverList.app.curReceiver = null;
11905                    }
11906                }
11907            }
11908        }
11909    }
11910
11911    private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
11912        if (r.callingUid < 0) {
11913            // This was from a registerReceiver() call; ignore it.
11914            return;
11915        }
11916        System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
11917                MAX_BROADCAST_HISTORY-1);
11918        r.finishTime = SystemClock.uptimeMillis();
11919        mBroadcastHistory[0] = r;
11920    }
11921
11922    private final void processNextBroadcast(boolean fromMsg) {
11923        synchronized(this) {
11924            BroadcastRecord r;
11925
11926            if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
11927                    + mParallelBroadcasts.size() + " broadcasts, "
11928                    + mOrderedBroadcasts.size() + " ordered broadcasts");
11929
11930            updateCpuStats();
11931
11932            if (fromMsg) {
11933                mBroadcastsScheduled = false;
11934            }
11935
11936            // First, deliver any non-serialized broadcasts right away.
11937            while (mParallelBroadcasts.size() > 0) {
11938                r = mParallelBroadcasts.remove(0);
11939                r.dispatchTime = SystemClock.uptimeMillis();
11940                final int N = r.receivers.size();
11941                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
11942                        + r);
11943                for (int i=0; i<N; i++) {
11944                    Object target = r.receivers.get(i);
11945                    if (DEBUG_BROADCAST)  Slog.v(TAG,
11946                            "Delivering non-ordered to registered "
11947                            + target + ": " + r);
11948                    deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
11949                }
11950                addBroadcastToHistoryLocked(r);
11951                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
11952                        + r);
11953            }
11954
11955            // Now take care of the next serialized one...
11956
11957            // If we are waiting for a process to come up to handle the next
11958            // broadcast, then do nothing at this point.  Just in case, we
11959            // check that the process we're waiting for still exists.
11960            if (mPendingBroadcast != null) {
11961                if (DEBUG_BROADCAST_LIGHT) {
11962                    Slog.v(TAG, "processNextBroadcast: waiting for "
11963                            + mPendingBroadcast.curApp);
11964                }
11965
11966                boolean isDead;
11967                synchronized (mPidsSelfLocked) {
11968                    isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
11969                }
11970                if (!isDead) {
11971                    // It's still alive, so keep waiting
11972                    return;
11973                } else {
11974                    Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
11975                            + " died before responding to broadcast");
11976                    mPendingBroadcast.state = BroadcastRecord.IDLE;
11977                    mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
11978                    mPendingBroadcast = null;
11979                }
11980            }
11981
11982            boolean looped = false;
11983
11984            do {
11985                if (mOrderedBroadcasts.size() == 0) {
11986                    // No more broadcasts pending, so all done!
11987                    scheduleAppGcsLocked();
11988                    if (looped) {
11989                        // If we had finished the last ordered broadcast, then
11990                        // make sure all processes have correct oom and sched
11991                        // adjustments.
11992                        updateOomAdjLocked();
11993                    }
11994                    return;
11995                }
11996                r = mOrderedBroadcasts.get(0);
11997                boolean forceReceive = false;
11998
11999                // Ensure that even if something goes awry with the timeout
12000                // detection, we catch "hung" broadcasts here, discard them,
12001                // and continue to make progress.
12002                //
12003                // This is only done if the system is ready so that PRE_BOOT_COMPLETED
12004                // receivers don't get executed with timeouts. They're intended for
12005                // one time heavy lifting after system upgrades and can take
12006                // significant amounts of time.
12007                int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
12008                if (mProcessesReady && r.dispatchTime > 0) {
12009                    long now = SystemClock.uptimeMillis();
12010                    if ((numReceivers > 0) &&
12011                            (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
12012                        Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
12013                                + " now=" + now
12014                                + " dispatchTime=" + r.dispatchTime
12015                                + " startTime=" + r.receiverTime
12016                                + " intent=" + r.intent
12017                                + " numReceivers=" + numReceivers
12018                                + " nextReceiver=" + r.nextReceiver
12019                                + " state=" + r.state);
12020                        broadcastTimeoutLocked(false); // forcibly finish this broadcast
12021                        forceReceive = true;
12022                        r.state = BroadcastRecord.IDLE;
12023                    }
12024                }
12025
12026                if (r.state != BroadcastRecord.IDLE) {
12027                    if (DEBUG_BROADCAST) Slog.d(TAG,
12028                            "processNextBroadcast() called when not idle (state="
12029                            + r.state + ")");
12030                    return;
12031                }
12032
12033                if (r.receivers == null || r.nextReceiver >= numReceivers
12034                        || r.resultAbort || forceReceive) {
12035                    // No more receivers for this broadcast!  Send the final
12036                    // result if requested...
12037                    if (r.resultTo != null) {
12038                        try {
12039                            if (DEBUG_BROADCAST) {
12040                                int seq = r.intent.getIntExtra("seq", -1);
12041                                Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
12042                                        + " seq=" + seq + " app=" + r.callerApp);
12043                            }
12044                            performReceiveLocked(r.callerApp, r.resultTo,
12045                                new Intent(r.intent), r.resultCode,
12046                                r.resultData, r.resultExtras, false, false);
12047                            // Set this to null so that the reference
12048                            // (local and remote) isnt kept in the mBroadcastHistory.
12049                            r.resultTo = null;
12050                        } catch (RemoteException e) {
12051                            Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
12052                        }
12053                    }
12054
12055                    if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
12056                    cancelBroadcastTimeoutLocked();
12057
12058                    if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
12059                            + r);
12060
12061                    // ... and on to the next...
12062                    addBroadcastToHistoryLocked(r);
12063                    mOrderedBroadcasts.remove(0);
12064                    r = null;
12065                    looped = true;
12066                    continue;
12067                }
12068            } while (r == null);
12069
12070            // Get the next receiver...
12071            int recIdx = r.nextReceiver++;
12072
12073            // Keep track of when this receiver started, and make sure there
12074            // is a timeout message pending to kill it if need be.
12075            r.receiverTime = SystemClock.uptimeMillis();
12076            if (recIdx == 0) {
12077                r.dispatchTime = r.receiverTime;
12078
12079                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
12080                        + r);
12081            }
12082            if (! mPendingBroadcastTimeoutMessage) {
12083                long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12084                if (DEBUG_BROADCAST) Slog.v(TAG,
12085                        "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12086                setBroadcastTimeoutLocked(timeoutTime);
12087            }
12088
12089            Object nextReceiver = r.receivers.get(recIdx);
12090            if (nextReceiver instanceof BroadcastFilter) {
12091                // Simple case: this is a registered receiver who gets
12092                // a direct call.
12093                BroadcastFilter filter = (BroadcastFilter)nextReceiver;
12094                if (DEBUG_BROADCAST)  Slog.v(TAG,
12095                        "Delivering ordered to registered "
12096                        + filter + ": " + r);
12097                deliverToRegisteredReceiverLocked(r, filter, r.ordered);
12098                if (r.receiver == null || !r.ordered) {
12099                    // The receiver has already finished, so schedule to
12100                    // process the next one.
12101                    if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12102                            + r.ordered + " receiver=" + r.receiver);
12103                    r.state = BroadcastRecord.IDLE;
12104                    scheduleBroadcastsLocked();
12105                }
12106                return;
12107            }
12108
12109            // Hard case: need to instantiate the receiver, possibly
12110            // starting its application process to host it.
12111
12112            ResolveInfo info =
12113                (ResolveInfo)nextReceiver;
12114
12115            boolean skip = false;
12116            int perm = checkComponentPermission(info.activityInfo.permission,
12117                    r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12118                    info.activityInfo.exported);
12119            if (perm != PackageManager.PERMISSION_GRANTED) {
12120                if (!info.activityInfo.exported) {
12121                    Slog.w(TAG, "Permission Denial: broadcasting "
12122                            + r.intent.toString()
12123                            + " from " + r.callerPackage + " (pid=" + r.callingPid
12124                            + ", uid=" + r.callingUid + ")"
12125                            + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12126                            + " due to receiver " + info.activityInfo.packageName
12127                            + "/" + info.activityInfo.name);
12128                } else {
12129                    Slog.w(TAG, "Permission Denial: broadcasting "
12130                            + r.intent.toString()
12131                            + " from " + r.callerPackage + " (pid=" + r.callingPid
12132                            + ", uid=" + r.callingUid + ")"
12133                            + " requires " + info.activityInfo.permission
12134                            + " due to receiver " + info.activityInfo.packageName
12135                            + "/" + info.activityInfo.name);
12136                }
12137                skip = true;
12138            }
12139            if (r.callingUid != Process.SYSTEM_UID &&
12140                r.requiredPermission != null) {
12141                try {
12142                    perm = AppGlobals.getPackageManager().
12143                            checkPermission(r.requiredPermission,
12144                                    info.activityInfo.applicationInfo.packageName);
12145                } catch (RemoteException e) {
12146                    perm = PackageManager.PERMISSION_DENIED;
12147                }
12148                if (perm != PackageManager.PERMISSION_GRANTED) {
12149                    Slog.w(TAG, "Permission Denial: receiving "
12150                            + r.intent + " to "
12151                            + info.activityInfo.applicationInfo.packageName
12152                            + " requires " + r.requiredPermission
12153                            + " due to sender " + r.callerPackage
12154                            + " (uid " + r.callingUid + ")");
12155                    skip = true;
12156                }
12157            }
12158            if (r.curApp != null && r.curApp.crashing) {
12159                // If the target process is crashing, just skip it.
12160                if (DEBUG_BROADCAST)  Slog.v(TAG,
12161                        "Skipping deliver ordered " + r + " to " + r.curApp
12162                        + ": process crashing");
12163                skip = true;
12164            }
12165
12166            if (skip) {
12167                if (DEBUG_BROADCAST)  Slog.v(TAG,
12168                        "Skipping delivery of ordered " + r + " for whatever reason");
12169                r.receiver = null;
12170                r.curFilter = null;
12171                r.state = BroadcastRecord.IDLE;
12172                scheduleBroadcastsLocked();
12173                return;
12174            }
12175
12176            r.state = BroadcastRecord.APP_RECEIVE;
12177            String targetProcess = info.activityInfo.processName;
12178            r.curComponent = new ComponentName(
12179                    info.activityInfo.applicationInfo.packageName,
12180                    info.activityInfo.name);
12181            r.curReceiver = info.activityInfo;
12182
12183            // Broadcast is being executed, its package can't be stopped.
12184            try {
12185                AppGlobals.getPackageManager().setPackageStoppedState(
12186                        r.curComponent.getPackageName(), false);
12187            } catch (RemoteException e) {
12188            } catch (IllegalArgumentException e) {
12189                Slog.w(TAG, "Failed trying to unstop package "
12190                        + r.curComponent.getPackageName() + ": " + e);
12191            }
12192
12193            // Is this receiver's application already running?
12194            ProcessRecord app = getProcessRecordLocked(targetProcess,
12195                    info.activityInfo.applicationInfo.uid);
12196            if (app != null && app.thread != null) {
12197                try {
12198                    app.addPackage(info.activityInfo.packageName);
12199                    processCurBroadcastLocked(r, app);
12200                    return;
12201                } catch (RemoteException e) {
12202                    Slog.w(TAG, "Exception when sending broadcast to "
12203                          + r.curComponent, e);
12204                }
12205
12206                // If a dead object exception was thrown -- fall through to
12207                // restart the application.
12208            }
12209
12210            // Not running -- get it started, to be executed when the app comes up.
12211            if (DEBUG_BROADCAST)  Slog.v(TAG,
12212                    "Need to start app " + targetProcess + " for broadcast " + r);
12213            if ((r.curApp=startProcessLocked(targetProcess,
12214                    info.activityInfo.applicationInfo, true,
12215                    r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
12216                    "broadcast", r.curComponent,
12217                    (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12218                            == null) {
12219                // Ah, this recipient is unavailable.  Finish it if necessary,
12220                // and mark the broadcast record as ready for the next.
12221                Slog.w(TAG, "Unable to launch app "
12222                        + info.activityInfo.applicationInfo.packageName + "/"
12223                        + info.activityInfo.applicationInfo.uid + " for broadcast "
12224                        + r.intent + ": process is bad");
12225                logBroadcastReceiverDiscardLocked(r);
12226                finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12227                        r.resultExtras, r.resultAbort, true);
12228                scheduleBroadcastsLocked();
12229                r.state = BroadcastRecord.IDLE;
12230                return;
12231            }
12232
12233            mPendingBroadcast = r;
12234            mPendingBroadcastRecvIndex = recIdx;
12235        }
12236    }
12237
12238    // =========================================================
12239    // INSTRUMENTATION
12240    // =========================================================
12241
12242    public boolean startInstrumentation(ComponentName className,
12243            String profileFile, int flags, Bundle arguments,
12244            IInstrumentationWatcher watcher) {
12245        // Refuse possible leaked file descriptors
12246        if (arguments != null && arguments.hasFileDescriptors()) {
12247            throw new IllegalArgumentException("File descriptors passed in Bundle");
12248        }
12249
12250        synchronized(this) {
12251            InstrumentationInfo ii = null;
12252            ApplicationInfo ai = null;
12253            try {
12254                ii = mContext.getPackageManager().getInstrumentationInfo(
12255                    className, STOCK_PM_FLAGS);
12256                ai = mContext.getPackageManager().getApplicationInfo(
12257                    ii.targetPackage, STOCK_PM_FLAGS);
12258            } catch (PackageManager.NameNotFoundException e) {
12259            }
12260            if (ii == null) {
12261                reportStartInstrumentationFailure(watcher, className,
12262                        "Unable to find instrumentation info for: " + className);
12263                return false;
12264            }
12265            if (ai == null) {
12266                reportStartInstrumentationFailure(watcher, className,
12267                        "Unable to find instrumentation target package: " + ii.targetPackage);
12268                return false;
12269            }
12270
12271            int match = mContext.getPackageManager().checkSignatures(
12272                    ii.targetPackage, ii.packageName);
12273            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12274                String msg = "Permission Denial: starting instrumentation "
12275                        + className + " from pid="
12276                        + Binder.getCallingPid()
12277                        + ", uid=" + Binder.getCallingPid()
12278                        + " not allowed because package " + ii.packageName
12279                        + " does not have a signature matching the target "
12280                        + ii.targetPackage;
12281                reportStartInstrumentationFailure(watcher, className, msg);
12282                throw new SecurityException(msg);
12283            }
12284
12285            final long origId = Binder.clearCallingIdentity();
12286            forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
12287            ProcessRecord app = addAppLocked(ai);
12288            app.instrumentationClass = className;
12289            app.instrumentationInfo = ai;
12290            app.instrumentationProfileFile = profileFile;
12291            app.instrumentationArguments = arguments;
12292            app.instrumentationWatcher = watcher;
12293            app.instrumentationResultClass = className;
12294            Binder.restoreCallingIdentity(origId);
12295        }
12296
12297        return true;
12298    }
12299
12300    /**
12301     * Report errors that occur while attempting to start Instrumentation.  Always writes the
12302     * error to the logs, but if somebody is watching, send the report there too.  This enables
12303     * the "am" command to report errors with more information.
12304     *
12305     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12306     * @param cn The component name of the instrumentation.
12307     * @param report The error report.
12308     */
12309    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12310            ComponentName cn, String report) {
12311        Slog.w(TAG, report);
12312        try {
12313            if (watcher != null) {
12314                Bundle results = new Bundle();
12315                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12316                results.putString("Error", report);
12317                watcher.instrumentationStatus(cn, -1, results);
12318            }
12319        } catch (RemoteException e) {
12320            Slog.w(TAG, e);
12321        }
12322    }
12323
12324    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12325        if (app.instrumentationWatcher != null) {
12326            try {
12327                // NOTE:  IInstrumentationWatcher *must* be oneway here
12328                app.instrumentationWatcher.instrumentationFinished(
12329                    app.instrumentationClass,
12330                    resultCode,
12331                    results);
12332            } catch (RemoteException e) {
12333            }
12334        }
12335        app.instrumentationWatcher = null;
12336        app.instrumentationClass = null;
12337        app.instrumentationInfo = null;
12338        app.instrumentationProfileFile = null;
12339        app.instrumentationArguments = null;
12340
12341        forceStopPackageLocked(app.processName, -1, false, false, true);
12342    }
12343
12344    public void finishInstrumentation(IApplicationThread target,
12345            int resultCode, Bundle results) {
12346        // Refuse possible leaked file descriptors
12347        if (results != null && results.hasFileDescriptors()) {
12348            throw new IllegalArgumentException("File descriptors passed in Intent");
12349        }
12350
12351        synchronized(this) {
12352            ProcessRecord app = getRecordForAppLocked(target);
12353            if (app == null) {
12354                Slog.w(TAG, "finishInstrumentation: no app for " + target);
12355                return;
12356            }
12357            final long origId = Binder.clearCallingIdentity();
12358            finishInstrumentationLocked(app, resultCode, results);
12359            Binder.restoreCallingIdentity(origId);
12360        }
12361    }
12362
12363    // =========================================================
12364    // CONFIGURATION
12365    // =========================================================
12366
12367    public ConfigurationInfo getDeviceConfigurationInfo() {
12368        ConfigurationInfo config = new ConfigurationInfo();
12369        synchronized (this) {
12370            config.reqTouchScreen = mConfiguration.touchscreen;
12371            config.reqKeyboardType = mConfiguration.keyboard;
12372            config.reqNavigation = mConfiguration.navigation;
12373            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12374                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12375                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12376            }
12377            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12378                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12379                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12380            }
12381            config.reqGlEsVersion = GL_ES_VERSION;
12382        }
12383        return config;
12384    }
12385
12386    public Configuration getConfiguration() {
12387        Configuration ci;
12388        synchronized(this) {
12389            ci = new Configuration(mConfiguration);
12390        }
12391        return ci;
12392    }
12393
12394    public void updateConfiguration(Configuration values) {
12395        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12396                "updateConfiguration()");
12397
12398        synchronized(this) {
12399            if (values == null && mWindowManager != null) {
12400                // sentinel: fetch the current configuration from the window manager
12401                values = mWindowManager.computeNewConfiguration();
12402            }
12403
12404            final long origId = Binder.clearCallingIdentity();
12405            updateConfigurationLocked(values, null);
12406            Binder.restoreCallingIdentity(origId);
12407        }
12408    }
12409
12410    /**
12411     * Do either or both things: (1) change the current configuration, and (2)
12412     * make sure the given activity is running with the (now) current
12413     * configuration.  Returns true if the activity has been left running, or
12414     * false if <var>starting</var> is being destroyed to match the new
12415     * configuration.
12416     */
12417    public boolean updateConfigurationLocked(Configuration values,
12418            ActivityRecord starting) {
12419        int changes = 0;
12420
12421        boolean kept = true;
12422
12423        if (values != null) {
12424            Configuration newConfig = new Configuration(mConfiguration);
12425            changes = newConfig.updateFrom(values);
12426            if (changes != 0) {
12427                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12428                    Slog.i(TAG, "Updating configuration to: " + values);
12429                }
12430
12431                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12432
12433                if (values.locale != null) {
12434                    saveLocaleLocked(values.locale,
12435                                     !values.locale.equals(mConfiguration.locale),
12436                                     values.userSetLocale);
12437                }
12438
12439                mConfigurationSeq++;
12440                if (mConfigurationSeq <= 0) {
12441                    mConfigurationSeq = 1;
12442                }
12443                newConfig.seq = mConfigurationSeq;
12444                mConfiguration = newConfig;
12445                Slog.i(TAG, "Config changed: " + newConfig);
12446
12447                AttributeCache ac = AttributeCache.instance();
12448                if (ac != null) {
12449                    ac.updateConfiguration(mConfiguration);
12450                }
12451
12452                // Make sure all resources in our process are updated
12453                // right now, so that anyone who is going to retrieve
12454                // resource values after we return will be sure to get
12455                // the new ones.  This is especially important during
12456                // boot, where the first config change needs to guarantee
12457                // all resources have that config before following boot
12458                // code is executed.
12459                mSystemThread.applyConfigurationToResources(newConfig);
12460
12461                if (Settings.System.hasInterestingConfigurationChanges(changes)) {
12462                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12463                    msg.obj = new Configuration(mConfiguration);
12464                    mHandler.sendMessage(msg);
12465                }
12466
12467                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12468                    ProcessRecord app = mLruProcesses.get(i);
12469                    try {
12470                        if (app.thread != null) {
12471                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12472                                    + app.processName + " new config " + mConfiguration);
12473                            app.thread.scheduleConfigurationChanged(mConfiguration);
12474                        }
12475                    } catch (Exception e) {
12476                    }
12477                }
12478                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12479                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12480                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
12481                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12482                        null, false, false, MY_PID, Process.SYSTEM_UID);
12483                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12484                    broadcastIntentLocked(null, null,
12485                            new Intent(Intent.ACTION_LOCALE_CHANGED),
12486                            null, null, 0, null, null,
12487                            null, false, false, MY_PID, Process.SYSTEM_UID);
12488                }
12489            }
12490        }
12491
12492        if (changes != 0 && starting == null) {
12493            // If the configuration changed, and the caller is not already
12494            // in the process of starting an activity, then find the top
12495            // activity to check if its configuration needs to change.
12496            starting = mMainStack.topRunningActivityLocked(null);
12497        }
12498
12499        if (starting != null) {
12500            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12501            // And we need to make sure at this point that all other activities
12502            // are made visible with the correct configuration.
12503            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12504        }
12505
12506        if (values != null && mWindowManager != null) {
12507            mWindowManager.setNewConfiguration(mConfiguration);
12508        }
12509
12510        return kept;
12511    }
12512
12513    /**
12514     * Save the locale.  You must be inside a synchronized (this) block.
12515     */
12516    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12517        if(isDiff) {
12518            SystemProperties.set("user.language", l.getLanguage());
12519            SystemProperties.set("user.region", l.getCountry());
12520        }
12521
12522        if(isPersist) {
12523            SystemProperties.set("persist.sys.language", l.getLanguage());
12524            SystemProperties.set("persist.sys.country", l.getCountry());
12525            SystemProperties.set("persist.sys.localevar", l.getVariant());
12526        }
12527    }
12528
12529    // =========================================================
12530    // LIFETIME MANAGEMENT
12531    // =========================================================
12532
12533    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12534            ProcessRecord TOP_APP, boolean recursed) {
12535        if (mAdjSeq == app.adjSeq) {
12536            // This adjustment has already been computed.  If we are calling
12537            // from the top, we may have already computed our adjustment with
12538            // an earlier hidden adjustment that isn't really for us... if
12539            // so, use the new hidden adjustment.
12540            if (!recursed && app.hidden) {
12541                app.curAdj = hiddenAdj;
12542            }
12543            return app.curAdj;
12544        }
12545
12546        if (app.thread == null) {
12547            app.adjSeq = mAdjSeq;
12548            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12549            return (app.curAdj=EMPTY_APP_ADJ);
12550        }
12551
12552        if (app.maxAdj <= FOREGROUND_APP_ADJ) {
12553            // The max adjustment doesn't allow this app to be anything
12554            // below foreground, so it is not worth doing work for it.
12555            app.adjType = "fixed";
12556            app.adjSeq = mAdjSeq;
12557            app.curRawAdj = app.maxAdj;
12558            app.keeping = true;
12559            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12560            return (app.curAdj=app.maxAdj);
12561        }
12562
12563        final boolean hadForegroundActivities = app.foregroundActivities;
12564
12565        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12566        app.adjSource = null;
12567        app.adjTarget = null;
12568        app.keeping = false;
12569        app.empty = false;
12570        app.hidden = false;
12571        app.foregroundActivities = false;
12572
12573        final int activitiesSize = app.activities.size();
12574
12575        // Determine the importance of the process, starting with most
12576        // important to least, and assign an appropriate OOM adjustment.
12577        int adj;
12578        int schedGroup;
12579        if (app == TOP_APP) {
12580            // The last app on the list is the foreground app.
12581            adj = FOREGROUND_APP_ADJ;
12582            schedGroup = Process.THREAD_GROUP_DEFAULT;
12583            app.adjType = "top-activity";
12584            app.foregroundActivities = true;
12585        } else if (app.instrumentationClass != null) {
12586            // Don't want to kill running instrumentation.
12587            adj = FOREGROUND_APP_ADJ;
12588            schedGroup = Process.THREAD_GROUP_DEFAULT;
12589            app.adjType = "instrumentation";
12590        } else if (app.curReceiver != null ||
12591                (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12592            // An app that is currently receiving a broadcast also
12593            // counts as being in the foreground.
12594            adj = FOREGROUND_APP_ADJ;
12595            schedGroup = Process.THREAD_GROUP_DEFAULT;
12596            app.adjType = "broadcast";
12597        } else if (app.executingServices.size() > 0) {
12598            // An app that is currently executing a service callback also
12599            // counts as being in the foreground.
12600            adj = FOREGROUND_APP_ADJ;
12601            schedGroup = Process.THREAD_GROUP_DEFAULT;
12602            app.adjType = "exec-service";
12603        } else if (activitiesSize > 0) {
12604            // This app is in the background with paused activities.
12605            // We inspect activities to potentially upgrade adjustment further below.
12606            adj = hiddenAdj;
12607            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12608            app.hidden = true;
12609            app.adjType = "bg-activities";
12610        } else {
12611            // A very not-needed process.  If this is lower in the lru list,
12612            // we will push it in to the empty bucket.
12613            adj = hiddenAdj;
12614            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12615            app.hidden = true;
12616            app.empty = true;
12617            app.adjType = "bg-empty";
12618        }
12619
12620        // Examine all activities if not already foreground.
12621        if (!app.foregroundActivities && activitiesSize > 0) {
12622            for (int j = 0; j < activitiesSize; j++) {
12623                final ActivityRecord r = app.activities.get(j);
12624                if (r.visible) {
12625                    // App has a visible activity; only upgrade adjustment.
12626                    if (adj > VISIBLE_APP_ADJ) {
12627                        adj = VISIBLE_APP_ADJ;
12628                        app.adjType = "visible";
12629                    }
12630                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12631                    app.hidden = false;
12632                    app.foregroundActivities = true;
12633                    break;
12634                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
12635                        || r.state == ActivityState.STOPPING) {
12636                    // Only upgrade adjustment.
12637                    if (adj > PERCEPTIBLE_APP_ADJ) {
12638                        adj = PERCEPTIBLE_APP_ADJ;
12639                        app.adjType = "stopping";
12640                    }
12641                    app.foregroundActivities = true;
12642                }
12643            }
12644        }
12645
12646        if (adj > PERCEPTIBLE_APP_ADJ) {
12647            if (app.foregroundServices) {
12648                // The user is aware of this app, so make it visible.
12649                adj = PERCEPTIBLE_APP_ADJ;
12650                app.adjType = "foreground-service";
12651                schedGroup = Process.THREAD_GROUP_DEFAULT;
12652            } else if (app.forcingToForeground != null) {
12653                // The user is aware of this app, so make it visible.
12654                adj = PERCEPTIBLE_APP_ADJ;
12655                app.adjType = "force-foreground";
12656                app.adjSource = app.forcingToForeground;
12657                schedGroup = Process.THREAD_GROUP_DEFAULT;
12658            }
12659        }
12660
12661        if (adj > HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12662            // We don't want to kill the current heavy-weight process.
12663            adj = HEAVY_WEIGHT_APP_ADJ;
12664            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12665            app.adjType = "heavy";
12666        }
12667
12668        if (adj > HOME_APP_ADJ && app == mHomeProcess) {
12669            // This process is hosting what we currently consider to be the
12670            // home app, so we don't want to let it go into the background.
12671            adj = HOME_APP_ADJ;
12672            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12673            app.adjType = "home";
12674        }
12675
12676        //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
12677
12678        // By default, we use the computed adjustment.  It may be changed if
12679        // there are applications dependent on our services or providers, but
12680        // this gives us a baseline and makes sure we don't get into an
12681        // infinite recursion.
12682        app.adjSeq = mAdjSeq;
12683        app.curRawAdj = adj;
12684
12685        if (mBackupTarget != null && app == mBackupTarget.app) {
12686            // If possible we want to avoid killing apps while they're being backed up
12687            if (adj > BACKUP_APP_ADJ) {
12688                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12689                adj = BACKUP_APP_ADJ;
12690                app.adjType = "backup";
12691                app.hidden = false;
12692            }
12693        }
12694
12695        if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
12696                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12697            final long now = SystemClock.uptimeMillis();
12698            // This process is more important if the top activity is
12699            // bound to the service.
12700            Iterator<ServiceRecord> jt = app.services.iterator();
12701            while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
12702                ServiceRecord s = jt.next();
12703                if (s.startRequested) {
12704                    if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12705                        // This service has seen some activity within
12706                        // recent memory, so we will keep its process ahead
12707                        // of the background processes.
12708                        if (adj > SECONDARY_SERVER_ADJ) {
12709                            adj = SECONDARY_SERVER_ADJ;
12710                            app.adjType = "started-services";
12711                            app.hidden = false;
12712                        }
12713                    }
12714                    // If we have let the service slide into the background
12715                    // state, still have some text describing what it is doing
12716                    // even though the service no longer has an impact.
12717                    if (adj > SECONDARY_SERVER_ADJ) {
12718                        app.adjType = "started-bg-services";
12719                    }
12720                    // Don't kill this process because it is doing work; it
12721                    // has said it is doing work.
12722                    app.keeping = true;
12723                }
12724                if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
12725                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12726                    Iterator<ArrayList<ConnectionRecord>> kt
12727                            = s.connections.values().iterator();
12728                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
12729                        ArrayList<ConnectionRecord> clist = kt.next();
12730                        for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
12731                            // XXX should compute this based on the max of
12732                            // all connected clients.
12733                            ConnectionRecord cr = clist.get(i);
12734                            if (cr.binding.client == app) {
12735                                // Binding to ourself is not interesting.
12736                                continue;
12737                            }
12738                            if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12739                                ProcessRecord client = cr.binding.client;
12740                                int myHiddenAdj = hiddenAdj;
12741                                if (myHiddenAdj > client.hiddenAdj) {
12742                                    if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
12743                                        myHiddenAdj = client.hiddenAdj;
12744                                    } else {
12745                                        myHiddenAdj = VISIBLE_APP_ADJ;
12746                                    }
12747                                }
12748                                int clientAdj = computeOomAdjLocked(
12749                                    client, myHiddenAdj, TOP_APP, true);
12750                                if (adj > clientAdj) {
12751                                    adj = clientAdj >= VISIBLE_APP_ADJ
12752                                            ? clientAdj : VISIBLE_APP_ADJ;
12753                                    if (!client.hidden) {
12754                                        app.hidden = false;
12755                                    }
12756                                    if (client.keeping) {
12757                                        app.keeping = true;
12758                                    }
12759                                    app.adjType = "service";
12760                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12761                                            .REASON_SERVICE_IN_USE;
12762                                    app.adjSource = cr.binding.client;
12763                                    app.adjTarget = s.name;
12764                                }
12765                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12766                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12767                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12768                                    }
12769                                }
12770                            }
12771                            ActivityRecord a = cr.activity;
12772                            //if (a != null) {
12773                            //    Slog.i(TAG, "Connection to " + a ": state=" + a.state);
12774                            //}
12775                            if (a != null && adj > FOREGROUND_APP_ADJ &&
12776                                    (a.state == ActivityState.RESUMED
12777                                     || a.state == ActivityState.PAUSING)) {
12778                                adj = FOREGROUND_APP_ADJ;
12779                                schedGroup = Process.THREAD_GROUP_DEFAULT;
12780                                app.hidden = false;
12781                                app.adjType = "service";
12782                                app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12783                                        .REASON_SERVICE_IN_USE;
12784                                app.adjSource = a;
12785                                app.adjTarget = s.name;
12786                            }
12787                        }
12788                    }
12789                }
12790            }
12791
12792            // Finally, if this process has active services running in it, we
12793            // would like to avoid killing it unless it would prevent the current
12794            // application from running.  By default we put the process in
12795            // with the rest of the background processes; as we scan through
12796            // its services we may bump it up from there.
12797            if (adj > hiddenAdj) {
12798                adj = hiddenAdj;
12799                app.hidden = false;
12800                app.adjType = "bg-services";
12801            }
12802        }
12803
12804        if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
12805                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12806            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12807            while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
12808                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12809                ContentProviderRecord cpr = jt.next();
12810                if (cpr.clients.size() != 0) {
12811                    Iterator<ProcessRecord> kt = cpr.clients.iterator();
12812                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
12813                        ProcessRecord client = kt.next();
12814                        if (client == app) {
12815                            // Being our own client is not interesting.
12816                            continue;
12817                        }
12818                        int myHiddenAdj = hiddenAdj;
12819                        if (myHiddenAdj > client.hiddenAdj) {
12820                            if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
12821                                myHiddenAdj = client.hiddenAdj;
12822                            } else {
12823                                myHiddenAdj = FOREGROUND_APP_ADJ;
12824                            }
12825                        }
12826                        int clientAdj = computeOomAdjLocked(
12827                            client, myHiddenAdj, TOP_APP, true);
12828                        if (adj > clientAdj) {
12829                            adj = clientAdj > FOREGROUND_APP_ADJ
12830                                    ? clientAdj : FOREGROUND_APP_ADJ;
12831                            if (!client.hidden) {
12832                                app.hidden = false;
12833                            }
12834                            if (client.keeping) {
12835                                app.keeping = true;
12836                            }
12837                            app.adjType = "provider";
12838                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12839                                    .REASON_PROVIDER_IN_USE;
12840                            app.adjSource = client;
12841                            app.adjTarget = cpr.name;
12842                        }
12843                        if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12844                            schedGroup = Process.THREAD_GROUP_DEFAULT;
12845                        }
12846                    }
12847                }
12848                // If the provider has external (non-framework) process
12849                // dependencies, ensure that its adjustment is at least
12850                // FOREGROUND_APP_ADJ.
12851                if (cpr.externals != 0) {
12852                    if (adj > FOREGROUND_APP_ADJ) {
12853                        adj = FOREGROUND_APP_ADJ;
12854                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12855                        app.hidden = false;
12856                        app.keeping = true;
12857                        app.adjType = "provider";
12858                        app.adjTarget = cpr.name;
12859                    }
12860                }
12861            }
12862        }
12863
12864        app.curRawAdj = adj;
12865
12866        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12867        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12868        if (adj > app.maxAdj) {
12869            adj = app.maxAdj;
12870            if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
12871                schedGroup = Process.THREAD_GROUP_DEFAULT;
12872            }
12873        }
12874        if (adj < HIDDEN_APP_MIN_ADJ) {
12875            app.keeping = true;
12876        }
12877
12878        app.curAdj = adj;
12879        app.curSchedGroup = schedGroup;
12880
12881        if (hadForegroundActivities != app.foregroundActivities) {
12882            mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
12883                    app.foregroundActivities).sendToTarget();
12884        }
12885
12886        return adj;
12887    }
12888
12889    /**
12890     * Ask a given process to GC right now.
12891     */
12892    final void performAppGcLocked(ProcessRecord app) {
12893        try {
12894            app.lastRequestedGc = SystemClock.uptimeMillis();
12895            if (app.thread != null) {
12896                if (app.reportLowMemory) {
12897                    app.reportLowMemory = false;
12898                    app.thread.scheduleLowMemory();
12899                } else {
12900                    app.thread.processInBackground();
12901                }
12902            }
12903        } catch (Exception e) {
12904            // whatever.
12905        }
12906    }
12907
12908    /**
12909     * Returns true if things are idle enough to perform GCs.
12910     */
12911    private final boolean canGcNowLocked() {
12912        return mParallelBroadcasts.size() == 0
12913                && mOrderedBroadcasts.size() == 0
12914                && (mSleeping || (mMainStack.mResumedActivity != null &&
12915                        mMainStack.mResumedActivity.idle));
12916    }
12917
12918    /**
12919     * Perform GCs on all processes that are waiting for it, but only
12920     * if things are idle.
12921     */
12922    final void performAppGcsLocked() {
12923        final int N = mProcessesToGc.size();
12924        if (N <= 0) {
12925            return;
12926        }
12927        if (canGcNowLocked()) {
12928            while (mProcessesToGc.size() > 0) {
12929                ProcessRecord proc = mProcessesToGc.remove(0);
12930                if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
12931                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12932                            <= SystemClock.uptimeMillis()) {
12933                        // To avoid spamming the system, we will GC processes one
12934                        // at a time, waiting a few seconds between each.
12935                        performAppGcLocked(proc);
12936                        scheduleAppGcsLocked();
12937                        return;
12938                    } else {
12939                        // It hasn't been long enough since we last GCed this
12940                        // process...  put it in the list to wait for its time.
12941                        addProcessToGcListLocked(proc);
12942                        break;
12943                    }
12944                }
12945            }
12946
12947            scheduleAppGcsLocked();
12948        }
12949    }
12950
12951    /**
12952     * If all looks good, perform GCs on all processes waiting for them.
12953     */
12954    final void performAppGcsIfAppropriateLocked() {
12955        if (canGcNowLocked()) {
12956            performAppGcsLocked();
12957            return;
12958        }
12959        // Still not idle, wait some more.
12960        scheduleAppGcsLocked();
12961    }
12962
12963    /**
12964     * Schedule the execution of all pending app GCs.
12965     */
12966    final void scheduleAppGcsLocked() {
12967        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
12968
12969        if (mProcessesToGc.size() > 0) {
12970            // Schedule a GC for the time to the next process.
12971            ProcessRecord proc = mProcessesToGc.get(0);
12972            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12973
12974            long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
12975            long now = SystemClock.uptimeMillis();
12976            if (when < (now+GC_TIMEOUT)) {
12977                when = now + GC_TIMEOUT;
12978            }
12979            mHandler.sendMessageAtTime(msg, when);
12980        }
12981    }
12982
12983    /**
12984     * Add a process to the array of processes waiting to be GCed.  Keeps the
12985     * list in sorted order by the last GC time.  The process can't already be
12986     * on the list.
12987     */
12988    final void addProcessToGcListLocked(ProcessRecord proc) {
12989        boolean added = false;
12990        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12991            if (mProcessesToGc.get(i).lastRequestedGc <
12992                    proc.lastRequestedGc) {
12993                added = true;
12994                mProcessesToGc.add(i+1, proc);
12995                break;
12996            }
12997        }
12998        if (!added) {
12999            mProcessesToGc.add(0, proc);
13000        }
13001    }
13002
13003    /**
13004     * Set up to ask a process to GC itself.  This will either do it
13005     * immediately, or put it on the list of processes to gc the next
13006     * time things are idle.
13007     */
13008    final void scheduleAppGcLocked(ProcessRecord app) {
13009        long now = SystemClock.uptimeMillis();
13010        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13011            return;
13012        }
13013        if (!mProcessesToGc.contains(app)) {
13014            addProcessToGcListLocked(app);
13015            scheduleAppGcsLocked();
13016        }
13017    }
13018
13019    final void checkExcessivePowerUsageLocked(boolean doKills) {
13020        updateCpuStatsNow();
13021
13022        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13023        boolean doWakeKills = doKills;
13024        boolean doCpuKills = doKills;
13025        if (mLastPowerCheckRealtime == 0) {
13026            doWakeKills = false;
13027        }
13028        if (mLastPowerCheckUptime == 0) {
13029            doCpuKills = false;
13030        }
13031        if (stats.isScreenOn()) {
13032            doWakeKills = false;
13033        }
13034        final long curRealtime = SystemClock.elapsedRealtime();
13035        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13036        final long curUptime = SystemClock.uptimeMillis();
13037        final long uptimeSince = curUptime - mLastPowerCheckUptime;
13038        mLastPowerCheckRealtime = curRealtime;
13039        mLastPowerCheckUptime = curUptime;
13040        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13041            doWakeKills = false;
13042        }
13043        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13044            doCpuKills = false;
13045        }
13046        int i = mLruProcesses.size();
13047        while (i > 0) {
13048            i--;
13049            ProcessRecord app = mLruProcesses.get(i);
13050            if (!app.keeping) {
13051                long wtime;
13052                synchronized (stats) {
13053                    wtime = stats.getProcessWakeTime(app.info.uid,
13054                            app.pid, curRealtime);
13055                }
13056                long wtimeUsed = wtime - app.lastWakeTime;
13057                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13058                if (DEBUG_POWER) {
13059                    StringBuilder sb = new StringBuilder(128);
13060                    sb.append("Wake for ");
13061                    app.toShortString(sb);
13062                    sb.append(": over ");
13063                    TimeUtils.formatDuration(realtimeSince, sb);
13064                    sb.append(" used ");
13065                    TimeUtils.formatDuration(wtimeUsed, sb);
13066                    sb.append(" (");
13067                    sb.append((wtimeUsed*100)/realtimeSince);
13068                    sb.append("%)");
13069                    Slog.i(TAG, sb.toString());
13070                    sb.setLength(0);
13071                    sb.append("CPU for ");
13072                    app.toShortString(sb);
13073                    sb.append(": over ");
13074                    TimeUtils.formatDuration(uptimeSince, sb);
13075                    sb.append(" used ");
13076                    TimeUtils.formatDuration(cputimeUsed, sb);
13077                    sb.append(" (");
13078                    sb.append((cputimeUsed*100)/uptimeSince);
13079                    sb.append("%)");
13080                    Slog.i(TAG, sb.toString());
13081                }
13082                // If a process has held a wake lock for more
13083                // than 50% of the time during this period,
13084                // that sounds pad.  Kill!
13085                if (doWakeKills && realtimeSince > 0
13086                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13087                    synchronized (stats) {
13088                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13089                                realtimeSince, wtimeUsed);
13090                    }
13091                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13092                            + " (pid " + app.pid + "): held " + wtimeUsed
13093                            + " during " + realtimeSince);
13094                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13095                            app.processName, app.setAdj, "excessive wake lock");
13096                    Process.killProcessQuiet(app.pid);
13097                } else if (doCpuKills && uptimeSince > 0
13098                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13099                    synchronized (stats) {
13100                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13101                                uptimeSince, cputimeUsed);
13102                    }
13103                    Slog.w(TAG, "Excessive CPU in " + app.processName
13104                            + " (pid " + app.pid + "): used " + cputimeUsed
13105                            + " during " + uptimeSince);
13106                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13107                            app.processName, app.setAdj, "excessive cpu");
13108                    Process.killProcessQuiet(app.pid);
13109                } else {
13110                    app.lastWakeTime = wtime;
13111                    app.lastCpuTime = app.curCpuTime;
13112                }
13113            }
13114        }
13115    }
13116
13117    private final boolean updateOomAdjLocked(
13118            ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
13119        app.hiddenAdj = hiddenAdj;
13120
13121        if (app.thread == null) {
13122            return true;
13123        }
13124
13125        boolean success = true;
13126
13127        final boolean wasKeeping = app.keeping;
13128
13129        int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
13130
13131        if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
13132            if (app.curRawAdj != app.setRawAdj) {
13133                if (app.curRawAdj > FOREGROUND_APP_ADJ
13134                        && app.setRawAdj <= FOREGROUND_APP_ADJ) {
13135                    // If this app is transitioning from foreground to
13136                    // non-foreground, have it do a gc.
13137                    scheduleAppGcLocked(app);
13138                } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
13139                        && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
13140                    // Likewise do a gc when an app is moving in to the
13141                    // background (such as a service stopping).
13142                    scheduleAppGcLocked(app);
13143                }
13144
13145                if (wasKeeping && !app.keeping) {
13146                    // This app is no longer something we want to keep.  Note
13147                    // its current wake lock time to later know to kill it if
13148                    // it is not behaving well.
13149                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13150                    synchronized (stats) {
13151                        app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13152                                app.pid, SystemClock.elapsedRealtime());
13153                    }
13154                    app.lastCpuTime = app.curCpuTime;
13155                }
13156
13157                app.setRawAdj = app.curRawAdj;
13158            }
13159            if (adj != app.setAdj) {
13160                if (Process.setOomAdj(app.pid, adj)) {
13161                    if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13162                        TAG, "Set app " + app.processName +
13163                        " oom adj to " + adj);
13164                    app.setAdj = adj;
13165                } else {
13166                    success = false;
13167                }
13168            }
13169            if (app.setSchedGroup != app.curSchedGroup) {
13170                app.setSchedGroup = app.curSchedGroup;
13171                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13172                        "Setting process group of " + app.processName
13173                        + " to " + app.curSchedGroup);
13174                if (app.waitingToKill != null &&
13175                        app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13176                    Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13177                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13178                            app.processName, app.setAdj, app.waitingToKill);
13179                    Process.killProcessQuiet(app.pid);
13180                } else {
13181                    if (true) {
13182                        long oldId = Binder.clearCallingIdentity();
13183                        try {
13184                            Process.setProcessGroup(app.pid, app.curSchedGroup);
13185                        } catch (Exception e) {
13186                            Slog.w(TAG, "Failed setting process group of " + app.pid
13187                                    + " to " + app.curSchedGroup);
13188                            e.printStackTrace();
13189                        } finally {
13190                            Binder.restoreCallingIdentity(oldId);
13191                        }
13192                    }
13193                    if (false) {
13194                        if (app.thread != null) {
13195                            try {
13196                                app.thread.setSchedulingGroup(app.curSchedGroup);
13197                            } catch (RemoteException e) {
13198                            }
13199                        }
13200                    }
13201                }
13202            }
13203        }
13204
13205        return success;
13206    }
13207
13208    private final ActivityRecord resumedAppLocked() {
13209        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13210        if (resumedActivity == null || resumedActivity.app == null) {
13211            resumedActivity = mMainStack.mPausingActivity;
13212            if (resumedActivity == null || resumedActivity.app == null) {
13213                resumedActivity = mMainStack.topRunningActivityLocked(null);
13214            }
13215        }
13216        return resumedActivity;
13217    }
13218
13219    private final boolean updateOomAdjLocked(ProcessRecord app) {
13220        final ActivityRecord TOP_ACT = resumedAppLocked();
13221        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13222        int curAdj = app.curAdj;
13223        final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13224            && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13225
13226        mAdjSeq++;
13227
13228        final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
13229        if (res) {
13230            final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13231                && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13232            if (nowHidden != wasHidden) {
13233                // Changed to/from hidden state, so apps after it in the LRU
13234                // list may also be changed.
13235                updateOomAdjLocked();
13236            }
13237        }
13238        return res;
13239    }
13240
13241    final boolean updateOomAdjLocked() {
13242        boolean didOomAdj = true;
13243        final ActivityRecord TOP_ACT = resumedAppLocked();
13244        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13245
13246        if (false) {
13247            RuntimeException e = new RuntimeException();
13248            e.fillInStackTrace();
13249            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13250        }
13251
13252        mAdjSeq++;
13253
13254        // Let's determine how many processes we have running vs.
13255        // how many slots we have for background processes; we may want
13256        // to put multiple processes in a slot of there are enough of
13257        // them.
13258        int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
13259        int factor = (mLruProcesses.size()-4)/numSlots;
13260        if (factor < 1) factor = 1;
13261        int step = 0;
13262        int numHidden = 0;
13263
13264        // First try updating the OOM adjustment for each of the
13265        // application processes based on their current state.
13266        int i = mLruProcesses.size();
13267        int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
13268        while (i > 0) {
13269            i--;
13270            ProcessRecord app = mLruProcesses.get(i);
13271            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13272            if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
13273                if (curHiddenAdj < EMPTY_APP_ADJ
13274                    && app.curAdj == curHiddenAdj) {
13275                    step++;
13276                    if (step >= factor) {
13277                        step = 0;
13278                        curHiddenAdj++;
13279                    }
13280                }
13281                if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
13282                    if (!app.killedBackground) {
13283                        numHidden++;
13284                        if (numHidden > MAX_HIDDEN_APPS) {
13285                            Slog.i(TAG, "No longer want " + app.processName
13286                                    + " (pid " + app.pid + "): hidden #" + numHidden);
13287                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13288                                    app.processName, app.setAdj, "too many background");
13289                            app.killedBackground = true;
13290                            Process.killProcessQuiet(app.pid);
13291                        }
13292                    }
13293                }
13294            } else {
13295                didOomAdj = false;
13296            }
13297        }
13298
13299        // If we return false, we will fall back on killing processes to
13300        // have a fixed limit.  Do this if a limit has been requested; else
13301        // only return false if one of the adjustments failed.
13302        return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
13303    }
13304
13305    final void trimApplications() {
13306        synchronized (this) {
13307            int i;
13308
13309            // First remove any unused application processes whose package
13310            // has been removed.
13311            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13312                final ProcessRecord app = mRemovedProcesses.get(i);
13313                if (app.activities.size() == 0
13314                        && app.curReceiver == null && app.services.size() == 0) {
13315                    Slog.i(
13316                        TAG, "Exiting empty application process "
13317                        + app.processName + " ("
13318                        + (app.thread != null ? app.thread.asBinder() : null)
13319                        + ")\n");
13320                    if (app.pid > 0 && app.pid != MY_PID) {
13321                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13322                                app.processName, app.setAdj, "empty");
13323                        Process.killProcessQuiet(app.pid);
13324                    } else {
13325                        try {
13326                            app.thread.scheduleExit();
13327                        } catch (Exception e) {
13328                            // Ignore exceptions.
13329                        }
13330                    }
13331                    cleanUpApplicationRecordLocked(app, false, -1);
13332                    mRemovedProcesses.remove(i);
13333
13334                    if (app.persistent) {
13335                        if (app.persistent) {
13336                            addAppLocked(app.info);
13337                        }
13338                    }
13339                }
13340            }
13341
13342            // Now try updating the OOM adjustment for each of the
13343            // application processes based on their current state.
13344            // If the setOomAdj() API is not supported, then go with our
13345            // back-up plan...
13346            if (!updateOomAdjLocked()) {
13347
13348                // Count how many processes are running services.
13349                int numServiceProcs = 0;
13350                for (i=mLruProcesses.size()-1; i>=0; i--) {
13351                    final ProcessRecord app = mLruProcesses.get(i);
13352
13353                    if (app.persistent || app.services.size() != 0
13354                            || app.curReceiver != null) {
13355                        // Don't count processes holding services against our
13356                        // maximum process count.
13357                        if (localLOGV) Slog.v(
13358                            TAG, "Not trimming app " + app + " with services: "
13359                            + app.services);
13360                        numServiceProcs++;
13361                    }
13362                }
13363
13364                int curMaxProcs = mProcessLimit;
13365                if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
13366                if (mAlwaysFinishActivities) {
13367                    curMaxProcs = 1;
13368                }
13369                curMaxProcs += numServiceProcs;
13370
13371                // Quit as many processes as we can to get down to the desired
13372                // process count.  First remove any processes that no longer
13373                // have activites running in them.
13374                for (   i=0;
13375                        i<mLruProcesses.size()
13376                            && mLruProcesses.size() > curMaxProcs;
13377                        i++) {
13378                    final ProcessRecord app = mLruProcesses.get(i);
13379                    // Quit an application only if it is not currently
13380                    // running any activities.
13381                    if (!app.persistent && app.activities.size() == 0
13382                            && app.curReceiver == null && app.services.size() == 0) {
13383                        Slog.i(
13384                            TAG, "Exiting empty application process "
13385                            + app.processName + " ("
13386                            + (app.thread != null ? app.thread.asBinder() : null)
13387                            + ")\n");
13388                        if (app.pid > 0 && app.pid != MY_PID) {
13389                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13390                                    app.processName, app.setAdj, "empty");
13391                            Process.killProcessQuiet(app.pid);
13392                        } else {
13393                            try {
13394                                app.thread.scheduleExit();
13395                            } catch (Exception e) {
13396                                // Ignore exceptions.
13397                            }
13398                        }
13399                        // todo: For now we assume the application is not buggy
13400                        // or evil, and will quit as a result of our request.
13401                        // Eventually we need to drive this off of the death
13402                        // notification, and kill the process if it takes too long.
13403                        cleanUpApplicationRecordLocked(app, false, i);
13404                        i--;
13405                    }
13406                }
13407
13408                // If we still have too many processes, now from the least
13409                // recently used process we start finishing activities.
13410                if (false) Slog.v(
13411                    TAG, "*** NOW HAVE " + mLruProcesses.size() +
13412                    " of " + curMaxProcs + " processes");
13413                for (   i=0;
13414                        i<mLruProcesses.size()
13415                            && mLruProcesses.size() > curMaxProcs;
13416                        i++) {
13417                    final ProcessRecord app = mLruProcesses.get(i);
13418                    // Quit the application only if we have a state saved for
13419                    // all of its activities.
13420                    boolean canQuit = !app.persistent && app.curReceiver == null
13421                        && app.services.size() == 0;
13422                    int NUMA = app.activities.size();
13423                    int j;
13424                    if (false) Slog.v(
13425                        TAG, "Looking to quit " + app.processName);
13426                    for (j=0; j<NUMA && canQuit; j++) {
13427                        ActivityRecord r = app.activities.get(j);
13428                        if (false) Slog.v(
13429                            TAG, "  " + r.intent.getComponent().flattenToShortString()
13430                            + ": frozen=" + r.haveState + ", visible=" + r.visible);
13431                        canQuit = (r.haveState || !r.stateNotNeeded)
13432                                && !r.visible && r.stopped;
13433                    }
13434                    if (canQuit) {
13435                        // Finish all of the activities, and then the app itself.
13436                        for (j=0; j<NUMA; j++) {
13437                            ActivityRecord r = app.activities.get(j);
13438                            if (!r.finishing) {
13439                                r.stack.destroyActivityLocked(r, false);
13440                            }
13441                            r.resultTo = null;
13442                        }
13443                        Slog.i(TAG, "Exiting application process "
13444                              + app.processName + " ("
13445                              + (app.thread != null ? app.thread.asBinder() : null)
13446                              + ")\n");
13447                        if (app.pid > 0 && app.pid != MY_PID) {
13448                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13449                                    app.processName, app.setAdj, "old background");
13450                            Process.killProcessQuiet(app.pid);
13451                        } else {
13452                            try {
13453                                app.thread.scheduleExit();
13454                            } catch (Exception e) {
13455                                // Ignore exceptions.
13456                            }
13457                        }
13458                        // todo: For now we assume the application is not buggy
13459                        // or evil, and will quit as a result of our request.
13460                        // Eventually we need to drive this off of the death
13461                        // notification, and kill the process if it takes too long.
13462                        cleanUpApplicationRecordLocked(app, false, i);
13463                        i--;
13464                        //dump();
13465                    }
13466                }
13467
13468            }
13469
13470            int curMaxActivities = MAX_ACTIVITIES;
13471            if (mAlwaysFinishActivities) {
13472                curMaxActivities = 1;
13473            }
13474
13475            // Finally, if there are too many activities now running, try to
13476            // finish as many as we can to get back down to the limit.
13477            for (   i=0;
13478                    i<mMainStack.mLRUActivities.size()
13479                        && mMainStack.mLRUActivities.size() > curMaxActivities;
13480                    i++) {
13481                final ActivityRecord r
13482                    = (ActivityRecord)mMainStack.mLRUActivities.get(i);
13483
13484                // We can finish this one if we have its icicle saved and
13485                // it is not persistent.
13486                if ((r.haveState || !r.stateNotNeeded) && !r.visible
13487                        && r.stopped && !r.finishing) {
13488                    final int origSize = mMainStack.mLRUActivities.size();
13489                    r.stack.destroyActivityLocked(r, true);
13490
13491                    // This will remove it from the LRU list, so keep
13492                    // our index at the same value.  Note that this check to
13493                    // see if the size changes is just paranoia -- if
13494                    // something unexpected happens, we don't want to end up
13495                    // in an infinite loop.
13496                    if (origSize > mMainStack.mLRUActivities.size()) {
13497                        i--;
13498                    }
13499                }
13500            }
13501        }
13502    }
13503
13504    /** This method sends the specified signal to each of the persistent apps */
13505    public void signalPersistentProcesses(int sig) throws RemoteException {
13506        if (sig != Process.SIGNAL_USR1) {
13507            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13508        }
13509
13510        synchronized (this) {
13511            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13512                    != PackageManager.PERMISSION_GRANTED) {
13513                throw new SecurityException("Requires permission "
13514                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13515            }
13516
13517            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13518                ProcessRecord r = mLruProcesses.get(i);
13519                if (r.thread != null && r.persistent) {
13520                    Process.sendSignal(r.pid, sig);
13521                }
13522            }
13523        }
13524    }
13525
13526    public boolean profileControl(String process, boolean start,
13527            String path, ParcelFileDescriptor fd) throws RemoteException {
13528
13529        try {
13530            synchronized (this) {
13531                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13532                // its own permission.
13533                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13534                        != PackageManager.PERMISSION_GRANTED) {
13535                    throw new SecurityException("Requires permission "
13536                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13537                }
13538
13539                if (start && fd == null) {
13540                    throw new IllegalArgumentException("null fd");
13541                }
13542
13543                ProcessRecord proc = null;
13544                try {
13545                    int pid = Integer.parseInt(process);
13546                    synchronized (mPidsSelfLocked) {
13547                        proc = mPidsSelfLocked.get(pid);
13548                    }
13549                } catch (NumberFormatException e) {
13550                }
13551
13552                if (proc == null) {
13553                    HashMap<String, SparseArray<ProcessRecord>> all
13554                            = mProcessNames.getMap();
13555                    SparseArray<ProcessRecord> procs = all.get(process);
13556                    if (procs != null && procs.size() > 0) {
13557                        proc = procs.valueAt(0);
13558                    }
13559                }
13560
13561                if (proc == null || proc.thread == null) {
13562                    throw new IllegalArgumentException("Unknown process: " + process);
13563                }
13564
13565                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13566                if (!isDebuggable) {
13567                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13568                        throw new SecurityException("Process not debuggable: " + proc);
13569                    }
13570                }
13571
13572                proc.thread.profilerControl(start, path, fd);
13573                fd = null;
13574                return true;
13575            }
13576        } catch (RemoteException e) {
13577            throw new IllegalStateException("Process disappeared");
13578        } finally {
13579            if (fd != null) {
13580                try {
13581                    fd.close();
13582                } catch (IOException e) {
13583                }
13584            }
13585        }
13586    }
13587
13588    public boolean dumpHeap(String process, boolean managed,
13589            String path, ParcelFileDescriptor fd) throws RemoteException {
13590
13591        try {
13592            synchronized (this) {
13593                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13594                // its own permission (same as profileControl).
13595                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13596                        != PackageManager.PERMISSION_GRANTED) {
13597                    throw new SecurityException("Requires permission "
13598                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13599                }
13600
13601                if (fd == null) {
13602                    throw new IllegalArgumentException("null fd");
13603                }
13604
13605                ProcessRecord proc = null;
13606                try {
13607                    int pid = Integer.parseInt(process);
13608                    synchronized (mPidsSelfLocked) {
13609                        proc = mPidsSelfLocked.get(pid);
13610                    }
13611                } catch (NumberFormatException e) {
13612                }
13613
13614                if (proc == null) {
13615                    HashMap<String, SparseArray<ProcessRecord>> all
13616                            = mProcessNames.getMap();
13617                    SparseArray<ProcessRecord> procs = all.get(process);
13618                    if (procs != null && procs.size() > 0) {
13619                        proc = procs.valueAt(0);
13620                    }
13621                }
13622
13623                if (proc == null || proc.thread == null) {
13624                    throw new IllegalArgumentException("Unknown process: " + process);
13625                }
13626
13627                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13628                if (!isDebuggable) {
13629                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13630                        throw new SecurityException("Process not debuggable: " + proc);
13631                    }
13632                }
13633
13634                proc.thread.dumpHeap(managed, path, fd);
13635                fd = null;
13636                return true;
13637            }
13638        } catch (RemoteException e) {
13639            throw new IllegalStateException("Process disappeared");
13640        } finally {
13641            if (fd != null) {
13642                try {
13643                    fd.close();
13644                } catch (IOException e) {
13645                }
13646            }
13647        }
13648    }
13649
13650    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13651    public void monitor() {
13652        synchronized (this) { }
13653    }
13654
13655    public void onCoreSettingsChange(Bundle settings) {
13656        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13657            ProcessRecord processRecord = mLruProcesses.get(i);
13658            try {
13659                if (processRecord.thread != null) {
13660                    processRecord.thread.setCoreSettings(settings);
13661                }
13662            } catch (RemoteException re) {
13663                /* ignore */
13664            }
13665        }
13666    }
13667
13668    // Multi-user methods
13669
13670    public boolean switchUser(int userid) {
13671        // TODO
13672        return true;
13673    }
13674}
13675