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.internal.os.ProcessStats;
22import com.android.server.AttributeCache;
23import com.android.server.IntentResolver;
24import com.android.server.ProcessMap;
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.Instrumentation;
49import android.app.Notification;
50import android.app.NotificationManager;
51import android.app.PendingIntent;
52import android.app.Service;
53import android.app.backup.IBackupManager;
54import android.content.ActivityNotFoundException;
55import android.content.BroadcastReceiver;
56import android.content.ComponentCallbacks2;
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.text.format.Time;
109import android.util.EventLog;
110import android.util.Pair;
111import android.util.Slog;
112import android.util.Log;
113import android.util.PrintWriterPrinter;
114import android.util.SparseArray;
115import android.util.TimeUtils;
116import android.view.Gravity;
117import android.view.LayoutInflater;
118import android.view.View;
119import android.view.WindowManager;
120import android.view.WindowManagerPolicy;
121
122import java.io.BufferedInputStream;
123import java.io.BufferedOutputStream;
124import java.io.BufferedReader;
125import java.io.DataInputStream;
126import java.io.DataOutputStream;
127import java.io.File;
128import java.io.FileDescriptor;
129import java.io.FileInputStream;
130import java.io.FileNotFoundException;
131import java.io.FileOutputStream;
132import java.io.IOException;
133import java.io.InputStreamReader;
134import java.io.PrintWriter;
135import java.io.StringWriter;
136import java.lang.IllegalStateException;
137import java.lang.ref.WeakReference;
138import java.util.ArrayList;
139import java.util.Collections;
140import java.util.Comparator;
141import java.util.HashMap;
142import java.util.HashSet;
143import java.util.Iterator;
144import java.util.List;
145import java.util.Locale;
146import java.util.Map;
147import java.util.Set;
148import java.util.concurrent.atomic.AtomicBoolean;
149import java.util.concurrent.atomic.AtomicLong;
150
151public final class ActivityManagerService extends ActivityManagerNative
152        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
153    static final String TAG = "ActivityManager";
154    static final boolean DEBUG = false;
155    static final boolean localLOGV = DEBUG;
156    static final boolean DEBUG_SWITCH = localLOGV || false;
157    static final boolean DEBUG_TASKS = localLOGV || false;
158    static final boolean DEBUG_PAUSE = localLOGV || false;
159    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
160    static final boolean DEBUG_TRANSITION = localLOGV || false;
161    static final boolean DEBUG_BROADCAST = localLOGV || false;
162    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
163    static final boolean DEBUG_SERVICE = localLOGV || false;
164    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
165    static final boolean DEBUG_VISBILITY = localLOGV || false;
166    static final boolean DEBUG_PROCESSES = localLOGV || false;
167    static final boolean DEBUG_PROVIDER = localLOGV || false;
168    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
169    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
170    static final boolean DEBUG_RESULTS = localLOGV || false;
171    static final boolean DEBUG_BACKUP = localLOGV || false;
172    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
173    static final boolean DEBUG_POWER = localLOGV || false;
174    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
175    static final boolean VALIDATE_TOKENS = false;
176    static final boolean SHOW_ACTIVITY_START_TIME = true;
177
178    // Control over CPU and battery monitoring.
179    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
180    static final boolean MONITOR_CPU_USAGE = true;
181    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
182    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
183    static final boolean MONITOR_THREAD_CPU_USAGE = false;
184
185    // The flags that are set for all calls we make to the package manager.
186    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
187
188    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
189
190    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
191
192    // Maximum number of recent tasks that we can remember.
193    static final int MAX_RECENT_TASKS = 20;
194
195    // Amount of time after a call to stopAppSwitches() during which we will
196    // prevent further untrusted switches from happening.
197    static final long APP_SWITCH_DELAY_TIME = 5*1000;
198
199    // How long we wait for a launched process to attach to the activity manager
200    // before we decide it's never going to come up for real.
201    static final int PROC_START_TIMEOUT = 10*1000;
202
203    // How long we wait for a launched process to attach to the activity manager
204    // before we decide it's never going to come up for real, when the process was
205    // started with a wrapper for instrumentation (such as Valgrind) because it
206    // could take much longer than usual.
207    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
208
209    // How long to wait after going idle before forcing apps to GC.
210    static final int GC_TIMEOUT = 5*1000;
211
212    // The minimum amount of time between successive GC requests for a process.
213    static final int GC_MIN_INTERVAL = 60*1000;
214
215    // The rate at which we check for apps using excessive power -- 15 mins.
216    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
217
218    // The minimum sample duration we will allow before deciding we have
219    // enough data on wake locks to start killing things.
220    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
221
222    // The minimum sample duration we will allow before deciding we have
223    // enough data on CPU usage to start killing things.
224    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
225
226    // How long we allow a receiver to run before giving up on it.
227    static final int BROADCAST_TIMEOUT = 10*1000;
228
229    // How long we wait for a service to finish executing.
230    static final int SERVICE_TIMEOUT = 20*1000;
231
232    // How long a service needs to be running until restarting its process
233    // is no longer considered to be a relaunch of the service.
234    static final int SERVICE_RESTART_DURATION = 5*1000;
235
236    // How long a service needs to be running until it will start back at
237    // SERVICE_RESTART_DURATION after being killed.
238    static final int SERVICE_RESET_RUN_DURATION = 60*1000;
239
240    // Multiplying factor to increase restart duration time by, for each time
241    // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
242    static final int SERVICE_RESTART_DURATION_FACTOR = 4;
243
244    // The minimum amount of time between restarting services that we allow.
245    // That is, when multiple services are restarting, we won't allow each
246    // to restart less than this amount of time from the last one.
247    static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
248
249    // Maximum amount of time for there to be no activity on a service before
250    // we consider it non-essential and allow its process to go on the
251    // LRU background list.
252    static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
253
254    // How long we wait until we timeout on key dispatching.
255    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
256
257    // How long we wait until we timeout on key dispatching during instrumentation.
258    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
259
260    static final int MY_PID = Process.myPid();
261
262    static final String[] EMPTY_STRING_ARRAY = new String[0];
263
264    public ActivityStack mMainStack;
265
266    /**
267     * Description of a request to start a new activity, which has been held
268     * due to app switches being disabled.
269     */
270    static class PendingActivityLaunch {
271        ActivityRecord r;
272        ActivityRecord sourceRecord;
273        Uri[] grantedUriPermissions;
274        int grantedMode;
275        boolean onlyIfNeeded;
276    }
277
278    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
279            = new ArrayList<PendingActivityLaunch>();
280
281    /**
282     * List of all active broadcasts that are to be executed immediately
283     * (without waiting for another broadcast to finish).  Currently this only
284     * contains broadcasts to registered receivers, to avoid spinning up
285     * a bunch of processes to execute IntentReceiver components.
286     */
287    final ArrayList<BroadcastRecord> mParallelBroadcasts
288            = new ArrayList<BroadcastRecord>();
289
290    /**
291     * List of all active broadcasts that are to be executed one at a time.
292     * The object at the top of the list is the currently activity broadcasts;
293     * those after it are waiting for the top to finish..
294     */
295    final ArrayList<BroadcastRecord> mOrderedBroadcasts
296            = new ArrayList<BroadcastRecord>();
297
298    /**
299     * Historical data of past broadcasts, for debugging.
300     */
301    static final int MAX_BROADCAST_HISTORY = 25;
302    final BroadcastRecord[] mBroadcastHistory
303            = new BroadcastRecord[MAX_BROADCAST_HISTORY];
304
305    /**
306     * Set when we current have a BROADCAST_INTENT_MSG in flight.
307     */
308    boolean mBroadcastsScheduled = false;
309
310    /**
311     * Activity we have told the window manager to have key focus.
312     */
313    ActivityRecord mFocusedActivity = null;
314    /**
315     * List of intents that were used to start the most recent tasks.
316     */
317    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
318
319    /**
320     * Process management.
321     */
322    final ProcessList mProcessList = new ProcessList();
323
324    /**
325     * All of the applications we currently have running organized by name.
326     * The keys are strings of the application package name (as
327     * returned by the package manager), and the keys are ApplicationRecord
328     * objects.
329     */
330    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
331
332    /**
333     * The currently running heavy-weight process, if any.
334     */
335    ProcessRecord mHeavyWeightProcess = null;
336
337    /**
338     * The last time that various processes have crashed.
339     */
340    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
341
342    /**
343     * Set of applications that we consider to be bad, and will reject
344     * incoming broadcasts from (which the user has no control over).
345     * Processes are added to this set when they have crashed twice within
346     * a minimum amount of time; they are removed from it when they are
347     * later restarted (hopefully due to some user action).  The value is the
348     * time it was added to the list.
349     */
350    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
351
352    /**
353     * All of the processes we currently have running organized by pid.
354     * The keys are the pid running the application.
355     *
356     * <p>NOTE: This object is protected by its own lock, NOT the global
357     * activity manager lock!
358     */
359    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
360
361    /**
362     * All of the processes that have been forced to be foreground.  The key
363     * is the pid of the caller who requested it (we hold a death
364     * link on it).
365     */
366    abstract class ForegroundToken implements IBinder.DeathRecipient {
367        int pid;
368        IBinder token;
369    }
370    final SparseArray<ForegroundToken> mForegroundProcesses
371            = new SparseArray<ForegroundToken>();
372
373    /**
374     * List of records for processes that someone had tried to start before the
375     * system was ready.  We don't start them at that point, but ensure they
376     * are started by the time booting is complete.
377     */
378    final ArrayList<ProcessRecord> mProcessesOnHold
379            = new ArrayList<ProcessRecord>();
380
381    /**
382     * List of persistent applications that are in the process
383     * of being started.
384     */
385    final ArrayList<ProcessRecord> mPersistentStartingProcesses
386            = new ArrayList<ProcessRecord>();
387
388    /**
389     * Processes that are being forcibly torn down.
390     */
391    final ArrayList<ProcessRecord> mRemovedProcesses
392            = new ArrayList<ProcessRecord>();
393
394    /**
395     * List of running applications, sorted by recent usage.
396     * The first entry in the list is the least recently used.
397     * It contains ApplicationRecord objects.  This list does NOT include
398     * any persistent application records (since we never want to exit them).
399     */
400    final ArrayList<ProcessRecord> mLruProcesses
401            = new ArrayList<ProcessRecord>();
402
403    /**
404     * List of processes that should gc as soon as things are idle.
405     */
406    final ArrayList<ProcessRecord> mProcessesToGc
407            = new ArrayList<ProcessRecord>();
408
409    /**
410     * This is the process holding what we currently consider to be
411     * the "home" activity.
412     */
413    ProcessRecord mHomeProcess;
414
415    /**
416     * This is the process holding the activity the user last visited that
417     * is in a different process from the one they are currently in.
418     */
419    ProcessRecord mPreviousProcess;
420
421    /**
422     * The time at which the previous process was last visible.
423     */
424    long mPreviousProcessVisibleTime;
425
426    /**
427     * Packages that the user has asked to have run in screen size
428     * compatibility mode instead of filling the screen.
429     */
430    final CompatModePackages mCompatModePackages;
431
432    /**
433     * Set of PendingResultRecord objects that are currently active.
434     */
435    final HashSet mPendingResultRecords = new HashSet();
436
437    /**
438     * Set of IntentSenderRecord objects that are currently active.
439     */
440    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
441            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
442
443    /**
444     * Fingerprints (hashCode()) of stack traces that we've
445     * already logged DropBox entries for.  Guarded by itself.  If
446     * something (rogue user app) forces this over
447     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
448     */
449    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
450    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
451
452    /**
453     * Strict Mode background batched logging state.
454     *
455     * The string buffer is guarded by itself, and its lock is also
456     * used to determine if another batched write is already
457     * in-flight.
458     */
459    private final StringBuilder mStrictModeBuffer = new StringBuilder();
460
461    /**
462     * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
463     */
464    private boolean mPendingBroadcastTimeoutMessage;
465
466    /**
467     * Intent broadcast that we have tried to start, but are
468     * waiting for its application's process to be created.  We only
469     * need one (instead of a list) because we always process broadcasts
470     * one at a time, so no others can be started while waiting for this
471     * one.
472     */
473    BroadcastRecord mPendingBroadcast = null;
474
475    /**
476     * The receiver index that is pending, to restart the broadcast if needed.
477     */
478    int mPendingBroadcastRecvIndex;
479
480    /**
481     * Keeps track of all IIntentReceivers that have been registered for
482     * broadcasts.  Hash keys are the receiver IBinder, hash value is
483     * a ReceiverList.
484     */
485    final HashMap mRegisteredReceivers = new HashMap();
486
487    /**
488     * Resolver for broadcast intents to registered receivers.
489     * Holds BroadcastFilter (subclass of IntentFilter).
490     */
491    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
492            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
493        @Override
494        protected boolean allowFilterResult(
495                BroadcastFilter filter, List<BroadcastFilter> dest) {
496            IBinder target = filter.receiverList.receiver.asBinder();
497            for (int i=dest.size()-1; i>=0; i--) {
498                if (dest.get(i).receiverList.receiver.asBinder() == target) {
499                    return false;
500                }
501            }
502            return true;
503        }
504
505        @Override
506        protected String packageForFilter(BroadcastFilter filter) {
507            return filter.packageName;
508        }
509    };
510
511    /**
512     * State of all active sticky broadcasts.  Keys are the action of the
513     * sticky Intent, values are an ArrayList of all broadcasted intents with
514     * that action (which should usually be one).
515     */
516    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
517            new HashMap<String, ArrayList<Intent>>();
518
519    /**
520     * All currently running services.
521     */
522    final HashMap<ComponentName, ServiceRecord> mServices =
523        new HashMap<ComponentName, ServiceRecord>();
524
525    /**
526     * All currently running services indexed by the Intent used to start them.
527     */
528    final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
529        new HashMap<Intent.FilterComparison, ServiceRecord>();
530
531    /**
532     * All currently bound service connections.  Keys are the IBinder of
533     * the client's IServiceConnection.
534     */
535    final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
536            = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
537
538    /**
539     * List of services that we have been asked to start,
540     * but haven't yet been able to.  It is used to hold start requests
541     * while waiting for their corresponding application thread to get
542     * going.
543     */
544    final ArrayList<ServiceRecord> mPendingServices
545            = new ArrayList<ServiceRecord>();
546
547    /**
548     * List of services that are scheduled to restart following a crash.
549     */
550    final ArrayList<ServiceRecord> mRestartingServices
551            = new ArrayList<ServiceRecord>();
552
553    /**
554     * List of services that are in the process of being stopped.
555     */
556    final ArrayList<ServiceRecord> mStoppingServices
557            = new ArrayList<ServiceRecord>();
558
559    /**
560     * Backup/restore process management
561     */
562    String mBackupAppName = null;
563    BackupRecord mBackupTarget = null;
564
565    /**
566     * List of PendingThumbnailsRecord objects of clients who are still
567     * waiting to receive all of the thumbnails for a task.
568     */
569    final ArrayList mPendingThumbnails = new ArrayList();
570
571    /**
572     * List of HistoryRecord objects that have been finished and must
573     * still report back to a pending thumbnail receiver.
574     */
575    final ArrayList mCancelledThumbnails = new ArrayList();
576
577    /**
578     * All of the currently running global content providers.  Keys are a
579     * string containing the provider name and values are a
580     * ContentProviderRecord object containing the data about it.  Note
581     * that a single provider may be published under multiple names, so
582     * there may be multiple entries here for a single one in mProvidersByClass.
583     */
584    final HashMap<String, ContentProviderRecord> mProvidersByName
585            = new HashMap<String, ContentProviderRecord>();
586
587    /**
588     * All of the currently running global content providers.  Keys are a
589     * string containing the provider's implementation class and values are a
590     * ContentProviderRecord object containing the data about it.
591     */
592    final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
593            = new HashMap<ComponentName, ContentProviderRecord>();
594
595    /**
596     * List of content providers who have clients waiting for them.  The
597     * application is currently being launched and the provider will be
598     * removed from this list once it is published.
599     */
600    final ArrayList<ContentProviderRecord> mLaunchingProviders
601            = new ArrayList<ContentProviderRecord>();
602
603    /**
604     * Global set of specific Uri permissions that have been granted.
605     */
606    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
607            = new SparseArray<HashMap<Uri, UriPermission>>();
608
609    CoreSettingsObserver mCoreSettingsObserver;
610
611    /**
612     * Thread-local storage used to carry caller permissions over through
613     * indirect content-provider access.
614     * @see #ActivityManagerService.openContentUri()
615     */
616    private class Identity {
617        public int pid;
618        public int uid;
619
620        Identity(int _pid, int _uid) {
621            pid = _pid;
622            uid = _uid;
623        }
624    }
625    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
626
627    /**
628     * All information we have collected about the runtime performance of
629     * any user id that can impact battery performance.
630     */
631    final BatteryStatsService mBatteryStatsService;
632
633    /**
634     * information about component usage
635     */
636    final UsageStatsService mUsageStatsService;
637
638    /**
639     * Current configuration information.  HistoryRecord objects are given
640     * a reference to this object to indicate which configuration they are
641     * currently running in, so this object must be kept immutable.
642     */
643    Configuration mConfiguration = new Configuration();
644
645    /**
646     * Current sequencing integer of the configuration, for skipping old
647     * configurations.
648     */
649    int mConfigurationSeq = 0;
650
651    /**
652     * Hardware-reported OpenGLES version.
653     */
654    final int GL_ES_VERSION;
655
656    /**
657     * List of initialization arguments to pass to all processes when binding applications to them.
658     * For example, references to the commonly used services.
659     */
660    HashMap<String, IBinder> mAppBindArgs;
661
662    /**
663     * Temporary to avoid allocations.  Protected by main lock.
664     */
665    final StringBuilder mStringBuilder = new StringBuilder(256);
666
667    /**
668     * Used to control how we initialize the service.
669     */
670    boolean mStartRunning = false;
671    ComponentName mTopComponent;
672    String mTopAction;
673    String mTopData;
674    boolean mProcessesReady = false;
675    boolean mSystemReady = false;
676    boolean mBooting = false;
677    boolean mWaitingUpdate = false;
678    boolean mDidUpdate = false;
679    boolean mOnBattery = false;
680    boolean mLaunchWarningShown = false;
681
682    Context mContext;
683
684    int mFactoryTest;
685
686    boolean mCheckedForSetup;
687
688    /**
689     * The time at which we will allow normal application switches again,
690     * after a call to {@link #stopAppSwitches()}.
691     */
692    long mAppSwitchesAllowedTime;
693
694    /**
695     * This is set to true after the first switch after mAppSwitchesAllowedTime
696     * is set; any switches after that will clear the time.
697     */
698    boolean mDidAppSwitch;
699
700    /**
701     * Last time (in realtime) at which we checked for power usage.
702     */
703    long mLastPowerCheckRealtime;
704
705    /**
706     * Last time (in uptime) at which we checked for power usage.
707     */
708    long mLastPowerCheckUptime;
709
710    /**
711     * Set while we are wanting to sleep, to prevent any
712     * activities from being started/resumed.
713     */
714    boolean mSleeping = false;
715
716    /**
717     * Set if we are shutting down the system, similar to sleeping.
718     */
719    boolean mShuttingDown = false;
720
721    /**
722     * Task identifier that activities are currently being started
723     * in.  Incremented each time a new task is created.
724     * todo: Replace this with a TokenSpace class that generates non-repeating
725     * integers that won't wrap.
726     */
727    int mCurTask = 1;
728
729    /**
730     * Current sequence id for oom_adj computation traversal.
731     */
732    int mAdjSeq = 0;
733
734    /**
735     * Current sequence id for process LRU updating.
736     */
737    int mLruSeq = 0;
738
739    /**
740     * Keep track of the number of service processes we last found, to
741     * determine on the next iteration which should be B services.
742     */
743    int mNumServiceProcs = 0;
744    int mNewNumServiceProcs = 0;
745
746    /**
747     * System monitoring: number of processes that died since the last
748     * N procs were started.
749     */
750    int[] mProcDeaths = new int[20];
751
752    /**
753     * This is set if we had to do a delayed dexopt of an app before launching
754     * it, to increasing the ANR timeouts in that case.
755     */
756    boolean mDidDexOpt;
757
758    String mDebugApp = null;
759    boolean mWaitForDebugger = false;
760    boolean mDebugTransient = false;
761    String mOrigDebugApp = null;
762    boolean mOrigWaitForDebugger = false;
763    boolean mAlwaysFinishActivities = false;
764    IActivityController mController = null;
765    String mProfileApp = null;
766    ProcessRecord mProfileProc = null;
767    String mProfileFile;
768    ParcelFileDescriptor mProfileFd;
769    int mProfileType = 0;
770    boolean mAutoStopProfiler = false;
771
772    final RemoteCallbackList<IActivityWatcher> mWatchers
773            = new RemoteCallbackList<IActivityWatcher>();
774
775    final RemoteCallbackList<IProcessObserver> mProcessObservers
776            = new RemoteCallbackList<IProcessObserver>();
777
778    /**
779     * Callback of last caller to {@link #requestPss}.
780     */
781    Runnable mRequestPssCallback;
782
783    /**
784     * Remaining processes for which we are waiting results from the last
785     * call to {@link #requestPss}.
786     */
787    final ArrayList<ProcessRecord> mRequestPssList
788            = new ArrayList<ProcessRecord>();
789
790    /**
791     * Runtime statistics collection thread.  This object's lock is used to
792     * protect all related state.
793     */
794    final Thread mProcessStatsThread;
795
796    /**
797     * Used to collect process stats when showing not responding dialog.
798     * Protected by mProcessStatsThread.
799     */
800    final ProcessStats mProcessStats = new ProcessStats(
801            MONITOR_THREAD_CPU_USAGE);
802    final AtomicLong mLastCpuTime = new AtomicLong(0);
803    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
804
805    long mLastWriteTime = 0;
806
807    /**
808     * Set to true after the system has finished booting.
809     */
810    boolean mBooted = false;
811
812    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
813    int mProcessLimitOverride = -1;
814
815    WindowManagerService mWindowManager;
816
817    static ActivityManagerService mSelf;
818    static ActivityThread mSystemThread;
819
820    private final class AppDeathRecipient implements IBinder.DeathRecipient {
821        final ProcessRecord mApp;
822        final int mPid;
823        final IApplicationThread mAppThread;
824
825        AppDeathRecipient(ProcessRecord app, int pid,
826                IApplicationThread thread) {
827            if (localLOGV) Slog.v(
828                TAG, "New death recipient " + this
829                + " for thread " + thread.asBinder());
830            mApp = app;
831            mPid = pid;
832            mAppThread = thread;
833        }
834
835        public void binderDied() {
836            if (localLOGV) Slog.v(
837                TAG, "Death received in " + this
838                + " for thread " + mAppThread.asBinder());
839            synchronized(ActivityManagerService.this) {
840                appDiedLocked(mApp, mPid, mAppThread);
841            }
842        }
843    }
844
845    static final int SHOW_ERROR_MSG = 1;
846    static final int SHOW_NOT_RESPONDING_MSG = 2;
847    static final int SHOW_FACTORY_ERROR_MSG = 3;
848    static final int UPDATE_CONFIGURATION_MSG = 4;
849    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
850    static final int WAIT_FOR_DEBUGGER_MSG = 6;
851    static final int BROADCAST_INTENT_MSG = 7;
852    static final int BROADCAST_TIMEOUT_MSG = 8;
853    static final int SERVICE_TIMEOUT_MSG = 12;
854    static final int UPDATE_TIME_ZONE = 13;
855    static final int SHOW_UID_ERROR_MSG = 14;
856    static final int IM_FEELING_LUCKY_MSG = 15;
857    static final int PROC_START_TIMEOUT_MSG = 20;
858    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
859    static final int KILL_APPLICATION_MSG = 22;
860    static final int FINALIZE_PENDING_INTENT_MSG = 23;
861    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
862    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
863    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
864    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
865    static final int CLEAR_DNS_CACHE = 28;
866    static final int UPDATE_HTTP_PROXY = 29;
867    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
868    static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
869    static final int DISPATCH_PROCESS_DIED = 32;
870    static final int REPORT_MEM_USAGE = 33;
871
872    AlertDialog mUidAlert;
873    CompatModeDialog mCompatModeDialog;
874    long mLastMemUsageReportTime = 0;
875
876    final Handler mHandler = new Handler() {
877        //public Handler() {
878        //    if (localLOGV) Slog.v(TAG, "Handler started!");
879        //}
880
881        public void handleMessage(Message msg) {
882            switch (msg.what) {
883            case SHOW_ERROR_MSG: {
884                HashMap data = (HashMap) msg.obj;
885                synchronized (ActivityManagerService.this) {
886                    ProcessRecord proc = (ProcessRecord)data.get("app");
887                    if (proc != null && proc.crashDialog != null) {
888                        Slog.e(TAG, "App already has crash dialog: " + proc);
889                        return;
890                    }
891                    AppErrorResult res = (AppErrorResult) data.get("result");
892                    if (!mSleeping && !mShuttingDown) {
893                        Dialog d = new AppErrorDialog(mContext, res, proc);
894                        d.show();
895                        proc.crashDialog = d;
896                    } else {
897                        // The device is asleep, so just pretend that the user
898                        // saw a crash dialog and hit "force quit".
899                        res.set(0);
900                    }
901                }
902
903                ensureBootCompleted();
904            } break;
905            case SHOW_NOT_RESPONDING_MSG: {
906                synchronized (ActivityManagerService.this) {
907                    HashMap data = (HashMap) msg.obj;
908                    ProcessRecord proc = (ProcessRecord)data.get("app");
909                    if (proc != null && proc.anrDialog != null) {
910                        Slog.e(TAG, "App already has anr dialog: " + proc);
911                        return;
912                    }
913
914                    Intent intent = new Intent("android.intent.action.ANR");
915                    if (!mProcessesReady) {
916                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
917                    }
918                    broadcastIntentLocked(null, null, intent,
919                            null, null, 0, null, null, null,
920                            false, false, MY_PID, Process.SYSTEM_UID);
921
922                    Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
923                            mContext, proc, (ActivityRecord)data.get("activity"));
924                    d.show();
925                    proc.anrDialog = d;
926                }
927
928                ensureBootCompleted();
929            } break;
930            case SHOW_STRICT_MODE_VIOLATION_MSG: {
931                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
932                synchronized (ActivityManagerService.this) {
933                    ProcessRecord proc = (ProcessRecord) data.get("app");
934                    if (proc == null) {
935                        Slog.e(TAG, "App not found when showing strict mode dialog.");
936                        break;
937                    }
938                    if (proc.crashDialog != null) {
939                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
940                        return;
941                    }
942                    AppErrorResult res = (AppErrorResult) data.get("result");
943                    if (!mSleeping && !mShuttingDown) {
944                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
945                        d.show();
946                        proc.crashDialog = d;
947                    } else {
948                        // The device is asleep, so just pretend that the user
949                        // saw a crash dialog and hit "force quit".
950                        res.set(0);
951                    }
952                }
953                ensureBootCompleted();
954            } break;
955            case SHOW_FACTORY_ERROR_MSG: {
956                Dialog d = new FactoryErrorDialog(
957                    mContext, msg.getData().getCharSequence("msg"));
958                d.show();
959                ensureBootCompleted();
960            } break;
961            case UPDATE_CONFIGURATION_MSG: {
962                final ContentResolver resolver = mContext.getContentResolver();
963                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
964            } break;
965            case GC_BACKGROUND_PROCESSES_MSG: {
966                synchronized (ActivityManagerService.this) {
967                    performAppGcsIfAppropriateLocked();
968                }
969            } break;
970            case WAIT_FOR_DEBUGGER_MSG: {
971                synchronized (ActivityManagerService.this) {
972                    ProcessRecord app = (ProcessRecord)msg.obj;
973                    if (msg.arg1 != 0) {
974                        if (!app.waitedForDebugger) {
975                            Dialog d = new AppWaitingForDebuggerDialog(
976                                    ActivityManagerService.this,
977                                    mContext, app);
978                            app.waitDialog = d;
979                            app.waitedForDebugger = true;
980                            d.show();
981                        }
982                    } else {
983                        if (app.waitDialog != null) {
984                            app.waitDialog.dismiss();
985                            app.waitDialog = null;
986                        }
987                    }
988                }
989            } break;
990            case BROADCAST_INTENT_MSG: {
991                if (DEBUG_BROADCAST) Slog.v(
992                        TAG, "Received BROADCAST_INTENT_MSG");
993                processNextBroadcast(true);
994            } break;
995            case BROADCAST_TIMEOUT_MSG: {
996                synchronized (ActivityManagerService.this) {
997                    broadcastTimeoutLocked(true);
998                }
999            } break;
1000            case SERVICE_TIMEOUT_MSG: {
1001                if (mDidDexOpt) {
1002                    mDidDexOpt = false;
1003                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1004                    nmsg.obj = msg.obj;
1005                    mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1006                    return;
1007                }
1008                serviceTimeout((ProcessRecord)msg.obj);
1009            } break;
1010            case UPDATE_TIME_ZONE: {
1011                synchronized (ActivityManagerService.this) {
1012                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1013                        ProcessRecord r = mLruProcesses.get(i);
1014                        if (r.thread != null) {
1015                            try {
1016                                r.thread.updateTimeZone();
1017                            } catch (RemoteException ex) {
1018                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1019                            }
1020                        }
1021                    }
1022                }
1023            } break;
1024            case CLEAR_DNS_CACHE: {
1025                synchronized (ActivityManagerService.this) {
1026                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1027                        ProcessRecord r = mLruProcesses.get(i);
1028                        if (r.thread != null) {
1029                            try {
1030                                r.thread.clearDnsCache();
1031                            } catch (RemoteException ex) {
1032                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1033                            }
1034                        }
1035                    }
1036                }
1037            } break;
1038            case UPDATE_HTTP_PROXY: {
1039                ProxyProperties proxy = (ProxyProperties)msg.obj;
1040                String host = "";
1041                String port = "";
1042                String exclList = "";
1043                if (proxy != null) {
1044                    host = proxy.getHost();
1045                    port = Integer.toString(proxy.getPort());
1046                    exclList = proxy.getExclusionList();
1047                }
1048                synchronized (ActivityManagerService.this) {
1049                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1050                        ProcessRecord r = mLruProcesses.get(i);
1051                        if (r.thread != null) {
1052                            try {
1053                                r.thread.setHttpProxy(host, port, exclList);
1054                            } catch (RemoteException ex) {
1055                                Slog.w(TAG, "Failed to update http proxy for: " +
1056                                        r.info.processName);
1057                            }
1058                        }
1059                    }
1060                }
1061            } break;
1062            case SHOW_UID_ERROR_MSG: {
1063                // XXX This is a temporary dialog, no need to localize.
1064                AlertDialog d = new BaseErrorDialog(mContext);
1065                d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1066                d.setCancelable(false);
1067                d.setTitle("System UIDs Inconsistent");
1068                d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
1069                d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1070                        mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1071                mUidAlert = d;
1072                d.show();
1073            } break;
1074            case IM_FEELING_LUCKY_MSG: {
1075                if (mUidAlert != null) {
1076                    mUidAlert.dismiss();
1077                    mUidAlert = null;
1078                }
1079            } break;
1080            case PROC_START_TIMEOUT_MSG: {
1081                if (mDidDexOpt) {
1082                    mDidDexOpt = false;
1083                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1084                    nmsg.obj = msg.obj;
1085                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1086                    return;
1087                }
1088                ProcessRecord app = (ProcessRecord)msg.obj;
1089                synchronized (ActivityManagerService.this) {
1090                    processStartTimedOutLocked(app);
1091                }
1092            } break;
1093            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1094                synchronized (ActivityManagerService.this) {
1095                    doPendingActivityLaunchesLocked(true);
1096                }
1097            } break;
1098            case KILL_APPLICATION_MSG: {
1099                synchronized (ActivityManagerService.this) {
1100                    int uid = msg.arg1;
1101                    boolean restart = (msg.arg2 == 1);
1102                    String pkg = (String) msg.obj;
1103                    forceStopPackageLocked(pkg, uid, restart, false, true, false);
1104                }
1105            } break;
1106            case FINALIZE_PENDING_INTENT_MSG: {
1107                ((PendingIntentRecord)msg.obj).completeFinalize();
1108            } break;
1109            case POST_HEAVY_NOTIFICATION_MSG: {
1110                INotificationManager inm = NotificationManager.getService();
1111                if (inm == null) {
1112                    return;
1113                }
1114
1115                ActivityRecord root = (ActivityRecord)msg.obj;
1116                ProcessRecord process = root.app;
1117                if (process == null) {
1118                    return;
1119                }
1120
1121                try {
1122                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1123                    String text = mContext.getString(R.string.heavy_weight_notification,
1124                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1125                    Notification notification = new Notification();
1126                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1127                    notification.when = 0;
1128                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1129                    notification.tickerText = text;
1130                    notification.defaults = 0; // please be quiet
1131                    notification.sound = null;
1132                    notification.vibrate = null;
1133                    notification.setLatestEventInfo(context, text,
1134                            mContext.getText(R.string.heavy_weight_notification_detail),
1135                            PendingIntent.getActivity(mContext, 0, root.intent,
1136                                    PendingIntent.FLAG_CANCEL_CURRENT));
1137
1138                    try {
1139                        int[] outId = new int[1];
1140                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
1141                                notification, outId);
1142                    } catch (RuntimeException e) {
1143                        Slog.w(ActivityManagerService.TAG,
1144                                "Error showing notification for heavy-weight app", e);
1145                    } catch (RemoteException e) {
1146                    }
1147                } catch (NameNotFoundException e) {
1148                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1149                }
1150            } break;
1151            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1152                INotificationManager inm = NotificationManager.getService();
1153                if (inm == null) {
1154                    return;
1155                }
1156                try {
1157                    inm.cancelNotification("android",
1158                            R.string.heavy_weight_notification);
1159                } catch (RuntimeException e) {
1160                    Slog.w(ActivityManagerService.TAG,
1161                            "Error canceling notification for service", e);
1162                } catch (RemoteException e) {
1163                }
1164            } break;
1165            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1166                synchronized (ActivityManagerService.this) {
1167                    checkExcessivePowerUsageLocked(true);
1168                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1169                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1170                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1171                }
1172            } break;
1173            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1174                synchronized (ActivityManagerService.this) {
1175                    ActivityRecord ar = (ActivityRecord)msg.obj;
1176                    if (mCompatModeDialog != null) {
1177                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1178                                ar.info.applicationInfo.packageName)) {
1179                            return;
1180                        }
1181                        mCompatModeDialog.dismiss();
1182                        mCompatModeDialog = null;
1183                    }
1184                    if (ar != null && false) {
1185                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1186                                ar.packageName)) {
1187                            int mode = mCompatModePackages.computeCompatModeLocked(
1188                                    ar.info.applicationInfo);
1189                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1190                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1191                                mCompatModeDialog = new CompatModeDialog(
1192                                        ActivityManagerService.this, mContext,
1193                                        ar.info.applicationInfo);
1194                                mCompatModeDialog.show();
1195                            }
1196                        }
1197                    }
1198                }
1199                break;
1200            }
1201            case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
1202                final int pid = msg.arg1;
1203                final int uid = msg.arg2;
1204                final boolean foregroundActivities = (Boolean) msg.obj;
1205                dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
1206                break;
1207            }
1208            case DISPATCH_PROCESS_DIED: {
1209                final int pid = msg.arg1;
1210                final int uid = msg.arg2;
1211                dispatchProcessDied(pid, uid);
1212                break;
1213            }
1214            case REPORT_MEM_USAGE: {
1215                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1216                if (!isDebuggable) {
1217                    return;
1218                }
1219                synchronized (ActivityManagerService.this) {
1220                    long now = SystemClock.uptimeMillis();
1221                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1222                        // Don't report more than every 5 minutes to somewhat
1223                        // avoid spamming.
1224                        return;
1225                    }
1226                    mLastMemUsageReportTime = now;
1227                }
1228                Thread thread = new Thread() {
1229                    @Override public void run() {
1230                        StringBuilder dropBuilder = new StringBuilder(1024);
1231                        StringBuilder logBuilder = new StringBuilder(1024);
1232                        StringWriter oomSw = new StringWriter();
1233                        PrintWriter oomPw = new PrintWriter(oomSw);
1234                        StringWriter catSw = new StringWriter();
1235                        PrintWriter catPw = new PrintWriter(catSw);
1236                        String[] emptyArgs = new String[] { };
1237                        StringBuilder tag = new StringBuilder(128);
1238                        StringBuilder stack = new StringBuilder(128);
1239                        tag.append("Low on memory -- ");
1240                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1241                                tag, stack);
1242                        dropBuilder.append(stack);
1243                        dropBuilder.append('\n');
1244                        dropBuilder.append('\n');
1245                        String oomString = oomSw.toString();
1246                        dropBuilder.append(oomString);
1247                        dropBuilder.append('\n');
1248                        logBuilder.append(oomString);
1249                        try {
1250                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1251                                    "procrank", });
1252                            final InputStreamReader converter = new InputStreamReader(
1253                                    proc.getInputStream());
1254                            BufferedReader in = new BufferedReader(converter);
1255                            String line;
1256                            while (true) {
1257                                line = in.readLine();
1258                                if (line == null) {
1259                                    break;
1260                                }
1261                                if (line.length() > 0) {
1262                                    logBuilder.append(line);
1263                                    logBuilder.append('\n');
1264                                }
1265                                dropBuilder.append(line);
1266                                dropBuilder.append('\n');
1267                            }
1268                            converter.close();
1269                        } catch (IOException e) {
1270                        }
1271                        synchronized (ActivityManagerService.this) {
1272                            catPw.println();
1273                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1274                            catPw.println();
1275                            dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null);
1276                            catPw.println();
1277                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1278                        }
1279                        dropBuilder.append(catSw.toString());
1280                        addErrorToDropBox("lowmem", null, "system_server", null,
1281                                null, tag.toString(), dropBuilder.toString(), null, null);
1282                        Slog.i(TAG, logBuilder.toString());
1283                        synchronized (ActivityManagerService.this) {
1284                            long now = SystemClock.uptimeMillis();
1285                            if (mLastMemUsageReportTime < now) {
1286                                mLastMemUsageReportTime = now;
1287                            }
1288                        }
1289                    }
1290                };
1291                thread.start();
1292                break;
1293            }
1294            }
1295        }
1296    };
1297
1298    public static void setSystemProcess() {
1299        try {
1300            ActivityManagerService m = mSelf;
1301
1302            ServiceManager.addService("activity", m);
1303            ServiceManager.addService("meminfo", new MemBinder(m));
1304            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1305            if (MONITOR_CPU_USAGE) {
1306                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1307            }
1308            ServiceManager.addService("permission", new PermissionController(m));
1309
1310            ApplicationInfo info =
1311                mSelf.mContext.getPackageManager().getApplicationInfo(
1312                        "android", STOCK_PM_FLAGS);
1313            mSystemThread.installSystemApplicationInfo(info);
1314
1315            synchronized (mSelf) {
1316                ProcessRecord app = mSelf.newProcessRecordLocked(
1317                        mSystemThread.getApplicationThread(), info,
1318                        info.processName);
1319                app.persistent = true;
1320                app.pid = MY_PID;
1321                app.maxAdj = ProcessList.SYSTEM_ADJ;
1322                mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1323                synchronized (mSelf.mPidsSelfLocked) {
1324                    mSelf.mPidsSelfLocked.put(app.pid, app);
1325                }
1326                mSelf.updateLruProcessLocked(app, true, true);
1327            }
1328        } catch (PackageManager.NameNotFoundException e) {
1329            throw new RuntimeException(
1330                    "Unable to find android system package", e);
1331        }
1332    }
1333
1334    public void setWindowManager(WindowManagerService wm) {
1335        mWindowManager = wm;
1336    }
1337
1338    public static final Context main(int factoryTest) {
1339        AThread thr = new AThread();
1340        thr.start();
1341
1342        synchronized (thr) {
1343            while (thr.mService == null) {
1344                try {
1345                    thr.wait();
1346                } catch (InterruptedException e) {
1347                }
1348            }
1349        }
1350
1351        ActivityManagerService m = thr.mService;
1352        mSelf = m;
1353        ActivityThread at = ActivityThread.systemMain();
1354        mSystemThread = at;
1355        Context context = at.getSystemContext();
1356        context.setTheme(android.R.style.Theme_Holo);
1357        m.mContext = context;
1358        m.mFactoryTest = factoryTest;
1359        m.mMainStack = new ActivityStack(m, context, true);
1360
1361        m.mBatteryStatsService.publish(context);
1362        m.mUsageStatsService.publish(context);
1363
1364        synchronized (thr) {
1365            thr.mReady = true;
1366            thr.notifyAll();
1367        }
1368
1369        m.startRunning(null, null, null, null);
1370
1371        return context;
1372    }
1373
1374    public static ActivityManagerService self() {
1375        return mSelf;
1376    }
1377
1378    static class AThread extends Thread {
1379        ActivityManagerService mService;
1380        boolean mReady = false;
1381
1382        public AThread() {
1383            super("ActivityManager");
1384        }
1385
1386        public void run() {
1387            Looper.prepare();
1388
1389            android.os.Process.setThreadPriority(
1390                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1391            android.os.Process.setCanSelfBackground(false);
1392
1393            ActivityManagerService m = new ActivityManagerService();
1394
1395            synchronized (this) {
1396                mService = m;
1397                notifyAll();
1398            }
1399
1400            synchronized (this) {
1401                while (!mReady) {
1402                    try {
1403                        wait();
1404                    } catch (InterruptedException e) {
1405                    }
1406                }
1407            }
1408
1409            // For debug builds, log event loop stalls to dropbox for analysis.
1410            if (StrictMode.conditionallyEnableDebugLogging()) {
1411                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1412            }
1413
1414            Looper.loop();
1415        }
1416    }
1417
1418    static class MemBinder extends Binder {
1419        ActivityManagerService mActivityManagerService;
1420        MemBinder(ActivityManagerService activityManagerService) {
1421            mActivityManagerService = activityManagerService;
1422        }
1423
1424        @Override
1425        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1426            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1427                    != PackageManager.PERMISSION_GRANTED) {
1428                pw.println("Permission Denial: can't dump meminfo from from pid="
1429                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1430                        + " without permission " + android.Manifest.permission.DUMP);
1431                return;
1432            }
1433
1434            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1435                    false, null, null, null);
1436        }
1437    }
1438
1439    static class GraphicsBinder extends Binder {
1440        ActivityManagerService mActivityManagerService;
1441        GraphicsBinder(ActivityManagerService activityManagerService) {
1442            mActivityManagerService = activityManagerService;
1443        }
1444
1445        @Override
1446        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1447            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1448                    != PackageManager.PERMISSION_GRANTED) {
1449                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1450                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1451                        + " without permission " + android.Manifest.permission.DUMP);
1452                return;
1453            }
1454
1455            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1456        }
1457    }
1458
1459    static class CpuBinder extends Binder {
1460        ActivityManagerService mActivityManagerService;
1461        CpuBinder(ActivityManagerService activityManagerService) {
1462            mActivityManagerService = activityManagerService;
1463        }
1464
1465        @Override
1466        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1467            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1468                    != PackageManager.PERMISSION_GRANTED) {
1469                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1470                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1471                        + " without permission " + android.Manifest.permission.DUMP);
1472                return;
1473            }
1474
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        mConfigurationSeq = mConfiguration.seq = 1;
1506        mProcessStats.init();
1507
1508        mCompatModePackages = new CompatModePackages(this, systemDir);
1509
1510        // Add ourself to the Watchdog monitors.
1511        Watchdog.getInstance().addMonitor(this);
1512
1513        mProcessStatsThread = new Thread("ProcessStats") {
1514            public void run() {
1515                while (true) {
1516                    try {
1517                        try {
1518                            synchronized(this) {
1519                                final long now = SystemClock.uptimeMillis();
1520                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1521                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1522                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1523                                //        + ", write delay=" + nextWriteDelay);
1524                                if (nextWriteDelay < nextCpuDelay) {
1525                                    nextCpuDelay = nextWriteDelay;
1526                                }
1527                                if (nextCpuDelay > 0) {
1528                                    mProcessStatsMutexFree.set(true);
1529                                    this.wait(nextCpuDelay);
1530                                }
1531                            }
1532                        } catch (InterruptedException e) {
1533                        }
1534                        updateCpuStatsNow();
1535                    } catch (Exception e) {
1536                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1537                    }
1538                }
1539            }
1540        };
1541        mProcessStatsThread.start();
1542    }
1543
1544    @Override
1545    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1546            throws RemoteException {
1547        try {
1548            return super.onTransact(code, data, reply, flags);
1549        } catch (RuntimeException e) {
1550            // The activity manager only throws security exceptions, so let's
1551            // log all others.
1552            if (!(e instanceof SecurityException)) {
1553                Slog.e(TAG, "Activity Manager Crash", e);
1554            }
1555            throw e;
1556        }
1557    }
1558
1559    void updateCpuStats() {
1560        final long now = SystemClock.uptimeMillis();
1561        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1562            return;
1563        }
1564        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1565            synchronized (mProcessStatsThread) {
1566                mProcessStatsThread.notify();
1567            }
1568        }
1569    }
1570
1571    void updateCpuStatsNow() {
1572        synchronized (mProcessStatsThread) {
1573            mProcessStatsMutexFree.set(false);
1574            final long now = SystemClock.uptimeMillis();
1575            boolean haveNewCpuStats = false;
1576
1577            if (MONITOR_CPU_USAGE &&
1578                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1579                mLastCpuTime.set(now);
1580                haveNewCpuStats = true;
1581                mProcessStats.update();
1582                //Slog.i(TAG, mProcessStats.printCurrentState());
1583                //Slog.i(TAG, "Total CPU usage: "
1584                //        + mProcessStats.getTotalCpuPercent() + "%");
1585
1586                // Slog the cpu usage if the property is set.
1587                if ("true".equals(SystemProperties.get("events.cpu"))) {
1588                    int user = mProcessStats.getLastUserTime();
1589                    int system = mProcessStats.getLastSystemTime();
1590                    int iowait = mProcessStats.getLastIoWaitTime();
1591                    int irq = mProcessStats.getLastIrqTime();
1592                    int softIrq = mProcessStats.getLastSoftIrqTime();
1593                    int idle = mProcessStats.getLastIdleTime();
1594
1595                    int total = user + system + iowait + irq + softIrq + idle;
1596                    if (total == 0) total = 1;
1597
1598                    EventLog.writeEvent(EventLogTags.CPU,
1599                            ((user+system+iowait+irq+softIrq) * 100) / total,
1600                            (user * 100) / total,
1601                            (system * 100) / total,
1602                            (iowait * 100) / total,
1603                            (irq * 100) / total,
1604                            (softIrq * 100) / total);
1605                }
1606            }
1607
1608            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1609            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1610            synchronized(bstats) {
1611                synchronized(mPidsSelfLocked) {
1612                    if (haveNewCpuStats) {
1613                        if (mOnBattery) {
1614                            int perc = bstats.startAddingCpuLocked();
1615                            int totalUTime = 0;
1616                            int totalSTime = 0;
1617                            final int N = mProcessStats.countStats();
1618                            for (int i=0; i<N; i++) {
1619                                ProcessStats.Stats st = mProcessStats.getStats(i);
1620                                if (!st.working) {
1621                                    continue;
1622                                }
1623                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1624                                int otherUTime = (st.rel_utime*perc)/100;
1625                                int otherSTime = (st.rel_stime*perc)/100;
1626                                totalUTime += otherUTime;
1627                                totalSTime += otherSTime;
1628                                if (pr != null) {
1629                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1630                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1631                                            st.rel_stime-otherSTime);
1632                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1633                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1634                                } else {
1635                                    BatteryStatsImpl.Uid.Proc ps =
1636                                            bstats.getProcessStatsLocked(st.name, st.pid);
1637                                    if (ps != null) {
1638                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1639                                                st.rel_stime-otherSTime);
1640                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1641                                    }
1642                                }
1643                            }
1644                            bstats.finishAddingCpuLocked(perc, totalUTime,
1645                                    totalSTime, cpuSpeedTimes);
1646                        }
1647                    }
1648                }
1649
1650                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1651                    mLastWriteTime = now;
1652                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1653                }
1654            }
1655        }
1656    }
1657
1658    @Override
1659    public void batteryNeedsCpuUpdate() {
1660        updateCpuStatsNow();
1661    }
1662
1663    @Override
1664    public void batteryPowerChanged(boolean onBattery) {
1665        // When plugging in, update the CPU stats first before changing
1666        // the plug state.
1667        updateCpuStatsNow();
1668        synchronized (this) {
1669            synchronized(mPidsSelfLocked) {
1670                mOnBattery = DEBUG_POWER ? true : onBattery;
1671            }
1672        }
1673    }
1674
1675    /**
1676     * Initialize the application bind args. These are passed to each
1677     * process when the bindApplication() IPC is sent to the process. They're
1678     * lazily setup to make sure the services are running when they're asked for.
1679     */
1680    private HashMap<String, IBinder> getCommonServicesLocked() {
1681        if (mAppBindArgs == null) {
1682            mAppBindArgs = new HashMap<String, IBinder>();
1683
1684            // Setup the application init args
1685            mAppBindArgs.put("package", ServiceManager.getService("package"));
1686            mAppBindArgs.put("window", ServiceManager.getService("window"));
1687            mAppBindArgs.put(Context.ALARM_SERVICE,
1688                    ServiceManager.getService(Context.ALARM_SERVICE));
1689        }
1690        return mAppBindArgs;
1691    }
1692
1693    final void setFocusedActivityLocked(ActivityRecord r) {
1694        if (mFocusedActivity != r) {
1695            mFocusedActivity = r;
1696            if (r != null) {
1697                mWindowManager.setFocusedApp(r.appToken, true);
1698            }
1699        }
1700    }
1701
1702    private final void updateLruProcessInternalLocked(ProcessRecord app,
1703            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1704        // put it on the LRU to keep track of when it should be exited.
1705        int lrui = mLruProcesses.indexOf(app);
1706        if (lrui >= 0) mLruProcesses.remove(lrui);
1707
1708        int i = mLruProcesses.size()-1;
1709        int skipTop = 0;
1710
1711        app.lruSeq = mLruSeq;
1712
1713        // compute the new weight for this process.
1714        if (updateActivityTime) {
1715            app.lastActivityTime = SystemClock.uptimeMillis();
1716        }
1717        if (app.activities.size() > 0) {
1718            // If this process has activities, we more strongly want to keep
1719            // it around.
1720            app.lruWeight = app.lastActivityTime;
1721        } else if (app.pubProviders.size() > 0) {
1722            // If this process contains content providers, we want to keep
1723            // it a little more strongly.
1724            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1725            // Also don't let it kick out the first few "real" hidden processes.
1726            skipTop = ProcessList.MIN_HIDDEN_APPS;
1727        } else {
1728            // If this process doesn't have activities, we less strongly
1729            // want to keep it around, and generally want to avoid getting
1730            // in front of any very recently used activities.
1731            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1732            // Also don't let it kick out the first few "real" hidden processes.
1733            skipTop = ProcessList.MIN_HIDDEN_APPS;
1734        }
1735
1736        while (i >= 0) {
1737            ProcessRecord p = mLruProcesses.get(i);
1738            // If this app shouldn't be in front of the first N background
1739            // apps, then skip over that many that are currently hidden.
1740            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1741                skipTop--;
1742            }
1743            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1744                mLruProcesses.add(i+1, app);
1745                break;
1746            }
1747            i--;
1748        }
1749        if (i < 0) {
1750            mLruProcesses.add(0, app);
1751        }
1752
1753        // If the app is currently using a content provider or service,
1754        // bump those processes as well.
1755        if (app.connections.size() > 0) {
1756            for (ConnectionRecord cr : app.connections) {
1757                if (cr.binding != null && cr.binding.service != null
1758                        && cr.binding.service.app != null
1759                        && cr.binding.service.app.lruSeq != mLruSeq) {
1760                    updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1761                            updateActivityTime, i+1);
1762                }
1763            }
1764        }
1765        if (app.conProviders.size() > 0) {
1766            for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1767                if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1768                    updateLruProcessInternalLocked(cpr.proc, oomAdj,
1769                            updateActivityTime, i+1);
1770                }
1771            }
1772        }
1773
1774        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1775        if (oomAdj) {
1776            updateOomAdjLocked();
1777        }
1778    }
1779
1780    final void updateLruProcessLocked(ProcessRecord app,
1781            boolean oomAdj, boolean updateActivityTime) {
1782        mLruSeq++;
1783        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1784    }
1785
1786    final ProcessRecord getProcessRecordLocked(
1787            String processName, int uid) {
1788        if (uid == Process.SYSTEM_UID) {
1789            // The system gets to run in any process.  If there are multiple
1790            // processes with the same uid, just pick the first (this
1791            // should never happen).
1792            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1793                    processName);
1794            return procs != null ? procs.valueAt(0) : null;
1795        }
1796        ProcessRecord proc = mProcessNames.get(processName, uid);
1797        return proc;
1798    }
1799
1800    void ensurePackageDexOpt(String packageName) {
1801        IPackageManager pm = AppGlobals.getPackageManager();
1802        try {
1803            if (pm.performDexOpt(packageName)) {
1804                mDidDexOpt = true;
1805            }
1806        } catch (RemoteException e) {
1807        }
1808    }
1809
1810    boolean isNextTransitionForward() {
1811        int transit = mWindowManager.getPendingAppTransition();
1812        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1813                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1814                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1815    }
1816
1817    final ProcessRecord startProcessLocked(String processName,
1818            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1819            String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
1820        ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1821        // We don't have to do anything more if:
1822        // (1) There is an existing application record; and
1823        // (2) The caller doesn't think it is dead, OR there is no thread
1824        //     object attached to it so we know it couldn't have crashed; and
1825        // (3) There is a pid assigned to it, so it is either starting or
1826        //     already running.
1827        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1828                + " app=" + app + " knownToBeDead=" + knownToBeDead
1829                + " thread=" + (app != null ? app.thread : null)
1830                + " pid=" + (app != null ? app.pid : -1));
1831        if (app != null && app.pid > 0) {
1832            if (!knownToBeDead || app.thread == null) {
1833                // We already have the app running, or are waiting for it to
1834                // come up (we have a pid but not yet its thread), so keep it.
1835                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1836                // If this is a new package in the process, add the package to the list
1837                app.addPackage(info.packageName);
1838                return app;
1839            } else {
1840                // An application record is attached to a previous process,
1841                // clean it up now.
1842                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1843                handleAppDiedLocked(app, true, true);
1844            }
1845        }
1846
1847        String hostingNameStr = hostingName != null
1848                ? hostingName.flattenToShortString() : null;
1849
1850        if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1851            // If we are in the background, then check to see if this process
1852            // is bad.  If so, we will just silently fail.
1853            if (mBadProcesses.get(info.processName, info.uid) != null) {
1854                if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1855                        + "/" + info.processName);
1856                return null;
1857            }
1858        } else {
1859            // When the user is explicitly starting a process, then clear its
1860            // crash count so that we won't make it bad until they see at
1861            // least one crash dialog again, and make the process good again
1862            // if it had been bad.
1863            if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1864                    + "/" + info.processName);
1865            mProcessCrashTimes.remove(info.processName, info.uid);
1866            if (mBadProcesses.get(info.processName, info.uid) != null) {
1867                EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1868                        info.processName);
1869                mBadProcesses.remove(info.processName, info.uid);
1870                if (app != null) {
1871                    app.bad = false;
1872                }
1873            }
1874        }
1875
1876        if (app == null) {
1877            app = newProcessRecordLocked(null, info, processName);
1878            mProcessNames.put(processName, info.uid, app);
1879        } else {
1880            // If this is a new package in the process, add the package to the list
1881            app.addPackage(info.packageName);
1882        }
1883
1884        // If the system is not ready yet, then hold off on starting this
1885        // process until it is.
1886        if (!mProcessesReady
1887                && !isAllowedWhileBooting(info)
1888                && !allowWhileBooting) {
1889            if (!mProcessesOnHold.contains(app)) {
1890                mProcessesOnHold.add(app);
1891            }
1892            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1893            return app;
1894        }
1895
1896        startProcessLocked(app, hostingType, hostingNameStr);
1897        return (app.pid != 0) ? app : null;
1898    }
1899
1900    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1901        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1902    }
1903
1904    private final void startProcessLocked(ProcessRecord app,
1905            String hostingType, String hostingNameStr) {
1906        if (app.pid > 0 && app.pid != MY_PID) {
1907            synchronized (mPidsSelfLocked) {
1908                mPidsSelfLocked.remove(app.pid);
1909                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1910            }
1911            app.pid = 0;
1912        }
1913
1914        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1915                "startProcessLocked removing on hold: " + app);
1916        mProcessesOnHold.remove(app);
1917
1918        updateCpuStats();
1919
1920        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1921        mProcDeaths[0] = 0;
1922
1923        try {
1924            int uid = app.info.uid;
1925            int[] gids = null;
1926            try {
1927                gids = mContext.getPackageManager().getPackageGids(
1928                        app.info.packageName);
1929            } catch (PackageManager.NameNotFoundException e) {
1930                Slog.w(TAG, "Unable to retrieve gids", e);
1931            }
1932            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1933                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1934                        && mTopComponent != null
1935                        && app.processName.equals(mTopComponent.getPackageName())) {
1936                    uid = 0;
1937                }
1938                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1939                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1940                    uid = 0;
1941                }
1942            }
1943            int debugFlags = 0;
1944            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1945                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1946                // Also turn on CheckJNI for debuggable apps. It's quite
1947                // awkward to turn on otherwise.
1948                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1949            }
1950            // Run the app in safe mode if its manifest requests so or the
1951            // system is booted in safe mode.
1952            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1953                Zygote.systemInSafeMode == true) {
1954                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1955            }
1956            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1957                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1958            }
1959            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1960                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1961            }
1962            if ("1".equals(SystemProperties.get("debug.assert"))) {
1963                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1964            }
1965
1966            // Start the process.  It will either succeed and return a result containing
1967            // the PID of the new process, or else throw a RuntimeException.
1968            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
1969                    app.processName, uid, uid, gids, debugFlags,
1970                    app.info.targetSdkVersion, null);
1971
1972            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1973            synchronized (bs) {
1974                if (bs.isOnBattery()) {
1975                    app.batteryStats.incStartsLocked();
1976                }
1977            }
1978
1979            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
1980                    app.processName, hostingType,
1981                    hostingNameStr != null ? hostingNameStr : "");
1982
1983            if (app.persistent) {
1984                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
1985            }
1986
1987            StringBuilder buf = mStringBuilder;
1988            buf.setLength(0);
1989            buf.append("Start proc ");
1990            buf.append(app.processName);
1991            buf.append(" for ");
1992            buf.append(hostingType);
1993            if (hostingNameStr != null) {
1994                buf.append(" ");
1995                buf.append(hostingNameStr);
1996            }
1997            buf.append(": pid=");
1998            buf.append(startResult.pid);
1999            buf.append(" uid=");
2000            buf.append(uid);
2001            buf.append(" gids={");
2002            if (gids != null) {
2003                for (int gi=0; gi<gids.length; gi++) {
2004                    if (gi != 0) buf.append(", ");
2005                    buf.append(gids[gi]);
2006
2007                }
2008            }
2009            buf.append("}");
2010            Slog.i(TAG, buf.toString());
2011            app.pid = startResult.pid;
2012            app.usingWrapper = startResult.usingWrapper;
2013            app.removed = false;
2014            synchronized (mPidsSelfLocked) {
2015                this.mPidsSelfLocked.put(startResult.pid, app);
2016                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2017                msg.obj = app;
2018                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2019                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2020            }
2021        } catch (RuntimeException e) {
2022            // XXX do better error recovery.
2023            app.pid = 0;
2024            Slog.e(TAG, "Failure starting process " + app.processName, e);
2025        }
2026    }
2027
2028    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2029        if (resumed) {
2030            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2031        } else {
2032            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2033        }
2034    }
2035
2036    boolean startHomeActivityLocked() {
2037        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2038                && mTopAction == null) {
2039            // We are running in factory test mode, but unable to find
2040            // the factory test app, so just sit around displaying the
2041            // error message and don't try to start anything.
2042            return false;
2043        }
2044        Intent intent = new Intent(
2045            mTopAction,
2046            mTopData != null ? Uri.parse(mTopData) : null);
2047        intent.setComponent(mTopComponent);
2048        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2049            intent.addCategory(Intent.CATEGORY_HOME);
2050        }
2051        ActivityInfo aInfo =
2052            intent.resolveActivityInfo(mContext.getPackageManager(),
2053                    STOCK_PM_FLAGS);
2054        if (aInfo != null) {
2055            intent.setComponent(new ComponentName(
2056                    aInfo.applicationInfo.packageName, aInfo.name));
2057            // Don't do this if the home app is currently being
2058            // instrumented.
2059            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2060                    aInfo.applicationInfo.uid);
2061            if (app == null || app.instrumentationClass == null) {
2062                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2063                mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
2064                        null, null, 0, 0, 0, false, false, null);
2065            }
2066        }
2067
2068
2069        return true;
2070    }
2071
2072    /**
2073     * Starts the "new version setup screen" if appropriate.
2074     */
2075    void startSetupActivityLocked() {
2076        // Only do this once per boot.
2077        if (mCheckedForSetup) {
2078            return;
2079        }
2080
2081        // We will show this screen if the current one is a different
2082        // version than the last one shown, and we are not running in
2083        // low-level factory test mode.
2084        final ContentResolver resolver = mContext.getContentResolver();
2085        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2086                Settings.Secure.getInt(resolver,
2087                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2088            mCheckedForSetup = true;
2089
2090            // See if we should be showing the platform update setup UI.
2091            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2092            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2093                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2094
2095            // We don't allow third party apps to replace this.
2096            ResolveInfo ri = null;
2097            for (int i=0; ris != null && i<ris.size(); i++) {
2098                if ((ris.get(i).activityInfo.applicationInfo.flags
2099                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2100                    ri = ris.get(i);
2101                    break;
2102                }
2103            }
2104
2105            if (ri != null) {
2106                String vers = ri.activityInfo.metaData != null
2107                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2108                        : null;
2109                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2110                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2111                            Intent.METADATA_SETUP_VERSION);
2112                }
2113                String lastVers = Settings.Secure.getString(
2114                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2115                if (vers != null && !vers.equals(lastVers)) {
2116                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2117                    intent.setComponent(new ComponentName(
2118                            ri.activityInfo.packageName, ri.activityInfo.name));
2119                    mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
2120                            null, null, 0, 0, 0, false, false, null);
2121                }
2122            }
2123        }
2124    }
2125
2126    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2127        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2128    }
2129
2130    public int getFrontActivityScreenCompatMode() {
2131        synchronized (this) {
2132            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2133        }
2134    }
2135
2136    public void setFrontActivityScreenCompatMode(int mode) {
2137        synchronized (this) {
2138            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2139        }
2140    }
2141
2142    public int getPackageScreenCompatMode(String packageName) {
2143        synchronized (this) {
2144            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2145        }
2146    }
2147
2148    public void setPackageScreenCompatMode(String packageName, int mode) {
2149        synchronized (this) {
2150            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2151        }
2152    }
2153
2154    public boolean getPackageAskScreenCompat(String packageName) {
2155        synchronized (this) {
2156            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2157        }
2158    }
2159
2160    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2161        synchronized (this) {
2162            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2163        }
2164    }
2165
2166    void reportResumedActivityLocked(ActivityRecord r) {
2167        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2168
2169        final int identHash = System.identityHashCode(r);
2170        updateUsageStats(r, true);
2171
2172        int i = mWatchers.beginBroadcast();
2173        while (i > 0) {
2174            i--;
2175            IActivityWatcher w = mWatchers.getBroadcastItem(i);
2176            if (w != null) {
2177                try {
2178                    w.activityResuming(identHash);
2179                } catch (RemoteException e) {
2180                }
2181            }
2182        }
2183        mWatchers.finishBroadcast();
2184    }
2185
2186    private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2187        int i = mProcessObservers.beginBroadcast();
2188        while (i > 0) {
2189            i--;
2190            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2191            if (observer != null) {
2192                try {
2193                    observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2194                } catch (RemoteException e) {
2195                }
2196            }
2197        }
2198        mProcessObservers.finishBroadcast();
2199    }
2200
2201    private void dispatchProcessDied(int pid, int uid) {
2202        int i = mProcessObservers.beginBroadcast();
2203        while (i > 0) {
2204            i--;
2205            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2206            if (observer != null) {
2207                try {
2208                    observer.onProcessDied(pid, uid);
2209                } catch (RemoteException e) {
2210                }
2211            }
2212        }
2213        mProcessObservers.finishBroadcast();
2214    }
2215
2216    final void doPendingActivityLaunchesLocked(boolean doResume) {
2217        final int N = mPendingActivityLaunches.size();
2218        if (N <= 0) {
2219            return;
2220        }
2221        for (int i=0; i<N; i++) {
2222            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2223            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2224                    pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2225                    doResume && i == (N-1));
2226        }
2227        mPendingActivityLaunches.clear();
2228    }
2229
2230    public final int startActivity(IApplicationThread caller,
2231            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2232            int grantedMode, IBinder resultTo,
2233            String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2234            String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
2235        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2236                grantedUriPermissions, grantedMode, resultTo, resultWho,
2237                requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2238                null, null);
2239    }
2240
2241    public final WaitResult startActivityAndWait(IApplicationThread caller,
2242            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2243            int grantedMode, IBinder resultTo,
2244            String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2245            String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
2246        WaitResult res = new WaitResult();
2247        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2248                grantedUriPermissions, grantedMode, resultTo, resultWho,
2249                requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2250                res, null);
2251        return res;
2252    }
2253
2254    public final int startActivityWithConfig(IApplicationThread caller,
2255            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2256            int grantedMode, IBinder resultTo,
2257            String resultWho, int requestCode, boolean onlyIfNeeded,
2258            boolean debug, Configuration config) {
2259        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2260                grantedUriPermissions, grantedMode, resultTo, resultWho,
2261                requestCode, onlyIfNeeded, debug, null, null, false, null, config);
2262    }
2263
2264    public int startActivityIntentSender(IApplicationThread caller,
2265            IntentSender intent, Intent fillInIntent, String resolvedType,
2266            IBinder resultTo, String resultWho, int requestCode,
2267            int flagsMask, int flagsValues) {
2268        // Refuse possible leaked file descriptors
2269        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2270            throw new IllegalArgumentException("File descriptors passed in Intent");
2271        }
2272
2273        IIntentSender sender = intent.getTarget();
2274        if (!(sender instanceof PendingIntentRecord)) {
2275            throw new IllegalArgumentException("Bad PendingIntent object");
2276        }
2277
2278        PendingIntentRecord pir = (PendingIntentRecord)sender;
2279
2280        synchronized (this) {
2281            // If this is coming from the currently resumed activity, it is
2282            // effectively saying that app switches are allowed at this point.
2283            if (mMainStack.mResumedActivity != null
2284                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2285                            Binder.getCallingUid()) {
2286                mAppSwitchesAllowedTime = 0;
2287            }
2288        }
2289
2290        return pir.sendInner(0, fillInIntent, resolvedType, null,
2291                null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2292    }
2293
2294    public boolean startNextMatchingActivity(IBinder callingActivity,
2295            Intent intent) {
2296        // Refuse possible leaked file descriptors
2297        if (intent != null && intent.hasFileDescriptors() == true) {
2298            throw new IllegalArgumentException("File descriptors passed in Intent");
2299        }
2300
2301        synchronized (this) {
2302            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2303            if (r == null) {
2304                return false;
2305            }
2306            if (r.app == null || r.app.thread == null) {
2307                // The caller is not running...  d'oh!
2308                return false;
2309            }
2310            intent = new Intent(intent);
2311            // The caller is not allowed to change the data.
2312            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2313            // And we are resetting to find the next component...
2314            intent.setComponent(null);
2315
2316            ActivityInfo aInfo = null;
2317            try {
2318                List<ResolveInfo> resolves =
2319                    AppGlobals.getPackageManager().queryIntentActivities(
2320                            intent, r.resolvedType,
2321                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
2322
2323                // Look for the original activity in the list...
2324                final int N = resolves != null ? resolves.size() : 0;
2325                for (int i=0; i<N; i++) {
2326                    ResolveInfo rInfo = resolves.get(i);
2327                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2328                            && rInfo.activityInfo.name.equals(r.info.name)) {
2329                        // We found the current one...  the next matching is
2330                        // after it.
2331                        i++;
2332                        if (i<N) {
2333                            aInfo = resolves.get(i).activityInfo;
2334                        }
2335                        break;
2336                    }
2337                }
2338            } catch (RemoteException e) {
2339            }
2340
2341            if (aInfo == null) {
2342                // Nobody who is next!
2343                return false;
2344            }
2345
2346            intent.setComponent(new ComponentName(
2347                    aInfo.applicationInfo.packageName, aInfo.name));
2348            intent.setFlags(intent.getFlags()&~(
2349                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2350                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2351                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2352                    Intent.FLAG_ACTIVITY_NEW_TASK));
2353
2354            // Okay now we need to start the new activity, replacing the
2355            // currently running activity.  This is a little tricky because
2356            // we want to start the new one as if the current one is finished,
2357            // but not finish the current one first so that there is no flicker.
2358            // And thus...
2359            final boolean wasFinishing = r.finishing;
2360            r.finishing = true;
2361
2362            // Propagate reply information over to the new activity.
2363            final ActivityRecord resultTo = r.resultTo;
2364            final String resultWho = r.resultWho;
2365            final int requestCode = r.requestCode;
2366            r.resultTo = null;
2367            if (resultTo != null) {
2368                resultTo.removeResultsLocked(r, resultWho, requestCode);
2369            }
2370
2371            final long origId = Binder.clearCallingIdentity();
2372            // XXX we are not dealing with propagating grantedUriPermissions...
2373            // those are not yet exposed to user code, so there is no need.
2374            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2375                    r.resolvedType, null, 0, aInfo,
2376                    resultTo != null ? resultTo.appToken : null, resultWho,
2377                    requestCode, -1, r.launchedFromUid, false, false, null);
2378            Binder.restoreCallingIdentity(origId);
2379
2380            r.finishing = wasFinishing;
2381            if (res != START_SUCCESS) {
2382                return false;
2383            }
2384            return true;
2385        }
2386    }
2387
2388    public final int startActivityInPackage(int uid,
2389            Intent intent, String resolvedType, IBinder resultTo,
2390            String resultWho, int requestCode, boolean onlyIfNeeded) {
2391
2392        // This is so super not safe, that only the system (or okay root)
2393        // can do it.
2394        final int callingUid = Binder.getCallingUid();
2395        if (callingUid != 0 && callingUid != Process.myUid()) {
2396            throw new SecurityException(
2397                    "startActivityInPackage only available to the system");
2398        }
2399
2400        return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2401                null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2402                null, null, false, null, null);
2403    }
2404
2405    public final int startActivities(IApplicationThread caller,
2406            Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2407        return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2408    }
2409
2410    public final int startActivitiesInPackage(int uid,
2411            Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2412
2413        // This is so super not safe, that only the system (or okay root)
2414        // can do it.
2415        final int callingUid = Binder.getCallingUid();
2416        if (callingUid != 0 && callingUid != Process.myUid()) {
2417            throw new SecurityException(
2418                    "startActivityInPackage only available to the system");
2419        }
2420
2421        return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
2422    }
2423
2424    final void addRecentTaskLocked(TaskRecord task) {
2425        int N = mRecentTasks.size();
2426        // Quick case: check if the top-most recent task is the same.
2427        if (N > 0 && mRecentTasks.get(0) == task) {
2428            return;
2429        }
2430        // Remove any existing entries that are the same kind of task.
2431        for (int i=0; i<N; i++) {
2432            TaskRecord tr = mRecentTasks.get(i);
2433            if ((task.affinity != null && task.affinity.equals(tr.affinity))
2434                    || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2435                mRecentTasks.remove(i);
2436                i--;
2437                N--;
2438                if (task.intent == null) {
2439                    // If the new recent task we are adding is not fully
2440                    // specified, then replace it with the existing recent task.
2441                    task = tr;
2442                }
2443            }
2444        }
2445        if (N >= MAX_RECENT_TASKS) {
2446            mRecentTasks.remove(N-1);
2447        }
2448        mRecentTasks.add(0, task);
2449    }
2450
2451    public void setRequestedOrientation(IBinder token,
2452            int requestedOrientation) {
2453        synchronized (this) {
2454            ActivityRecord r = mMainStack.isInStackLocked(token);
2455            if (r == null) {
2456                return;
2457            }
2458            final long origId = Binder.clearCallingIdentity();
2459            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2460            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2461                    mConfiguration,
2462                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2463            if (config != null) {
2464                r.frozenBeforeDestroy = true;
2465                if (!updateConfigurationLocked(config, r, false, false)) {
2466                    mMainStack.resumeTopActivityLocked(null);
2467                }
2468            }
2469            Binder.restoreCallingIdentity(origId);
2470        }
2471    }
2472
2473    public int getRequestedOrientation(IBinder token) {
2474        synchronized (this) {
2475            ActivityRecord r = mMainStack.isInStackLocked(token);
2476            if (r == null) {
2477                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2478            }
2479            return mWindowManager.getAppOrientation(r.appToken);
2480        }
2481    }
2482
2483    /**
2484     * This is the internal entry point for handling Activity.finish().
2485     *
2486     * @param token The Binder token referencing the Activity we want to finish.
2487     * @param resultCode Result code, if any, from this Activity.
2488     * @param resultData Result data (Intent), if any, from this Activity.
2489     *
2490     * @return Returns true if the activity successfully finished, or false if it is still running.
2491     */
2492    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2493        // Refuse possible leaked file descriptors
2494        if (resultData != null && resultData.hasFileDescriptors() == true) {
2495            throw new IllegalArgumentException("File descriptors passed in Intent");
2496        }
2497
2498        synchronized(this) {
2499            if (mController != null) {
2500                // Find the first activity that is not finishing.
2501                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2502                if (next != null) {
2503                    // ask watcher if this is allowed
2504                    boolean resumeOK = true;
2505                    try {
2506                        resumeOK = mController.activityResuming(next.packageName);
2507                    } catch (RemoteException e) {
2508                        mController = null;
2509                    }
2510
2511                    if (!resumeOK) {
2512                        return false;
2513                    }
2514                }
2515            }
2516            final long origId = Binder.clearCallingIdentity();
2517            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2518                    resultData, "app-request");
2519            Binder.restoreCallingIdentity(origId);
2520            return res;
2521        }
2522    }
2523
2524    public final void finishHeavyWeightApp() {
2525        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2526                != PackageManager.PERMISSION_GRANTED) {
2527            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2528                    + Binder.getCallingPid()
2529                    + ", uid=" + Binder.getCallingUid()
2530                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2531            Slog.w(TAG, msg);
2532            throw new SecurityException(msg);
2533        }
2534
2535        synchronized(this) {
2536            if (mHeavyWeightProcess == null) {
2537                return;
2538            }
2539
2540            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2541                    mHeavyWeightProcess.activities);
2542            for (int i=0; i<activities.size(); i++) {
2543                ActivityRecord r = activities.get(i);
2544                if (!r.finishing) {
2545                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2546                    if (index >= 0) {
2547                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2548                                null, "finish-heavy");
2549                    }
2550                }
2551            }
2552
2553            mHeavyWeightProcess = null;
2554            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2555        }
2556    }
2557
2558    public void crashApplication(int uid, int initialPid, String packageName,
2559            String message) {
2560        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2561                != PackageManager.PERMISSION_GRANTED) {
2562            String msg = "Permission Denial: crashApplication() from pid="
2563                    + Binder.getCallingPid()
2564                    + ", uid=" + Binder.getCallingUid()
2565                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2566            Slog.w(TAG, msg);
2567            throw new SecurityException(msg);
2568        }
2569
2570        synchronized(this) {
2571            ProcessRecord proc = null;
2572
2573            // Figure out which process to kill.  We don't trust that initialPid
2574            // still has any relation to current pids, so must scan through the
2575            // list.
2576            synchronized (mPidsSelfLocked) {
2577                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2578                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2579                    if (p.info.uid != uid) {
2580                        continue;
2581                    }
2582                    if (p.pid == initialPid) {
2583                        proc = p;
2584                        break;
2585                    }
2586                    for (String str : p.pkgList) {
2587                        if (str.equals(packageName)) {
2588                            proc = p;
2589                        }
2590                    }
2591                }
2592            }
2593
2594            if (proc == null) {
2595                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2596                        + " initialPid=" + initialPid
2597                        + " packageName=" + packageName);
2598                return;
2599            }
2600
2601            if (proc.thread != null) {
2602                if (proc.pid == Process.myPid()) {
2603                    Log.w(TAG, "crashApplication: trying to crash self!");
2604                    return;
2605                }
2606                long ident = Binder.clearCallingIdentity();
2607                try {
2608                    proc.thread.scheduleCrash(message);
2609                } catch (RemoteException e) {
2610                }
2611                Binder.restoreCallingIdentity(ident);
2612            }
2613        }
2614    }
2615
2616    public final void finishSubActivity(IBinder token, String resultWho,
2617            int requestCode) {
2618        synchronized(this) {
2619            ActivityRecord self = mMainStack.isInStackLocked(token);
2620            if (self == null) {
2621                return;
2622            }
2623
2624            final long origId = Binder.clearCallingIdentity();
2625
2626            int i;
2627            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2628                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2629                if (r.resultTo == self && r.requestCode == requestCode) {
2630                    if ((r.resultWho == null && resultWho == null) ||
2631                        (r.resultWho != null && r.resultWho.equals(resultWho))) {
2632                        mMainStack.finishActivityLocked(r, i,
2633                                Activity.RESULT_CANCELED, null, "request-sub");
2634                    }
2635                }
2636            }
2637
2638            Binder.restoreCallingIdentity(origId);
2639        }
2640    }
2641
2642    public boolean willActivityBeVisible(IBinder token) {
2643        synchronized(this) {
2644            int i;
2645            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2646                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2647                if (r.appToken == token) {
2648                    return true;
2649                }
2650                if (r.fullscreen && !r.finishing) {
2651                    return false;
2652                }
2653            }
2654            return true;
2655        }
2656    }
2657
2658    public void overridePendingTransition(IBinder token, String packageName,
2659            int enterAnim, int exitAnim) {
2660        synchronized(this) {
2661            ActivityRecord self = mMainStack.isInStackLocked(token);
2662            if (self == null) {
2663                return;
2664            }
2665
2666            final long origId = Binder.clearCallingIdentity();
2667
2668            if (self.state == ActivityState.RESUMED
2669                    || self.state == ActivityState.PAUSING) {
2670                mWindowManager.overridePendingAppTransition(packageName,
2671                        enterAnim, exitAnim);
2672            }
2673
2674            Binder.restoreCallingIdentity(origId);
2675        }
2676    }
2677
2678    /**
2679     * Main function for removing an existing process from the activity manager
2680     * as a result of that process going away.  Clears out all connections
2681     * to the process.
2682     */
2683    private final void handleAppDiedLocked(ProcessRecord app,
2684            boolean restarting, boolean allowRestart) {
2685        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2686        if (!restarting) {
2687            mLruProcesses.remove(app);
2688        }
2689
2690        if (mProfileProc == app) {
2691            clearProfilerLocked();
2692        }
2693
2694        // Just in case...
2695        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2696            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2697            mMainStack.mPausingActivity = null;
2698        }
2699        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2700            mMainStack.mLastPausedActivity = null;
2701        }
2702
2703        // Remove this application's activities from active lists.
2704        mMainStack.removeHistoryRecordsForAppLocked(app);
2705
2706        boolean atTop = true;
2707        boolean hasVisibleActivities = false;
2708
2709        // Clean out the history list.
2710        int i = mMainStack.mHistory.size();
2711        if (localLOGV) Slog.v(
2712            TAG, "Removing app " + app + " from history with " + i + " entries");
2713        while (i > 0) {
2714            i--;
2715            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2716            if (localLOGV) Slog.v(
2717                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2718            if (r.app == app) {
2719                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2720                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2721                        RuntimeException here = new RuntimeException("here");
2722                        here.fillInStackTrace();
2723                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2724                                + ": haveState=" + r.haveState
2725                                + " stateNotNeeded=" + r.stateNotNeeded
2726                                + " finishing=" + r.finishing
2727                                + " state=" + r.state, here);
2728                    }
2729                    if (!r.finishing) {
2730                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2731                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2732                                System.identityHashCode(r),
2733                                r.task.taskId, r.shortComponentName,
2734                                "proc died without state saved");
2735                    }
2736                    mMainStack.removeActivityFromHistoryLocked(r);
2737
2738                } else {
2739                    // We have the current state for this activity, so
2740                    // it can be restarted later when needed.
2741                    if (localLOGV) Slog.v(
2742                        TAG, "Keeping entry, setting app to null");
2743                    if (r.visible) {
2744                        hasVisibleActivities = true;
2745                    }
2746                    r.app = null;
2747                    r.nowVisible = false;
2748                    if (!r.haveState) {
2749                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2750                                "App died, clearing saved state of " + r);
2751                        r.icicle = null;
2752                    }
2753                }
2754
2755                r.stack.cleanUpActivityLocked(r, true, true);
2756            }
2757            atTop = false;
2758        }
2759
2760        app.activities.clear();
2761
2762        if (app.instrumentationClass != null) {
2763            Slog.w(TAG, "Crash of app " + app.processName
2764                  + " running instrumentation " + app.instrumentationClass);
2765            Bundle info = new Bundle();
2766            info.putString("shortMsg", "Process crashed.");
2767            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2768        }
2769
2770        if (!restarting) {
2771            if (!mMainStack.resumeTopActivityLocked(null)) {
2772                // If there was nothing to resume, and we are not already
2773                // restarting this process, but there is a visible activity that
2774                // is hosted by the process...  then make sure all visible
2775                // activities are running, taking care of restarting this
2776                // process.
2777                if (hasVisibleActivities) {
2778                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2779                }
2780            }
2781        }
2782    }
2783
2784    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2785        IBinder threadBinder = thread.asBinder();
2786
2787        // Find the application record.
2788        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2789            ProcessRecord rec = mLruProcesses.get(i);
2790            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2791                return i;
2792            }
2793        }
2794        return -1;
2795    }
2796
2797    final ProcessRecord getRecordForAppLocked(
2798            IApplicationThread thread) {
2799        if (thread == null) {
2800            return null;
2801        }
2802
2803        int appIndex = getLRURecordIndexForAppLocked(thread);
2804        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2805    }
2806
2807    final void appDiedLocked(ProcessRecord app, int pid,
2808            IApplicationThread thread) {
2809
2810        mProcDeaths[0]++;
2811
2812        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2813        synchronized (stats) {
2814            stats.noteProcessDiedLocked(app.info.uid, pid);
2815        }
2816
2817        // Clean up already done if the process has been re-started.
2818        if (app.pid == pid && app.thread != null &&
2819                app.thread.asBinder() == thread.asBinder()) {
2820            if (!app.killedBackground) {
2821                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2822                        + ") has died.");
2823            }
2824            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2825            if (localLOGV) Slog.v(
2826                TAG, "Dying app: " + app + ", pid: " + pid
2827                + ", thread: " + thread.asBinder());
2828            boolean doLowMem = app.instrumentationClass == null;
2829            handleAppDiedLocked(app, false, true);
2830
2831            if (doLowMem) {
2832                // If there are no longer any background processes running,
2833                // and the app that died was not running instrumentation,
2834                // then tell everyone we are now low on memory.
2835                boolean haveBg = false;
2836                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2837                    ProcessRecord rec = mLruProcesses.get(i);
2838                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2839                        haveBg = true;
2840                        break;
2841                    }
2842                }
2843
2844                if (!haveBg) {
2845                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2846                    long now = SystemClock.uptimeMillis();
2847                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2848                        ProcessRecord rec = mLruProcesses.get(i);
2849                        if (rec != app && rec.thread != null &&
2850                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2851                            // The low memory report is overriding any current
2852                            // state for a GC request.  Make sure to do
2853                            // heavy/important/visible/foreground processes first.
2854                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
2855                                rec.lastRequestedGc = 0;
2856                            } else {
2857                                rec.lastRequestedGc = rec.lastLowMemory;
2858                            }
2859                            rec.reportLowMemory = true;
2860                            rec.lastLowMemory = now;
2861                            mProcessesToGc.remove(rec);
2862                            addProcessToGcListLocked(rec);
2863                        }
2864                    }
2865                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
2866                    scheduleAppGcsLocked();
2867                }
2868            }
2869        } else if (app.pid != pid) {
2870            // A new process has already been started.
2871            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2872                    + ") has died and restarted (pid " + app.pid + ").");
2873            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2874        } else if (DEBUG_PROCESSES) {
2875            Slog.d(TAG, "Received spurious death notification for thread "
2876                    + thread.asBinder());
2877        }
2878    }
2879
2880    /**
2881     * If a stack trace dump file is configured, dump process stack traces.
2882     * @param clearTraces causes the dump file to be erased prior to the new
2883     *    traces being written, if true; when false, the new traces will be
2884     *    appended to any existing file content.
2885     * @param firstPids of dalvik VM processes to dump stack traces for first
2886     * @param lastPids of dalvik VM processes to dump stack traces for last
2887     * @return file containing stack traces, or null if no dump file is configured
2888     */
2889    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2890            ProcessStats processStats, SparseArray<Boolean> lastPids) {
2891        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2892        if (tracesPath == null || tracesPath.length() == 0) {
2893            return null;
2894        }
2895
2896        File tracesFile = new File(tracesPath);
2897        try {
2898            File tracesDir = tracesFile.getParentFile();
2899            if (!tracesDir.exists()) tracesFile.mkdirs();
2900            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
2901
2902            if (clearTraces && tracesFile.exists()) tracesFile.delete();
2903            tracesFile.createNewFile();
2904            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2905        } catch (IOException e) {
2906            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
2907            return null;
2908        }
2909
2910        dumpStackTraces(tracesPath, firstPids, processStats, lastPids);
2911        return tracesFile;
2912    }
2913
2914    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
2915            ProcessStats processStats, SparseArray<Boolean> lastPids) {
2916        // Use a FileObserver to detect when traces finish writing.
2917        // The order of traces is considered important to maintain for legibility.
2918        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2919            public synchronized void onEvent(int event, String path) { notify(); }
2920        };
2921
2922        try {
2923            observer.startWatching();
2924
2925            // First collect all of the stacks of the most important pids.
2926            if (firstPids != null) {
2927                try {
2928                    int num = firstPids.size();
2929                    for (int i = 0; i < num; i++) {
2930                        synchronized (observer) {
2931                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2932                            observer.wait(200);  // Wait for write-close, give up after 200msec
2933                        }
2934                    }
2935                } catch (InterruptedException e) {
2936                    Log.wtf(TAG, e);
2937                }
2938            }
2939
2940            // Next measure CPU usage.
2941            if (processStats != null) {
2942                processStats.init();
2943                System.gc();
2944                processStats.update();
2945                try {
2946                    synchronized (processStats) {
2947                        processStats.wait(500); // measure over 1/2 second.
2948                    }
2949                } catch (InterruptedException e) {
2950                }
2951                processStats.update();
2952
2953                // We'll take the stack crawls of just the top apps using CPU.
2954                final int N = processStats.countWorkingStats();
2955                int numProcs = 0;
2956                for (int i=0; i<N && numProcs<5; i++) {
2957                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
2958                    if (lastPids.indexOfKey(stats.pid) >= 0) {
2959                        numProcs++;
2960                        try {
2961                            synchronized (observer) {
2962                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2963                                observer.wait(200);  // Wait for write-close, give up after 200msec
2964                            }
2965                        } catch (InterruptedException e) {
2966                            Log.wtf(TAG, e);
2967                        }
2968
2969                    }
2970                }
2971            }
2972
2973        } finally {
2974            observer.stopWatching();
2975        }
2976    }
2977
2978    private final class AppNotResponding implements Runnable {
2979        private final ProcessRecord mApp;
2980        private final String mAnnotation;
2981
2982        public AppNotResponding(ProcessRecord app, String annotation) {
2983            mApp = app;
2984            mAnnotation = annotation;
2985        }
2986
2987        @Override
2988        public void run() {
2989            appNotResponding(mApp, null, null, mAnnotation);
2990        }
2991    }
2992
2993    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
2994        if (IS_USER_BUILD) {
2995            return;
2996        }
2997        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2998        if (tracesPath == null || tracesPath.length() == 0) {
2999            return;
3000        }
3001
3002        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3003        StrictMode.allowThreadDiskWrites();
3004        try {
3005            final File tracesFile = new File(tracesPath);
3006            final File tracesDir = tracesFile.getParentFile();
3007            final File tracesTmp = new File(tracesDir, "__tmp__");
3008            try {
3009                if (!tracesDir.exists()) tracesFile.mkdirs();
3010                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3011
3012                if (tracesFile.exists()) {
3013                    tracesTmp.delete();
3014                    tracesFile.renameTo(tracesTmp);
3015                }
3016                StringBuilder sb = new StringBuilder();
3017                Time tobj = new Time();
3018                tobj.set(System.currentTimeMillis());
3019                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3020                sb.append(": ");
3021                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3022                sb.append(" since ");
3023                sb.append(msg);
3024                FileOutputStream fos = new FileOutputStream(tracesFile);
3025                fos.write(sb.toString().getBytes());
3026                if (app == null) {
3027                    fos.write("\n*** No application process!".getBytes());
3028                }
3029                fos.close();
3030                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3031            } catch (IOException e) {
3032                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3033                return;
3034            }
3035
3036            if (app != null) {
3037                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3038                firstPids.add(app.pid);
3039                dumpStackTraces(tracesPath, firstPids, null, null);
3040            }
3041
3042            File lastTracesFile = null;
3043            File curTracesFile = null;
3044            for (int i=9; i>=0; i--) {
3045                String name = String.format("slow%02d.txt", i);
3046                curTracesFile = new File(tracesDir, name);
3047                if (curTracesFile.exists()) {
3048                    if (lastTracesFile != null) {
3049                        curTracesFile.renameTo(lastTracesFile);
3050                    } else {
3051                        curTracesFile.delete();
3052                    }
3053                }
3054                lastTracesFile = curTracesFile;
3055            }
3056            tracesFile.renameTo(curTracesFile);
3057            if (tracesTmp.exists()) {
3058                tracesTmp.renameTo(tracesFile);
3059            }
3060        } finally {
3061            StrictMode.setThreadPolicy(oldPolicy);
3062        }
3063    }
3064
3065    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3066            ActivityRecord parent, final String annotation) {
3067        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3068        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3069
3070        if (mController != null) {
3071            try {
3072                // 0 == continue, -1 = kill process immediately
3073                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3074                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3075            } catch (RemoteException e) {
3076                mController = null;
3077            }
3078        }
3079
3080        long anrTime = SystemClock.uptimeMillis();
3081        if (MONITOR_CPU_USAGE) {
3082            updateCpuStatsNow();
3083        }
3084
3085        synchronized (this) {
3086            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3087            if (mShuttingDown) {
3088                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3089                return;
3090            } else if (app.notResponding) {
3091                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3092                return;
3093            } else if (app.crashing) {
3094                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3095                return;
3096            }
3097
3098            // In case we come through here for the same app before completing
3099            // this one, mark as anring now so we will bail out.
3100            app.notResponding = true;
3101
3102            // Log the ANR to the event log.
3103            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3104                    annotation);
3105
3106            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3107            firstPids.add(app.pid);
3108
3109            int parentPid = app.pid;
3110            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3111            if (parentPid != app.pid) firstPids.add(parentPid);
3112
3113            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3114
3115            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3116                ProcessRecord r = mLruProcesses.get(i);
3117                if (r != null && r.thread != null) {
3118                    int pid = r.pid;
3119                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3120                        if (r.persistent) {
3121                            firstPids.add(pid);
3122                        } else {
3123                            lastPids.put(pid, Boolean.TRUE);
3124                        }
3125                    }
3126                }
3127            }
3128        }
3129
3130        // Log the ANR to the main log.
3131        StringBuilder info = mStringBuilder;
3132        info.setLength(0);
3133        info.append("ANR in ").append(app.processName);
3134        if (activity != null && activity.shortComponentName != null) {
3135            info.append(" (").append(activity.shortComponentName).append(")");
3136        }
3137        info.append("\n");
3138        if (annotation != null) {
3139            info.append("Reason: ").append(annotation).append("\n");
3140        }
3141        if (parent != null && parent != activity) {
3142            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3143        }
3144
3145        final ProcessStats processStats = new ProcessStats(true);
3146
3147        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3148
3149        String cpuInfo = null;
3150        if (MONITOR_CPU_USAGE) {
3151            updateCpuStatsNow();
3152            synchronized (mProcessStatsThread) {
3153                cpuInfo = mProcessStats.printCurrentState(anrTime);
3154            }
3155            info.append(processStats.printCurrentLoad());
3156            info.append(cpuInfo);
3157        }
3158
3159        info.append(processStats.printCurrentState(anrTime));
3160
3161        Slog.e(TAG, info.toString());
3162        if (tracesFile == null) {
3163            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3164            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3165        }
3166
3167        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3168                cpuInfo, tracesFile, null);
3169
3170        if (mController != null) {
3171            try {
3172                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3173                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3174                if (res != 0) {
3175                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3176                    return;
3177                }
3178            } catch (RemoteException e) {
3179                mController = null;
3180            }
3181        }
3182
3183        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3184        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3185                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3186
3187        synchronized (this) {
3188            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3189                Slog.w(TAG, "Killing " + app + ": background ANR");
3190                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3191                        app.processName, app.setAdj, "background ANR");
3192                Process.killProcessQuiet(app.pid);
3193                return;
3194            }
3195
3196            // Set the app's notResponding state, and look up the errorReportReceiver
3197            makeAppNotRespondingLocked(app,
3198                    activity != null ? activity.shortComponentName : null,
3199                    annotation != null ? "ANR " + annotation : "ANR",
3200                    info.toString());
3201
3202            // Bring up the infamous App Not Responding dialog
3203            Message msg = Message.obtain();
3204            HashMap map = new HashMap();
3205            msg.what = SHOW_NOT_RESPONDING_MSG;
3206            msg.obj = map;
3207            map.put("app", app);
3208            if (activity != null) {
3209                map.put("activity", activity);
3210            }
3211
3212            mHandler.sendMessage(msg);
3213        }
3214    }
3215
3216    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3217        if (!mLaunchWarningShown) {
3218            mLaunchWarningShown = true;
3219            mHandler.post(new Runnable() {
3220                @Override
3221                public void run() {
3222                    synchronized (ActivityManagerService.this) {
3223                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3224                        d.show();
3225                        mHandler.postDelayed(new Runnable() {
3226                            @Override
3227                            public void run() {
3228                                synchronized (ActivityManagerService.this) {
3229                                    d.dismiss();
3230                                    mLaunchWarningShown = false;
3231                                }
3232                            }
3233                        }, 4000);
3234                    }
3235                }
3236            });
3237        }
3238    }
3239
3240    public boolean clearApplicationUserData(final String packageName,
3241            final IPackageDataObserver observer) {
3242        int uid = Binder.getCallingUid();
3243        int pid = Binder.getCallingPid();
3244        long callingId = Binder.clearCallingIdentity();
3245        try {
3246            IPackageManager pm = AppGlobals.getPackageManager();
3247            int pkgUid = -1;
3248            synchronized(this) {
3249                try {
3250                    pkgUid = pm.getPackageUid(packageName);
3251                } catch (RemoteException e) {
3252                }
3253                if (pkgUid == -1) {
3254                    Slog.w(TAG, "Invalid packageName:" + packageName);
3255                    return false;
3256                }
3257                if (uid == pkgUid || checkComponentPermission(
3258                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3259                        pid, uid, -1, true)
3260                        == PackageManager.PERMISSION_GRANTED) {
3261                    forceStopPackageLocked(packageName, pkgUid);
3262                } else {
3263                    throw new SecurityException(pid+" does not have permission:"+
3264                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3265                                    "for process:"+packageName);
3266                }
3267            }
3268
3269            try {
3270                //clear application user data
3271                pm.clearApplicationUserData(packageName, observer);
3272                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3273                        Uri.fromParts("package", packageName, null));
3274                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3275                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3276                        null, null, 0, null, null, null, false, false);
3277            } catch (RemoteException e) {
3278            }
3279        } finally {
3280            Binder.restoreCallingIdentity(callingId);
3281        }
3282        return true;
3283    }
3284
3285    public void killBackgroundProcesses(final String packageName) {
3286        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3287                != PackageManager.PERMISSION_GRANTED &&
3288                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3289                        != PackageManager.PERMISSION_GRANTED) {
3290            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3291                    + Binder.getCallingPid()
3292                    + ", uid=" + Binder.getCallingUid()
3293                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3294            Slog.w(TAG, msg);
3295            throw new SecurityException(msg);
3296        }
3297
3298        long callingId = Binder.clearCallingIdentity();
3299        try {
3300            IPackageManager pm = AppGlobals.getPackageManager();
3301            int pkgUid = -1;
3302            synchronized(this) {
3303                try {
3304                    pkgUid = pm.getPackageUid(packageName);
3305                } catch (RemoteException e) {
3306                }
3307                if (pkgUid == -1) {
3308                    Slog.w(TAG, "Invalid packageName: " + packageName);
3309                    return;
3310                }
3311                killPackageProcessesLocked(packageName, pkgUid,
3312                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3313            }
3314        } finally {
3315            Binder.restoreCallingIdentity(callingId);
3316        }
3317    }
3318
3319    public void killAllBackgroundProcesses() {
3320        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3321                != PackageManager.PERMISSION_GRANTED) {
3322            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3323                    + Binder.getCallingPid()
3324                    + ", uid=" + Binder.getCallingUid()
3325                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3326            Slog.w(TAG, msg);
3327            throw new SecurityException(msg);
3328        }
3329
3330        long callingId = Binder.clearCallingIdentity();
3331        try {
3332            synchronized(this) {
3333                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3334                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3335                    final int NA = apps.size();
3336                    for (int ia=0; ia<NA; ia++) {
3337                        ProcessRecord app = apps.valueAt(ia);
3338                        if (app.persistent) {
3339                            // we don't kill persistent processes
3340                            continue;
3341                        }
3342                        if (app.removed) {
3343                            procs.add(app);
3344                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3345                            app.removed = true;
3346                            procs.add(app);
3347                        }
3348                    }
3349                }
3350
3351                int N = procs.size();
3352                for (int i=0; i<N; i++) {
3353                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3354                }
3355            }
3356        } finally {
3357            Binder.restoreCallingIdentity(callingId);
3358        }
3359    }
3360
3361    public void forceStopPackage(final String packageName) {
3362        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3363                != PackageManager.PERMISSION_GRANTED) {
3364            String msg = "Permission Denial: forceStopPackage() from pid="
3365                    + Binder.getCallingPid()
3366                    + ", uid=" + Binder.getCallingUid()
3367                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3368            Slog.w(TAG, msg);
3369            throw new SecurityException(msg);
3370        }
3371
3372        long callingId = Binder.clearCallingIdentity();
3373        try {
3374            IPackageManager pm = AppGlobals.getPackageManager();
3375            int pkgUid = -1;
3376            synchronized(this) {
3377                try {
3378                    pkgUid = pm.getPackageUid(packageName);
3379                } catch (RemoteException e) {
3380                }
3381                if (pkgUid == -1) {
3382                    Slog.w(TAG, "Invalid packageName: " + packageName);
3383                    return;
3384                }
3385                forceStopPackageLocked(packageName, pkgUid);
3386                try {
3387                    pm.setPackageStoppedState(packageName, true);
3388                } catch (RemoteException e) {
3389                } catch (IllegalArgumentException e) {
3390                    Slog.w(TAG, "Failed trying to unstop package "
3391                            + packageName + ": " + e);
3392                }
3393            }
3394        } finally {
3395            Binder.restoreCallingIdentity(callingId);
3396        }
3397    }
3398
3399    /*
3400     * The pkg name and uid have to be specified.
3401     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3402     */
3403    public void killApplicationWithUid(String pkg, int uid) {
3404        if (pkg == null) {
3405            return;
3406        }
3407        // Make sure the uid is valid.
3408        if (uid < 0) {
3409            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3410            return;
3411        }
3412        int callerUid = Binder.getCallingUid();
3413        // Only the system server can kill an application
3414        if (callerUid == Process.SYSTEM_UID) {
3415            // Post an aysnc message to kill the application
3416            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3417            msg.arg1 = uid;
3418            msg.arg2 = 0;
3419            msg.obj = pkg;
3420            mHandler.sendMessage(msg);
3421        } else {
3422            throw new SecurityException(callerUid + " cannot kill pkg: " +
3423                    pkg);
3424        }
3425    }
3426
3427    public void closeSystemDialogs(String reason) {
3428        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3429        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3430        if (reason != null) {
3431            intent.putExtra("reason", reason);
3432        }
3433
3434        final int uid = Binder.getCallingUid();
3435        final long origId = Binder.clearCallingIdentity();
3436        synchronized (this) {
3437            int i = mWatchers.beginBroadcast();
3438            while (i > 0) {
3439                i--;
3440                IActivityWatcher w = mWatchers.getBroadcastItem(i);
3441                if (w != null) {
3442                    try {
3443                        w.closingSystemDialogs(reason);
3444                    } catch (RemoteException e) {
3445                    }
3446                }
3447            }
3448            mWatchers.finishBroadcast();
3449
3450            mWindowManager.closeSystemDialogs(reason);
3451
3452            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3453                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3454                if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3455                    r.stack.finishActivityLocked(r, i,
3456                            Activity.RESULT_CANCELED, null, "close-sys");
3457                }
3458            }
3459
3460            broadcastIntentLocked(null, null, intent, null,
3461                    null, 0, null, null, null, false, false, -1, uid);
3462        }
3463        Binder.restoreCallingIdentity(origId);
3464    }
3465
3466    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3467            throws RemoteException {
3468        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3469        for (int i=pids.length-1; i>=0; i--) {
3470            infos[i] = new Debug.MemoryInfo();
3471            Debug.getMemoryInfo(pids[i], infos[i]);
3472        }
3473        return infos;
3474    }
3475
3476    public long[] getProcessPss(int[] pids) throws RemoteException {
3477        long[] pss = new long[pids.length];
3478        for (int i=pids.length-1; i>=0; i--) {
3479            pss[i] = Debug.getPss(pids[i]);
3480        }
3481        return pss;
3482    }
3483
3484    public void killApplicationProcess(String processName, int uid) {
3485        if (processName == null) {
3486            return;
3487        }
3488
3489        int callerUid = Binder.getCallingUid();
3490        // Only the system server can kill an application
3491        if (callerUid == Process.SYSTEM_UID) {
3492            synchronized (this) {
3493                ProcessRecord app = getProcessRecordLocked(processName, uid);
3494                if (app != null && app.thread != null) {
3495                    try {
3496                        app.thread.scheduleSuicide();
3497                    } catch (RemoteException e) {
3498                        // If the other end already died, then our work here is done.
3499                    }
3500                } else {
3501                    Slog.w(TAG, "Process/uid not found attempting kill of "
3502                            + processName + " / " + uid);
3503                }
3504            }
3505        } else {
3506            throw new SecurityException(callerUid + " cannot kill app process: " +
3507                    processName);
3508        }
3509    }
3510
3511    private void forceStopPackageLocked(final String packageName, int uid) {
3512        forceStopPackageLocked(packageName, uid, false, false, true, false);
3513        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3514                Uri.fromParts("package", packageName, null));
3515        if (!mProcessesReady) {
3516            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3517        }
3518        intent.putExtra(Intent.EXTRA_UID, uid);
3519        broadcastIntentLocked(null, null, intent,
3520                null, null, 0, null, null, null,
3521                false, false, MY_PID, Process.SYSTEM_UID);
3522    }
3523
3524    private final boolean killPackageProcessesLocked(String packageName, int uid,
3525            int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3526            boolean evenPersistent, String reason) {
3527        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3528
3529        // Remove all processes this package may have touched: all with the
3530        // same UID (except for the system or root user), and all whose name
3531        // matches the package name.
3532        final String procNamePrefix = packageName + ":";
3533        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3534            final int NA = apps.size();
3535            for (int ia=0; ia<NA; ia++) {
3536                ProcessRecord app = apps.valueAt(ia);
3537                if (app.persistent && !evenPersistent) {
3538                    // we don't kill persistent processes
3539                    continue;
3540                }
3541                if (app.removed) {
3542                    if (doit) {
3543                        procs.add(app);
3544                    }
3545                } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3546                        || app.processName.equals(packageName)
3547                        || app.processName.startsWith(procNamePrefix)) {
3548                    if (app.setAdj >= minOomAdj) {
3549                        if (!doit) {
3550                            return true;
3551                        }
3552                        app.removed = true;
3553                        procs.add(app);
3554                    }
3555                }
3556            }
3557        }
3558
3559        int N = procs.size();
3560        for (int i=0; i<N; i++) {
3561            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3562        }
3563        return N > 0;
3564    }
3565
3566    private final boolean forceStopPackageLocked(String name, int uid,
3567            boolean callerWillRestart, boolean purgeCache, boolean doit,
3568            boolean evenPersistent) {
3569        int i;
3570        int N;
3571
3572        if (uid < 0) {
3573            try {
3574                uid = AppGlobals.getPackageManager().getPackageUid(name);
3575            } catch (RemoteException e) {
3576            }
3577        }
3578
3579        if (doit) {
3580            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3581
3582            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3583            while (badApps.hasNext()) {
3584                SparseArray<Long> ba = badApps.next();
3585                if (ba.get(uid) != null) {
3586                    badApps.remove();
3587                }
3588            }
3589        }
3590
3591        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3592                callerWillRestart, false, doit, evenPersistent, "force stop");
3593
3594        TaskRecord lastTask = null;
3595        for (i=0; i<mMainStack.mHistory.size(); i++) {
3596            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3597            final boolean samePackage = r.packageName.equals(name);
3598            if ((samePackage || r.task == lastTask)
3599                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3600                if (!doit) {
3601                    if (r.finishing) {
3602                        // If this activity is just finishing, then it is not
3603                        // interesting as far as something to stop.
3604                        continue;
3605                    }
3606                    return true;
3607                }
3608                didSomething = true;
3609                Slog.i(TAG, "  Force finishing activity " + r);
3610                if (samePackage) {
3611                    if (r.app != null) {
3612                        r.app.removed = true;
3613                    }
3614                    r.app = null;
3615                }
3616                lastTask = r.task;
3617                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3618                        null, "force-stop")) {
3619                    i--;
3620                }
3621            }
3622        }
3623
3624        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3625        for (ServiceRecord service : mServices.values()) {
3626            if (service.packageName.equals(name)
3627                    && (service.app == null || evenPersistent || !service.app.persistent)) {
3628                if (!doit) {
3629                    return true;
3630                }
3631                didSomething = true;
3632                Slog.i(TAG, "  Force stopping service " + service);
3633                if (service.app != null) {
3634                    service.app.removed = true;
3635                }
3636                service.app = null;
3637                services.add(service);
3638            }
3639        }
3640
3641        N = services.size();
3642        for (i=0; i<N; i++) {
3643            bringDownServiceLocked(services.get(i), true);
3644        }
3645
3646        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3647        for (ContentProviderRecord provider : mProvidersByClass.values()) {
3648            if (provider.info.packageName.equals(name)
3649                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3650                if (!doit) {
3651                    return true;
3652                }
3653                didSomething = true;
3654                providers.add(provider);
3655            }
3656        }
3657
3658        N = providers.size();
3659        for (i=0; i<N; i++) {
3660            removeDyingProviderLocked(null, providers.get(i));
3661        }
3662
3663        if (doit) {
3664            if (purgeCache) {
3665                AttributeCache ac = AttributeCache.instance();
3666                if (ac != null) {
3667                    ac.removePackage(name);
3668                }
3669            }
3670            if (mBooted) {
3671                mMainStack.resumeTopActivityLocked(null);
3672                mMainStack.scheduleIdleLocked();
3673            }
3674        }
3675
3676        return didSomething;
3677    }
3678
3679    private final boolean removeProcessLocked(ProcessRecord app,
3680            boolean callerWillRestart, boolean allowRestart, String reason) {
3681        final String name = app.processName;
3682        final int uid = app.info.uid;
3683        if (DEBUG_PROCESSES) Slog.d(
3684            TAG, "Force removing proc " + app.toShortString() + " (" + name
3685            + "/" + uid + ")");
3686
3687        mProcessNames.remove(name, uid);
3688        if (mHeavyWeightProcess == app) {
3689            mHeavyWeightProcess = null;
3690            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3691        }
3692        boolean needRestart = false;
3693        if (app.pid > 0 && app.pid != MY_PID) {
3694            int pid = app.pid;
3695            synchronized (mPidsSelfLocked) {
3696                mPidsSelfLocked.remove(pid);
3697                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3698            }
3699            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3700            handleAppDiedLocked(app, true, allowRestart);
3701            mLruProcesses.remove(app);
3702            Process.killProcessQuiet(pid);
3703
3704            if (app.persistent) {
3705                if (!callerWillRestart) {
3706                    addAppLocked(app.info);
3707                } else {
3708                    needRestart = true;
3709                }
3710            }
3711        } else {
3712            mRemovedProcesses.add(app);
3713        }
3714
3715        return needRestart;
3716    }
3717
3718    private final void processStartTimedOutLocked(ProcessRecord app) {
3719        final int pid = app.pid;
3720        boolean gone = false;
3721        synchronized (mPidsSelfLocked) {
3722            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3723            if (knownApp != null && knownApp.thread == null) {
3724                mPidsSelfLocked.remove(pid);
3725                gone = true;
3726            }
3727        }
3728
3729        if (gone) {
3730            Slog.w(TAG, "Process " + app + " failed to attach");
3731            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
3732                    app.processName);
3733            mProcessNames.remove(app.processName, app.info.uid);
3734            if (mHeavyWeightProcess == app) {
3735                mHeavyWeightProcess = null;
3736                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3737            }
3738            // Take care of any launching providers waiting for this process.
3739            checkAppInLaunchingProvidersLocked(app, true);
3740            // Take care of any services that are waiting for the process.
3741            for (int i=0; i<mPendingServices.size(); i++) {
3742                ServiceRecord sr = mPendingServices.get(i);
3743                if (app.info.uid == sr.appInfo.uid
3744                        && app.processName.equals(sr.processName)) {
3745                    Slog.w(TAG, "Forcing bringing down service: " + sr);
3746                    mPendingServices.remove(i);
3747                    i--;
3748                    bringDownServiceLocked(sr, true);
3749                }
3750            }
3751            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3752                    app.processName, app.setAdj, "start timeout");
3753            Process.killProcessQuiet(pid);
3754            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3755                Slog.w(TAG, "Unattached app died before backup, skipping");
3756                try {
3757                    IBackupManager bm = IBackupManager.Stub.asInterface(
3758                            ServiceManager.getService(Context.BACKUP_SERVICE));
3759                    bm.agentDisconnected(app.info.packageName);
3760                } catch (RemoteException e) {
3761                    // Can't happen; the backup manager is local
3762                }
3763            }
3764            if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
3765                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3766                mPendingBroadcast.state = BroadcastRecord.IDLE;
3767                mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
3768                mPendingBroadcast = null;
3769                scheduleBroadcastsLocked();
3770            }
3771        } else {
3772            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3773        }
3774    }
3775
3776    private final boolean attachApplicationLocked(IApplicationThread thread,
3777            int pid) {
3778
3779        // Find the application record that is being attached...  either via
3780        // the pid if we are running in multiple processes, or just pull the
3781        // next app record if we are emulating process with anonymous threads.
3782        ProcessRecord app;
3783        if (pid != MY_PID && pid >= 0) {
3784            synchronized (mPidsSelfLocked) {
3785                app = mPidsSelfLocked.get(pid);
3786            }
3787        } else {
3788            app = null;
3789        }
3790
3791        if (app == null) {
3792            Slog.w(TAG, "No pending application record for pid " + pid
3793                    + " (IApplicationThread " + thread + "); dropping process");
3794            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3795            if (pid > 0 && pid != MY_PID) {
3796                Process.killProcessQuiet(pid);
3797            } else {
3798                try {
3799                    thread.scheduleExit();
3800                } catch (Exception e) {
3801                    // Ignore exceptions.
3802                }
3803            }
3804            return false;
3805        }
3806
3807        // If this application record is still attached to a previous
3808        // process, clean it up now.
3809        if (app.thread != null) {
3810            handleAppDiedLocked(app, true, true);
3811        }
3812
3813        // Tell the process all about itself.
3814
3815        if (localLOGV) Slog.v(
3816                TAG, "Binding process pid " + pid + " to record " + app);
3817
3818        String processName = app.processName;
3819        try {
3820            AppDeathRecipient adr = new AppDeathRecipient(
3821                    app, pid, thread);
3822            thread.asBinder().linkToDeath(adr, 0);
3823            app.deathRecipient = adr;
3824        } catch (RemoteException e) {
3825            app.resetPackageList();
3826            startProcessLocked(app, "link fail", processName);
3827            return false;
3828        }
3829
3830        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3831
3832        app.thread = thread;
3833        app.curAdj = app.setAdj = -100;
3834        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3835        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3836        app.forcingToForeground = null;
3837        app.foregroundServices = false;
3838        app.hasShownUi = false;
3839        app.debugging = false;
3840
3841        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3842
3843        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3844        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3845
3846        if (!normalMode) {
3847            Slog.i(TAG, "Launching preboot mode app: " + app);
3848        }
3849
3850        if (localLOGV) Slog.v(
3851            TAG, "New app record " + app
3852            + " thread=" + thread.asBinder() + " pid=" + pid);
3853        try {
3854            int testMode = IApplicationThread.DEBUG_OFF;
3855            if (mDebugApp != null && mDebugApp.equals(processName)) {
3856                testMode = mWaitForDebugger
3857                    ? IApplicationThread.DEBUG_WAIT
3858                    : IApplicationThread.DEBUG_ON;
3859                app.debugging = true;
3860                if (mDebugTransient) {
3861                    mDebugApp = mOrigDebugApp;
3862                    mWaitForDebugger = mOrigWaitForDebugger;
3863                }
3864            }
3865            String profileFile = app.instrumentationProfileFile;
3866            ParcelFileDescriptor profileFd = null;
3867            boolean profileAutoStop = false;
3868            if (mProfileApp != null && mProfileApp.equals(processName)) {
3869                mProfileProc = app;
3870                profileFile = mProfileFile;
3871                profileFd = mProfileFd;
3872                profileAutoStop = mAutoStopProfiler;
3873            }
3874
3875            // If the app is being launched for restore or full backup, set it up specially
3876            boolean isRestrictedBackupMode = false;
3877            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3878                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3879                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
3880                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3881            }
3882
3883            ensurePackageDexOpt(app.instrumentationInfo != null
3884                    ? app.instrumentationInfo.packageName
3885                    : app.info.packageName);
3886            if (app.instrumentationClass != null) {
3887                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
3888            }
3889            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
3890                    + processName + " with config " + mConfiguration);
3891            ApplicationInfo appInfo = app.instrumentationInfo != null
3892                    ? app.instrumentationInfo : app.info;
3893            app.compat = compatibilityInfoForPackageLocked(appInfo);
3894            if (profileFd != null) {
3895                profileFd = profileFd.dup();
3896            }
3897            thread.bindApplication(processName, appInfo, providers,
3898                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
3899                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
3900                    isRestrictedBackupMode || !normalMode, app.persistent,
3901                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
3902                    mCoreSettingsObserver.getCoreSettingsLocked());
3903            updateLruProcessLocked(app, false, true);
3904            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
3905        } catch (Exception e) {
3906            // todo: Yikes!  What should we do?  For now we will try to
3907            // start another process, but that could easily get us in
3908            // an infinite loop of restarting processes...
3909            Slog.w(TAG, "Exception thrown during bind!", e);
3910
3911            app.resetPackageList();
3912            app.unlinkDeathRecipient();
3913            startProcessLocked(app, "bind fail", processName);
3914            return false;
3915        }
3916
3917        // Remove this record from the list of starting applications.
3918        mPersistentStartingProcesses.remove(app);
3919        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3920                "Attach application locked removing on hold: " + app);
3921        mProcessesOnHold.remove(app);
3922
3923        boolean badApp = false;
3924        boolean didSomething = false;
3925
3926        // See if the top visible activity is waiting to run in this process...
3927        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
3928        if (hr != null && normalMode) {
3929            if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3930                    && processName.equals(hr.processName)) {
3931                try {
3932                    if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
3933                        didSomething = true;
3934                    }
3935                } catch (Exception e) {
3936                    Slog.w(TAG, "Exception in new application when starting activity "
3937                          + hr.intent.getComponent().flattenToShortString(), e);
3938                    badApp = true;
3939                }
3940            } else {
3941                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
3942            }
3943        }
3944
3945        // Find any services that should be running in this process...
3946        if (!badApp && mPendingServices.size() > 0) {
3947            ServiceRecord sr = null;
3948            try {
3949                for (int i=0; i<mPendingServices.size(); i++) {
3950                    sr = mPendingServices.get(i);
3951                    if (app.info.uid != sr.appInfo.uid
3952                            || !processName.equals(sr.processName)) {
3953                        continue;
3954                    }
3955
3956                    mPendingServices.remove(i);
3957                    i--;
3958                    realStartServiceLocked(sr, app);
3959                    didSomething = true;
3960                }
3961            } catch (Exception e) {
3962                Slog.w(TAG, "Exception in new application when starting service "
3963                      + sr.shortName, e);
3964                badApp = true;
3965            }
3966        }
3967
3968        // Check if the next broadcast receiver is in this process...
3969        BroadcastRecord br = mPendingBroadcast;
3970        if (!badApp && br != null && br.curApp == app) {
3971            try {
3972                mPendingBroadcast = null;
3973                processCurBroadcastLocked(br, app);
3974                didSomething = true;
3975            } catch (Exception e) {
3976                Slog.w(TAG, "Exception in new application when starting receiver "
3977                      + br.curComponent.flattenToShortString(), e);
3978                badApp = true;
3979                logBroadcastReceiverDiscardLocked(br);
3980                finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3981                        br.resultExtras, br.resultAbort, true);
3982                scheduleBroadcastsLocked();
3983                // We need to reset the state if we fails to start the receiver.
3984                br.state = BroadcastRecord.IDLE;
3985            }
3986        }
3987
3988        // Check whether the next backup agent is in this process...
3989        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
3990            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
3991            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
3992            try {
3993                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3994                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3995                        mBackupTarget.backupMode);
3996            } catch (Exception e) {
3997                Slog.w(TAG, "Exception scheduling backup agent creation: ");
3998                e.printStackTrace();
3999            }
4000        }
4001
4002        if (badApp) {
4003            // todo: Also need to kill application to deal with all
4004            // kinds of exceptions.
4005            handleAppDiedLocked(app, false, true);
4006            return false;
4007        }
4008
4009        if (!didSomething) {
4010            updateOomAdjLocked();
4011        }
4012
4013        return true;
4014    }
4015
4016    public final void attachApplication(IApplicationThread thread) {
4017        synchronized (this) {
4018            int callingPid = Binder.getCallingPid();
4019            final long origId = Binder.clearCallingIdentity();
4020            attachApplicationLocked(thread, callingPid);
4021            Binder.restoreCallingIdentity(origId);
4022        }
4023    }
4024
4025    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4026        final long origId = Binder.clearCallingIdentity();
4027        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4028        if (stopProfiling) {
4029            synchronized (this) {
4030                if (mProfileProc == r.app) {
4031                    if (mProfileFd != null) {
4032                        try {
4033                            mProfileFd.close();
4034                        } catch (IOException e) {
4035                        }
4036                        clearProfilerLocked();
4037                    }
4038                }
4039            }
4040        }
4041        Binder.restoreCallingIdentity(origId);
4042    }
4043
4044    void enableScreenAfterBoot() {
4045        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4046                SystemClock.uptimeMillis());
4047        mWindowManager.enableScreenAfterBoot();
4048    }
4049
4050    public void showBootMessage(final CharSequence msg, final boolean always) {
4051        mWindowManager.showBootMessage(msg, always);
4052    }
4053
4054    public void dismissKeyguardOnNextActivity() {
4055        synchronized (this) {
4056            mMainStack.dismissKeyguardOnNextActivityLocked();
4057        }
4058    }
4059
4060    final void finishBooting() {
4061        IntentFilter pkgFilter = new IntentFilter();
4062        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4063        pkgFilter.addDataScheme("package");
4064        mContext.registerReceiver(new BroadcastReceiver() {
4065            @Override
4066            public void onReceive(Context context, Intent intent) {
4067                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4068                if (pkgs != null) {
4069                    for (String pkg : pkgs) {
4070                        synchronized (ActivityManagerService.this) {
4071                          if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
4072                              setResultCode(Activity.RESULT_OK);
4073                              return;
4074                          }
4075                       }
4076                    }
4077                }
4078            }
4079        }, pkgFilter);
4080
4081        synchronized (this) {
4082            // Ensure that any processes we had put on hold are now started
4083            // up.
4084            final int NP = mProcessesOnHold.size();
4085            if (NP > 0) {
4086                ArrayList<ProcessRecord> procs =
4087                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4088                for (int ip=0; ip<NP; ip++) {
4089                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4090                            + procs.get(ip));
4091                    startProcessLocked(procs.get(ip), "on-hold", null);
4092                }
4093            }
4094
4095            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4096                // Start looking for apps that are abusing wake locks.
4097                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4098                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4099                // Tell anyone interested that we are done booting!
4100                SystemProperties.set("sys.boot_completed", "1");
4101                broadcastIntentLocked(null, null,
4102                        new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4103                        null, null, 0, null, null,
4104                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4105                        false, false, MY_PID, Process.SYSTEM_UID);
4106            }
4107        }
4108    }
4109
4110    final void ensureBootCompleted() {
4111        boolean booting;
4112        boolean enableScreen;
4113        synchronized (this) {
4114            booting = mBooting;
4115            mBooting = false;
4116            enableScreen = !mBooted;
4117            mBooted = true;
4118        }
4119
4120        if (booting) {
4121            finishBooting();
4122        }
4123
4124        if (enableScreen) {
4125            enableScreenAfterBoot();
4126        }
4127    }
4128
4129    public final void activityPaused(IBinder token) {
4130        final long origId = Binder.clearCallingIdentity();
4131        mMainStack.activityPaused(token, false);
4132        Binder.restoreCallingIdentity(origId);
4133    }
4134
4135    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4136            CharSequence description) {
4137        if (localLOGV) Slog.v(
4138            TAG, "Activity stopped: token=" + token);
4139
4140        // Refuse possible leaked file descriptors
4141        if (icicle != null && icicle.hasFileDescriptors()) {
4142            throw new IllegalArgumentException("File descriptors passed in Bundle");
4143        }
4144
4145        ActivityRecord r = null;
4146
4147        final long origId = Binder.clearCallingIdentity();
4148
4149        synchronized (this) {
4150            r = mMainStack.isInStackLocked(token);
4151            if (r != null) {
4152                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4153            }
4154        }
4155
4156        if (r != null) {
4157            sendPendingThumbnail(r, null, null, null, false);
4158        }
4159
4160        trimApplications();
4161
4162        Binder.restoreCallingIdentity(origId);
4163    }
4164
4165    public final void activityDestroyed(IBinder token) {
4166        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4167        mMainStack.activityDestroyed(token);
4168    }
4169
4170    public String getCallingPackage(IBinder token) {
4171        synchronized (this) {
4172            ActivityRecord r = getCallingRecordLocked(token);
4173            return r != null && r.app != null ? r.info.packageName : null;
4174        }
4175    }
4176
4177    public ComponentName getCallingActivity(IBinder token) {
4178        synchronized (this) {
4179            ActivityRecord r = getCallingRecordLocked(token);
4180            return r != null ? r.intent.getComponent() : null;
4181        }
4182    }
4183
4184    private ActivityRecord getCallingRecordLocked(IBinder token) {
4185        ActivityRecord r = mMainStack.isInStackLocked(token);
4186        if (r == null) {
4187            return null;
4188        }
4189        return r.resultTo;
4190    }
4191
4192    public ComponentName getActivityClassForToken(IBinder token) {
4193        synchronized(this) {
4194            ActivityRecord r = mMainStack.isInStackLocked(token);
4195            if (r == null) {
4196                return null;
4197            }
4198            return r.intent.getComponent();
4199        }
4200    }
4201
4202    public String getPackageForToken(IBinder token) {
4203        synchronized(this) {
4204            ActivityRecord r = mMainStack.isInStackLocked(token);
4205            if (r == null) {
4206                return null;
4207            }
4208            return r.packageName;
4209        }
4210    }
4211
4212    public IIntentSender getIntentSender(int type,
4213            String packageName, IBinder token, String resultWho,
4214            int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
4215        // Refuse possible leaked file descriptors
4216        if (intents != null) {
4217            if (intents.length < 1) {
4218                throw new IllegalArgumentException("Intents array length must be >= 1");
4219            }
4220            for (int i=0; i<intents.length; i++) {
4221                Intent intent = intents[i];
4222                if (intent != null) {
4223                    if (intent.hasFileDescriptors()) {
4224                        throw new IllegalArgumentException("File descriptors passed in Intent");
4225                    }
4226                    if (type == INTENT_SENDER_BROADCAST &&
4227                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4228                        throw new IllegalArgumentException(
4229                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4230                    }
4231                    intents[i] = new Intent(intent);
4232                }
4233            }
4234            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4235                throw new IllegalArgumentException(
4236                        "Intent array length does not match resolvedTypes length");
4237            }
4238        }
4239
4240        synchronized(this) {
4241            int callingUid = Binder.getCallingUid();
4242            try {
4243                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4244                    int uid = AppGlobals.getPackageManager()
4245                            .getPackageUid(packageName);
4246                    if (uid != Binder.getCallingUid()) {
4247                        String msg = "Permission Denial: getIntentSender() from pid="
4248                            + Binder.getCallingPid()
4249                            + ", uid=" + Binder.getCallingUid()
4250                            + ", (need uid=" + uid + ")"
4251                            + " is not allowed to send as package " + packageName;
4252                        Slog.w(TAG, msg);
4253                        throw new SecurityException(msg);
4254                    }
4255                }
4256
4257                return getIntentSenderLocked(type, packageName, callingUid,
4258                        token, resultWho, requestCode, intents, resolvedTypes, flags);
4259
4260            } catch (RemoteException e) {
4261                throw new SecurityException(e);
4262            }
4263        }
4264    }
4265
4266    IIntentSender getIntentSenderLocked(int type,
4267            String packageName, int callingUid, IBinder token, String resultWho,
4268            int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
4269        ActivityRecord activity = null;
4270        if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4271            activity = mMainStack.isInStackLocked(token);
4272            if (activity == null) {
4273                return null;
4274            }
4275            if (activity.finishing) {
4276                return null;
4277            }
4278        }
4279
4280        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4281        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4282        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4283        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4284                |PendingIntent.FLAG_UPDATE_CURRENT);
4285
4286        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4287                type, packageName, activity, resultWho,
4288                requestCode, intents, resolvedTypes, flags);
4289        WeakReference<PendingIntentRecord> ref;
4290        ref = mIntentSenderRecords.get(key);
4291        PendingIntentRecord rec = ref != null ? ref.get() : null;
4292        if (rec != null) {
4293            if (!cancelCurrent) {
4294                if (updateCurrent) {
4295                    if (rec.key.requestIntent != null) {
4296                        rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4297                    }
4298                    if (intents != null) {
4299                        intents[intents.length-1] = rec.key.requestIntent;
4300                        rec.key.allIntents = intents;
4301                        rec.key.allResolvedTypes = resolvedTypes;
4302                    } else {
4303                        rec.key.allIntents = null;
4304                        rec.key.allResolvedTypes = null;
4305                    }
4306                }
4307                return rec;
4308            }
4309            rec.canceled = true;
4310            mIntentSenderRecords.remove(key);
4311        }
4312        if (noCreate) {
4313            return rec;
4314        }
4315        rec = new PendingIntentRecord(this, key, callingUid);
4316        mIntentSenderRecords.put(key, rec.ref);
4317        if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4318            if (activity.pendingResults == null) {
4319                activity.pendingResults
4320                        = new HashSet<WeakReference<PendingIntentRecord>>();
4321            }
4322            activity.pendingResults.add(rec.ref);
4323        }
4324        return rec;
4325    }
4326
4327    public void cancelIntentSender(IIntentSender sender) {
4328        if (!(sender instanceof PendingIntentRecord)) {
4329            return;
4330        }
4331        synchronized(this) {
4332            PendingIntentRecord rec = (PendingIntentRecord)sender;
4333            try {
4334                int uid = AppGlobals.getPackageManager()
4335                        .getPackageUid(rec.key.packageName);
4336                if (uid != Binder.getCallingUid()) {
4337                    String msg = "Permission Denial: cancelIntentSender() from pid="
4338                        + Binder.getCallingPid()
4339                        + ", uid=" + Binder.getCallingUid()
4340                        + " is not allowed to cancel packges "
4341                        + rec.key.packageName;
4342                    Slog.w(TAG, msg);
4343                    throw new SecurityException(msg);
4344                }
4345            } catch (RemoteException e) {
4346                throw new SecurityException(e);
4347            }
4348            cancelIntentSenderLocked(rec, true);
4349        }
4350    }
4351
4352    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4353        rec.canceled = true;
4354        mIntentSenderRecords.remove(rec.key);
4355        if (cleanActivity && rec.key.activity != null) {
4356            rec.key.activity.pendingResults.remove(rec.ref);
4357        }
4358    }
4359
4360    public String getPackageForIntentSender(IIntentSender pendingResult) {
4361        if (!(pendingResult instanceof PendingIntentRecord)) {
4362            return null;
4363        }
4364        try {
4365            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4366            return res.key.packageName;
4367        } catch (ClassCastException e) {
4368        }
4369        return null;
4370    }
4371
4372    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4373        if (!(pendingResult instanceof PendingIntentRecord)) {
4374            return false;
4375        }
4376        try {
4377            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4378            if (res.key.allIntents == null) {
4379                return false;
4380            }
4381            for (int i=0; i<res.key.allIntents.length; i++) {
4382                Intent intent = res.key.allIntents[i];
4383                if (intent.getPackage() != null && intent.getComponent() != null) {
4384                    return false;
4385                }
4386            }
4387            return true;
4388        } catch (ClassCastException e) {
4389        }
4390        return false;
4391    }
4392
4393    public void setProcessLimit(int max) {
4394        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4395                "setProcessLimit()");
4396        synchronized (this) {
4397            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4398            mProcessLimitOverride = max;
4399        }
4400        trimApplications();
4401    }
4402
4403    public int getProcessLimit() {
4404        synchronized (this) {
4405            return mProcessLimitOverride;
4406        }
4407    }
4408
4409    void foregroundTokenDied(ForegroundToken token) {
4410        synchronized (ActivityManagerService.this) {
4411            synchronized (mPidsSelfLocked) {
4412                ForegroundToken cur
4413                    = mForegroundProcesses.get(token.pid);
4414                if (cur != token) {
4415                    return;
4416                }
4417                mForegroundProcesses.remove(token.pid);
4418                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4419                if (pr == null) {
4420                    return;
4421                }
4422                pr.forcingToForeground = null;
4423                pr.foregroundServices = false;
4424            }
4425            updateOomAdjLocked();
4426        }
4427    }
4428
4429    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4430        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4431                "setProcessForeground()");
4432        synchronized(this) {
4433            boolean changed = false;
4434
4435            synchronized (mPidsSelfLocked) {
4436                ProcessRecord pr = mPidsSelfLocked.get(pid);
4437                if (pr == null) {
4438                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4439                    return;
4440                }
4441                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4442                if (oldToken != null) {
4443                    oldToken.token.unlinkToDeath(oldToken, 0);
4444                    mForegroundProcesses.remove(pid);
4445                    pr.forcingToForeground = null;
4446                    changed = true;
4447                }
4448                if (isForeground && token != null) {
4449                    ForegroundToken newToken = new ForegroundToken() {
4450                        public void binderDied() {
4451                            foregroundTokenDied(this);
4452                        }
4453                    };
4454                    newToken.pid = pid;
4455                    newToken.token = token;
4456                    try {
4457                        token.linkToDeath(newToken, 0);
4458                        mForegroundProcesses.put(pid, newToken);
4459                        pr.forcingToForeground = token;
4460                        changed = true;
4461                    } catch (RemoteException e) {
4462                        // If the process died while doing this, we will later
4463                        // do the cleanup with the process death link.
4464                    }
4465                }
4466            }
4467
4468            if (changed) {
4469                updateOomAdjLocked();
4470            }
4471        }
4472    }
4473
4474    // =========================================================
4475    // PERMISSIONS
4476    // =========================================================
4477
4478    static class PermissionController extends IPermissionController.Stub {
4479        ActivityManagerService mActivityManagerService;
4480        PermissionController(ActivityManagerService activityManagerService) {
4481            mActivityManagerService = activityManagerService;
4482        }
4483
4484        public boolean checkPermission(String permission, int pid, int uid) {
4485            return mActivityManagerService.checkPermission(permission, pid,
4486                    uid) == PackageManager.PERMISSION_GRANTED;
4487        }
4488    }
4489
4490    /**
4491     * This can be called with or without the global lock held.
4492     */
4493    int checkComponentPermission(String permission, int pid, int uid,
4494            int owningUid, boolean exported) {
4495        // We might be performing an operation on behalf of an indirect binder
4496        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4497        // client identity accordingly before proceeding.
4498        Identity tlsIdentity = sCallerIdentity.get();
4499        if (tlsIdentity != null) {
4500            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4501                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4502            uid = tlsIdentity.uid;
4503            pid = tlsIdentity.pid;
4504        }
4505
4506        // Root, system server and our own process get to do everything.
4507        if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
4508            return PackageManager.PERMISSION_GRANTED;
4509        }
4510        // If there is a uid that owns whatever is being accessed, it has
4511        // blanket access to it regardless of the permissions it requires.
4512        if (owningUid >= 0 && uid == owningUid) {
4513            return PackageManager.PERMISSION_GRANTED;
4514        }
4515        // If the target is not exported, then nobody else can get to it.
4516        if (!exported) {
4517            Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
4518            return PackageManager.PERMISSION_DENIED;
4519        }
4520        if (permission == null) {
4521            return PackageManager.PERMISSION_GRANTED;
4522        }
4523        try {
4524            return AppGlobals.getPackageManager()
4525                    .checkUidPermission(permission, uid);
4526        } catch (RemoteException e) {
4527            // Should never happen, but if it does... deny!
4528            Slog.e(TAG, "PackageManager is dead?!?", e);
4529        }
4530        return PackageManager.PERMISSION_DENIED;
4531    }
4532
4533    /**
4534     * As the only public entry point for permissions checking, this method
4535     * can enforce the semantic that requesting a check on a null global
4536     * permission is automatically denied.  (Internally a null permission
4537     * string is used when calling {@link #checkComponentPermission} in cases
4538     * when only uid-based security is needed.)
4539     *
4540     * This can be called with or without the global lock held.
4541     */
4542    public int checkPermission(String permission, int pid, int uid) {
4543        if (permission == null) {
4544            return PackageManager.PERMISSION_DENIED;
4545        }
4546        return checkComponentPermission(permission, pid, uid, -1, true);
4547    }
4548
4549    /**
4550     * Binder IPC calls go through the public entry point.
4551     * This can be called with or without the global lock held.
4552     */
4553    int checkCallingPermission(String permission) {
4554        return checkPermission(permission,
4555                Binder.getCallingPid(),
4556                Binder.getCallingUid());
4557    }
4558
4559    /**
4560     * This can be called with or without the global lock held.
4561     */
4562    void enforceCallingPermission(String permission, String func) {
4563        if (checkCallingPermission(permission)
4564                == PackageManager.PERMISSION_GRANTED) {
4565            return;
4566        }
4567
4568        String msg = "Permission Denial: " + func + " from pid="
4569                + Binder.getCallingPid()
4570                + ", uid=" + Binder.getCallingUid()
4571                + " requires " + permission;
4572        Slog.w(TAG, msg);
4573        throw new SecurityException(msg);
4574    }
4575
4576    private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
4577            ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4578        boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4579        boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4580        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4581                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4582        try {
4583            // Is the component private from the target uid?
4584            final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4585
4586            // Acceptable if the there is no read permission needed from the
4587            // target or the target is holding the read permission.
4588            if (!readPerm) {
4589                if ((!prv && pi.readPermission == null) ||
4590                        (pm.checkUidPermission(pi.readPermission, uid)
4591                                == PackageManager.PERMISSION_GRANTED)) {
4592                    readPerm = true;
4593                }
4594            }
4595
4596            // Acceptable if the there is no write permission needed from the
4597            // target or the target is holding the read permission.
4598            if (!writePerm) {
4599                if (!prv && (pi.writePermission == null) ||
4600                        (pm.checkUidPermission(pi.writePermission, uid)
4601                                == PackageManager.PERMISSION_GRANTED)) {
4602                    writePerm = true;
4603                }
4604            }
4605
4606            // Acceptable if there is a path permission matching the URI that
4607            // the target holds the permission on.
4608            PathPermission[] pps = pi.pathPermissions;
4609            if (pps != null && (!readPerm || !writePerm)) {
4610                final String path = uri.getPath();
4611                int i = pps.length;
4612                while (i > 0 && (!readPerm || !writePerm)) {
4613                    i--;
4614                    PathPermission pp = pps[i];
4615                    if (!readPerm) {
4616                        final String pprperm = pp.getReadPermission();
4617                        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4618                                + pprperm + " for " + pp.getPath()
4619                                + ": match=" + pp.match(path)
4620                                + " check=" + pm.checkUidPermission(pprperm, uid));
4621                        if (pprperm != null && pp.match(path) &&
4622                                (pm.checkUidPermission(pprperm, uid)
4623                                        == PackageManager.PERMISSION_GRANTED)) {
4624                            readPerm = true;
4625                        }
4626                    }
4627                    if (!writePerm) {
4628                        final String ppwperm = pp.getWritePermission();
4629                        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4630                                + ppwperm + " for " + pp.getPath()
4631                                + ": match=" + pp.match(path)
4632                                + " check=" + pm.checkUidPermission(ppwperm, uid));
4633                        if (ppwperm != null && pp.match(path) &&
4634                                (pm.checkUidPermission(ppwperm, uid)
4635                                        == PackageManager.PERMISSION_GRANTED)) {
4636                            writePerm = true;
4637                        }
4638                    }
4639                }
4640            }
4641        } catch (RemoteException e) {
4642            return false;
4643        }
4644
4645        return readPerm && writePerm;
4646    }
4647
4648    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4649            int modeFlags) {
4650        // Root gets to do everything.
4651        if (uid == 0) {
4652            return true;
4653        }
4654        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4655        if (perms == null) return false;
4656        UriPermission perm = perms.get(uri);
4657        if (perm == null) return false;
4658        return (modeFlags&perm.modeFlags) == modeFlags;
4659    }
4660
4661    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4662        // Another redirected-binder-call permissions check as in
4663        // {@link checkComponentPermission}.
4664        Identity tlsIdentity = sCallerIdentity.get();
4665        if (tlsIdentity != null) {
4666            uid = tlsIdentity.uid;
4667            pid = tlsIdentity.pid;
4668        }
4669
4670        // Our own process gets to do everything.
4671        if (pid == MY_PID) {
4672            return PackageManager.PERMISSION_GRANTED;
4673        }
4674        synchronized(this) {
4675            return checkUriPermissionLocked(uri, uid, modeFlags)
4676                    ? PackageManager.PERMISSION_GRANTED
4677                    : PackageManager.PERMISSION_DENIED;
4678        }
4679    }
4680
4681    /**
4682     * Check if the targetPkg can be granted permission to access uri by
4683     * the callingUid using the given modeFlags.  Throws a security exception
4684     * if callingUid is not allowed to do this.  Returns the uid of the target
4685     * if the URI permission grant should be performed; returns -1 if it is not
4686     * needed (for example targetPkg already has permission to access the URI).
4687     */
4688    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4689            Uri uri, int modeFlags) {
4690        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4691                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4692        if (modeFlags == 0) {
4693            return -1;
4694        }
4695
4696        if (targetPkg != null) {
4697            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4698                    "Checking grant " + targetPkg + " permission to " + uri);
4699        }
4700
4701        final IPackageManager pm = AppGlobals.getPackageManager();
4702
4703        // If this is not a content: uri, we can't do anything with it.
4704        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4705            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4706                    "Can't grant URI permission for non-content URI: " + uri);
4707            return -1;
4708        }
4709
4710        String name = uri.getAuthority();
4711        ProviderInfo pi = null;
4712        ContentProviderRecord cpr = mProvidersByName.get(name);
4713        if (cpr != null) {
4714            pi = cpr.info;
4715        } else {
4716            try {
4717                pi = pm.resolveContentProvider(name,
4718                        PackageManager.GET_URI_PERMISSION_PATTERNS);
4719            } catch (RemoteException ex) {
4720            }
4721        }
4722        if (pi == null) {
4723            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4724            return -1;
4725        }
4726
4727        int targetUid;
4728        if (targetPkg != null) {
4729            try {
4730                targetUid = pm.getPackageUid(targetPkg);
4731                if (targetUid < 0) {
4732                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4733                            "Can't grant URI permission no uid for: " + targetPkg);
4734                    return -1;
4735                }
4736            } catch (RemoteException ex) {
4737                return -1;
4738            }
4739        } else {
4740            targetUid = -1;
4741        }
4742
4743        if (targetUid >= 0) {
4744            // First...  does the target actually need this permission?
4745            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4746                // No need to grant the target this permission.
4747                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4748                        "Target " + targetPkg + " already has full permission to " + uri);
4749                return -1;
4750            }
4751        } else {
4752            // First...  there is no target package, so can anyone access it?
4753            boolean allowed = pi.exported;
4754            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4755                if (pi.readPermission != null) {
4756                    allowed = false;
4757                }
4758            }
4759            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4760                if (pi.writePermission != null) {
4761                    allowed = false;
4762                }
4763            }
4764            if (allowed) {
4765                return -1;
4766            }
4767        }
4768
4769        // Second...  is the provider allowing granting of URI permissions?
4770        if (!pi.grantUriPermissions) {
4771            throw new SecurityException("Provider " + pi.packageName
4772                    + "/" + pi.name
4773                    + " does not allow granting of Uri permissions (uri "
4774                    + uri + ")");
4775        }
4776        if (pi.uriPermissionPatterns != null) {
4777            final int N = pi.uriPermissionPatterns.length;
4778            boolean allowed = false;
4779            for (int i=0; i<N; i++) {
4780                if (pi.uriPermissionPatterns[i] != null
4781                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4782                    allowed = true;
4783                    break;
4784                }
4785            }
4786            if (!allowed) {
4787                throw new SecurityException("Provider " + pi.packageName
4788                        + "/" + pi.name
4789                        + " does not allow granting of permission to path of Uri "
4790                        + uri);
4791            }
4792        }
4793
4794        // Third...  does the caller itself have permission to access
4795        // this uri?
4796        if (callingUid != Process.myUid()) {
4797            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4798                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4799                    throw new SecurityException("Uid " + callingUid
4800                            + " does not have permission to uri " + uri);
4801                }
4802            }
4803        }
4804
4805        return targetUid;
4806    }
4807
4808    public int checkGrantUriPermission(int callingUid, String targetPkg,
4809            Uri uri, int modeFlags) {
4810        synchronized(this) {
4811            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4812        }
4813    }
4814
4815    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4816            Uri uri, int modeFlags, UriPermissionOwner owner) {
4817        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4818                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4819        if (modeFlags == 0) {
4820            return;
4821        }
4822
4823        // So here we are: the caller has the assumed permission
4824        // to the uri, and the target doesn't.  Let's now give this to
4825        // the target.
4826
4827        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4828                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
4829
4830        HashMap<Uri, UriPermission> targetUris
4831                = mGrantedUriPermissions.get(targetUid);
4832        if (targetUris == null) {
4833            targetUris = new HashMap<Uri, UriPermission>();
4834            mGrantedUriPermissions.put(targetUid, targetUris);
4835        }
4836
4837        UriPermission perm = targetUris.get(uri);
4838        if (perm == null) {
4839            perm = new UriPermission(targetUid, uri);
4840            targetUris.put(uri, perm);
4841        }
4842
4843        perm.modeFlags |= modeFlags;
4844        if (owner == null) {
4845            perm.globalModeFlags |= modeFlags;
4846        } else {
4847            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4848                 perm.readOwners.add(owner);
4849                 owner.addReadPermission(perm);
4850            }
4851            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4852                 perm.writeOwners.add(owner);
4853                 owner.addWritePermission(perm);
4854            }
4855        }
4856    }
4857
4858    void grantUriPermissionLocked(int callingUid,
4859            String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
4860        if (targetPkg == null) {
4861            throw new NullPointerException("targetPkg");
4862        }
4863
4864        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4865        if (targetUid < 0) {
4866            return;
4867        }
4868
4869        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4870    }
4871
4872    /**
4873     * Like checkGrantUriPermissionLocked, but takes an Intent.
4874     */
4875    int checkGrantUriPermissionFromIntentLocked(int callingUid,
4876            String targetPkg, Intent intent) {
4877        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4878                "Checking URI perm to " + (intent != null ? intent.getData() : null)
4879                + " from " + intent + "; flags=0x"
4880                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4881
4882        if (targetPkg == null) {
4883            throw new NullPointerException("targetPkg");
4884        }
4885
4886        if (intent == null) {
4887            return -1;
4888        }
4889        Uri data = intent.getData();
4890        if (data == null) {
4891            return -1;
4892        }
4893        return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4894                intent.getFlags());
4895    }
4896
4897    /**
4898     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4899     */
4900    void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4901            String targetPkg, Intent intent, UriPermissionOwner owner) {
4902        grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4903                intent.getFlags(), owner);
4904    }
4905
4906    void grantUriPermissionFromIntentLocked(int callingUid,
4907            String targetPkg, Intent intent, UriPermissionOwner owner) {
4908        int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4909        if (targetUid < 0) {
4910            return;
4911        }
4912
4913        grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
4914    }
4915
4916    public void grantUriPermission(IApplicationThread caller, String targetPkg,
4917            Uri uri, int modeFlags) {
4918        synchronized(this) {
4919            final ProcessRecord r = getRecordForAppLocked(caller);
4920            if (r == null) {
4921                throw new SecurityException("Unable to find app for caller "
4922                        + caller
4923                        + " when granting permission to uri " + uri);
4924            }
4925            if (targetPkg == null) {
4926                throw new IllegalArgumentException("null target");
4927            }
4928            if (uri == null) {
4929                throw new IllegalArgumentException("null uri");
4930            }
4931
4932            grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4933                    null);
4934        }
4935    }
4936
4937    void removeUriPermissionIfNeededLocked(UriPermission perm) {
4938        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4939                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4940            HashMap<Uri, UriPermission> perms
4941                    = mGrantedUriPermissions.get(perm.uid);
4942            if (perms != null) {
4943                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4944                        "Removing " + perm.uid + " permission to " + perm.uri);
4945                perms.remove(perm.uri);
4946                if (perms.size() == 0) {
4947                    mGrantedUriPermissions.remove(perm.uid);
4948                }
4949            }
4950        }
4951    }
4952
4953    private void revokeUriPermissionLocked(int callingUid, Uri uri,
4954            int modeFlags) {
4955        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4956                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4957        if (modeFlags == 0) {
4958            return;
4959        }
4960
4961        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4962                "Revoking all granted permissions to " + uri);
4963
4964        final IPackageManager pm = AppGlobals.getPackageManager();
4965
4966        final String authority = uri.getAuthority();
4967        ProviderInfo pi = null;
4968        ContentProviderRecord cpr = mProvidersByName.get(authority);
4969        if (cpr != null) {
4970            pi = cpr.info;
4971        } else {
4972            try {
4973                pi = pm.resolveContentProvider(authority,
4974                        PackageManager.GET_URI_PERMISSION_PATTERNS);
4975            } catch (RemoteException ex) {
4976            }
4977        }
4978        if (pi == null) {
4979            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
4980            return;
4981        }
4982
4983        // Does the caller have this permission on the URI?
4984        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4985            // Right now, if you are not the original owner of the permission,
4986            // you are not allowed to revoke it.
4987            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4988                throw new SecurityException("Uid " + callingUid
4989                        + " does not have permission to uri " + uri);
4990            //}
4991        }
4992
4993        // Go through all of the permissions and remove any that match.
4994        final List<String> SEGMENTS = uri.getPathSegments();
4995        if (SEGMENTS != null) {
4996            final int NS = SEGMENTS.size();
4997            int N = mGrantedUriPermissions.size();
4998            for (int i=0; i<N; i++) {
4999                HashMap<Uri, UriPermission> perms
5000                        = mGrantedUriPermissions.valueAt(i);
5001                Iterator<UriPermission> it = perms.values().iterator();
5002            toploop:
5003                while (it.hasNext()) {
5004                    UriPermission perm = it.next();
5005                    Uri targetUri = perm.uri;
5006                    if (!authority.equals(targetUri.getAuthority())) {
5007                        continue;
5008                    }
5009                    List<String> targetSegments = targetUri.getPathSegments();
5010                    if (targetSegments == null) {
5011                        continue;
5012                    }
5013                    if (targetSegments.size() < NS) {
5014                        continue;
5015                    }
5016                    for (int j=0; j<NS; j++) {
5017                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5018                            continue toploop;
5019                        }
5020                    }
5021                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5022                            "Revoking " + perm.uid + " permission to " + perm.uri);
5023                    perm.clearModes(modeFlags);
5024                    if (perm.modeFlags == 0) {
5025                        it.remove();
5026                    }
5027                }
5028                if (perms.size() == 0) {
5029                    mGrantedUriPermissions.remove(
5030                            mGrantedUriPermissions.keyAt(i));
5031                    N--;
5032                    i--;
5033                }
5034            }
5035        }
5036    }
5037
5038    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5039            int modeFlags) {
5040        synchronized(this) {
5041            final ProcessRecord r = getRecordForAppLocked(caller);
5042            if (r == null) {
5043                throw new SecurityException("Unable to find app for caller "
5044                        + caller
5045                        + " when revoking permission to uri " + uri);
5046            }
5047            if (uri == null) {
5048                Slog.w(TAG, "revokeUriPermission: null uri");
5049                return;
5050            }
5051
5052            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5053                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5054            if (modeFlags == 0) {
5055                return;
5056            }
5057
5058            final IPackageManager pm = AppGlobals.getPackageManager();
5059
5060            final String authority = uri.getAuthority();
5061            ProviderInfo pi = null;
5062            ContentProviderRecord cpr = mProvidersByName.get(authority);
5063            if (cpr != null) {
5064                pi = cpr.info;
5065            } else {
5066                try {
5067                    pi = pm.resolveContentProvider(authority,
5068                            PackageManager.GET_URI_PERMISSION_PATTERNS);
5069                } catch (RemoteException ex) {
5070                }
5071            }
5072            if (pi == null) {
5073                Slog.w(TAG, "No content provider found for permission revoke: "
5074                        + uri.toSafeString());
5075                return;
5076            }
5077
5078            revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
5079        }
5080    }
5081
5082    @Override
5083    public IBinder newUriPermissionOwner(String name) {
5084        synchronized(this) {
5085            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5086            return owner.getExternalTokenLocked();
5087        }
5088    }
5089
5090    @Override
5091    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5092            Uri uri, int modeFlags) {
5093        synchronized(this) {
5094            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5095            if (owner == null) {
5096                throw new IllegalArgumentException("Unknown owner: " + token);
5097            }
5098            if (fromUid != Binder.getCallingUid()) {
5099                if (Binder.getCallingUid() != Process.myUid()) {
5100                    // Only system code can grant URI permissions on behalf
5101                    // of other users.
5102                    throw new SecurityException("nice try");
5103                }
5104            }
5105            if (targetPkg == null) {
5106                throw new IllegalArgumentException("null target");
5107            }
5108            if (uri == null) {
5109                throw new IllegalArgumentException("null uri");
5110            }
5111
5112            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5113        }
5114    }
5115
5116    @Override
5117    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5118        synchronized(this) {
5119            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5120            if (owner == null) {
5121                throw new IllegalArgumentException("Unknown owner: " + token);
5122            }
5123
5124            if (uri == null) {
5125                owner.removeUriPermissionsLocked(mode);
5126            } else {
5127                owner.removeUriPermissionLocked(uri, mode);
5128            }
5129        }
5130    }
5131
5132    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5133        synchronized (this) {
5134            ProcessRecord app =
5135                who != null ? getRecordForAppLocked(who) : null;
5136            if (app == null) return;
5137
5138            Message msg = Message.obtain();
5139            msg.what = WAIT_FOR_DEBUGGER_MSG;
5140            msg.obj = app;
5141            msg.arg1 = waiting ? 1 : 0;
5142            mHandler.sendMessage(msg);
5143        }
5144    }
5145
5146    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5147        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5148        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5149        outInfo.availMem = Process.getFreeMemory();
5150        outInfo.threshold = homeAppMem;
5151        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5152        outInfo.hiddenAppThreshold = hiddenAppMem;
5153        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5154                ProcessList.SERVICE_ADJ);
5155        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5156                ProcessList.VISIBLE_APP_ADJ);
5157        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5158                ProcessList.FOREGROUND_APP_ADJ);
5159    }
5160
5161    // =========================================================
5162    // TASK MANAGEMENT
5163    // =========================================================
5164
5165    public List getTasks(int maxNum, int flags,
5166                         IThumbnailReceiver receiver) {
5167        ArrayList list = new ArrayList();
5168
5169        PendingThumbnailsRecord pending = null;
5170        IApplicationThread topThumbnail = null;
5171        ActivityRecord topRecord = null;
5172
5173        synchronized(this) {
5174            if (localLOGV) Slog.v(
5175                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5176                + ", receiver=" + receiver);
5177
5178            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5179                    != PackageManager.PERMISSION_GRANTED) {
5180                if (receiver != null) {
5181                    // If the caller wants to wait for pending thumbnails,
5182                    // it ain't gonna get them.
5183                    try {
5184                        receiver.finished();
5185                    } catch (RemoteException ex) {
5186                    }
5187                }
5188                String msg = "Permission Denial: getTasks() from pid="
5189                        + Binder.getCallingPid()
5190                        + ", uid=" + Binder.getCallingUid()
5191                        + " requires " + android.Manifest.permission.GET_TASKS;
5192                Slog.w(TAG, msg);
5193                throw new SecurityException(msg);
5194            }
5195
5196            int pos = mMainStack.mHistory.size()-1;
5197            ActivityRecord next =
5198                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5199            ActivityRecord top = null;
5200            TaskRecord curTask = null;
5201            int numActivities = 0;
5202            int numRunning = 0;
5203            while (pos >= 0 && maxNum > 0) {
5204                final ActivityRecord r = next;
5205                pos--;
5206                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5207
5208                // Initialize state for next task if needed.
5209                if (top == null ||
5210                        (top.state == ActivityState.INITIALIZING
5211                            && top.task == r.task)) {
5212                    top = r;
5213                    curTask = r.task;
5214                    numActivities = numRunning = 0;
5215                }
5216
5217                // Add 'r' into the current task.
5218                numActivities++;
5219                if (r.app != null && r.app.thread != null) {
5220                    numRunning++;
5221                }
5222
5223                if (localLOGV) Slog.v(
5224                    TAG, r.intent.getComponent().flattenToShortString()
5225                    + ": task=" + r.task);
5226
5227                // If the next one is a different task, generate a new
5228                // TaskInfo entry for what we have.
5229                if (next == null || next.task != curTask) {
5230                    ActivityManager.RunningTaskInfo ci
5231                            = new ActivityManager.RunningTaskInfo();
5232                    ci.id = curTask.taskId;
5233                    ci.baseActivity = r.intent.getComponent();
5234                    ci.topActivity = top.intent.getComponent();
5235                    if (top.thumbHolder != null) {
5236                        ci.description = top.thumbHolder.lastDescription;
5237                    }
5238                    ci.numActivities = numActivities;
5239                    ci.numRunning = numRunning;
5240                    //System.out.println(
5241                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5242                    if (ci.thumbnail == null && receiver != null) {
5243                        if (localLOGV) Slog.v(
5244                            TAG, "State=" + top.state + "Idle=" + top.idle
5245                            + " app=" + top.app
5246                            + " thr=" + (top.app != null ? top.app.thread : null));
5247                        if (top.state == ActivityState.RESUMED
5248                                || top.state == ActivityState.PAUSING) {
5249                            if (top.idle && top.app != null
5250                                && top.app.thread != null) {
5251                                topRecord = top;
5252                                topThumbnail = top.app.thread;
5253                            } else {
5254                                top.thumbnailNeeded = true;
5255                            }
5256                        }
5257                        if (pending == null) {
5258                            pending = new PendingThumbnailsRecord(receiver);
5259                        }
5260                        pending.pendingRecords.add(top);
5261                    }
5262                    list.add(ci);
5263                    maxNum--;
5264                    top = null;
5265                }
5266            }
5267
5268            if (pending != null) {
5269                mPendingThumbnails.add(pending);
5270            }
5271        }
5272
5273        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5274
5275        if (topThumbnail != null) {
5276            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5277            try {
5278                topThumbnail.requestThumbnail(topRecord.appToken);
5279            } catch (Exception e) {
5280                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5281                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5282            }
5283        }
5284
5285        if (pending == null && receiver != null) {
5286            // In this case all thumbnails were available and the client
5287            // is being asked to be told when the remaining ones come in...
5288            // which is unusually, since the top-most currently running
5289            // activity should never have a canned thumbnail!  Oh well.
5290            try {
5291                receiver.finished();
5292            } catch (RemoteException ex) {
5293            }
5294        }
5295
5296        return list;
5297    }
5298
5299    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5300            int flags) {
5301        synchronized (this) {
5302            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5303                    "getRecentTasks()");
5304
5305            IPackageManager pm = AppGlobals.getPackageManager();
5306
5307            final int N = mRecentTasks.size();
5308            ArrayList<ActivityManager.RecentTaskInfo> res
5309                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5310                            maxNum < N ? maxNum : N);
5311            for (int i=0; i<N && maxNum > 0; i++) {
5312                TaskRecord tr = mRecentTasks.get(i);
5313                // Return the entry if desired by the caller.  We always return
5314                // the first entry, because callers always expect this to be the
5315                // forground app.  We may filter others if the caller has
5316                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5317                // we should exclude the entry.
5318                if (i == 0
5319                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5320                        || (tr.intent == null)
5321                        || ((tr.intent.getFlags()
5322                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5323                    ActivityManager.RecentTaskInfo rti
5324                            = new ActivityManager.RecentTaskInfo();
5325                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5326                    rti.persistentId = tr.taskId;
5327                    rti.baseIntent = new Intent(
5328                            tr.intent != null ? tr.intent : tr.affinityIntent);
5329                    rti.origActivity = tr.origActivity;
5330                    rti.description = tr.lastDescription;
5331
5332                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5333                        // Check whether this activity is currently available.
5334                        try {
5335                            if (rti.origActivity != null) {
5336                                if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5337                                    continue;
5338                                }
5339                            } else if (rti.baseIntent != null) {
5340                                if (pm.queryIntentActivities(rti.baseIntent,
5341                                        null, 0) == null) {
5342                                    continue;
5343                                }
5344                            }
5345                        } catch (RemoteException e) {
5346                            // Will never happen.
5347                        }
5348                    }
5349
5350                    res.add(rti);
5351                    maxNum--;
5352                }
5353            }
5354            return res;
5355        }
5356    }
5357
5358    private TaskRecord taskForIdLocked(int id) {
5359        final int N = mRecentTasks.size();
5360        for (int i=0; i<N; i++) {
5361            TaskRecord tr = mRecentTasks.get(i);
5362            if (tr.taskId == id) {
5363                return tr;
5364            }
5365        }
5366        return null;
5367    }
5368
5369    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5370        synchronized (this) {
5371            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5372                    "getTaskThumbnails()");
5373            TaskRecord tr = taskForIdLocked(id);
5374            if (tr != null) {
5375                return mMainStack.getTaskThumbnailsLocked(tr);
5376            }
5377        }
5378        return null;
5379    }
5380
5381    public boolean removeSubTask(int taskId, int subTaskIndex) {
5382        synchronized (this) {
5383            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5384                    "removeSubTask()");
5385            long ident = Binder.clearCallingIdentity();
5386            try {
5387                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5388            } finally {
5389                Binder.restoreCallingIdentity(ident);
5390            }
5391        }
5392    }
5393
5394    private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
5395        TaskRecord tr = root.task;
5396        Intent baseIntent = new Intent(
5397                tr.intent != null ? tr.intent : tr.affinityIntent);
5398        ComponentName component = baseIntent.getComponent();
5399        if (component == null) {
5400            Slog.w(TAG, "Now component for base intent of task: " + tr);
5401            return;
5402        }
5403
5404        // Find any running services associated with this app.
5405        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5406        for (ServiceRecord sr : mServices.values()) {
5407            if (sr.packageName.equals(component.getPackageName())) {
5408                services.add(sr);
5409            }
5410        }
5411
5412        // Take care of any running services associated with the app.
5413        for (int i=0; i<services.size(); i++) {
5414            ServiceRecord sr = services.get(i);
5415            if (sr.startRequested) {
5416                if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
5417                    Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
5418                    stopServiceLocked(sr);
5419                } else {
5420                    sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5421                            sr.makeNextStartId(), baseIntent, -1));
5422                    if (sr.app != null && sr.app.thread != null) {
5423                        sendServiceArgsLocked(sr, false);
5424                    }
5425                }
5426            }
5427        }
5428
5429        if (killProcesses) {
5430            // Find any running processes associated with this app.
5431            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5432            SparseArray<ProcessRecord> appProcs
5433                    = mProcessNames.getMap().get(component.getPackageName());
5434            if (appProcs != null) {
5435                for (int i=0; i<appProcs.size(); i++) {
5436                    procs.add(appProcs.valueAt(i));
5437                }
5438            }
5439
5440            // Kill the running processes.
5441            for (int i=0; i<procs.size(); i++) {
5442                ProcessRecord pr = procs.get(i);
5443                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5444                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5445                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5446                            pr.processName, pr.setAdj, "remove task");
5447                    Process.killProcessQuiet(pr.pid);
5448                } else {
5449                    pr.waitingToKill = "remove task";
5450                }
5451            }
5452        }
5453    }
5454
5455    public boolean removeTask(int taskId, int flags) {
5456        synchronized (this) {
5457            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5458                    "removeTask()");
5459            long ident = Binder.clearCallingIdentity();
5460            try {
5461                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5462                if (r != null) {
5463                    mRecentTasks.remove(r.task);
5464                    cleanUpRemovedTaskLocked(r,
5465                            (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
5466                    return true;
5467                } else {
5468                    TaskRecord tr = null;
5469                    int i=0;
5470                    while (i < mRecentTasks.size()) {
5471                        TaskRecord t = mRecentTasks.get(i);
5472                        if (t.taskId == taskId) {
5473                            tr = t;
5474                            break;
5475                        }
5476                        i++;
5477                    }
5478                    if (tr != null) {
5479                        if (tr.numActivities <= 0) {
5480                            // Caller is just removing a recent task that is
5481                            // not actively running.  That is easy!
5482                            mRecentTasks.remove(i);
5483                        } else {
5484                            Slog.w(TAG, "removeTask: task " + taskId
5485                                    + " does not have activities to remove, "
5486                                    + " but numActivities=" + tr.numActivities
5487                                    + ": " + tr);
5488                        }
5489                    }
5490                }
5491            } finally {
5492                Binder.restoreCallingIdentity(ident);
5493            }
5494        }
5495        return false;
5496    }
5497
5498    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5499        int j;
5500        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5501        TaskRecord jt = startTask;
5502
5503        // First look backwards
5504        for (j=startIndex-1; j>=0; j--) {
5505            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5506            if (r.task != jt) {
5507                jt = r.task;
5508                if (affinity.equals(jt.affinity)) {
5509                    return j;
5510                }
5511            }
5512        }
5513
5514        // Now look forwards
5515        final int N = mMainStack.mHistory.size();
5516        jt = startTask;
5517        for (j=startIndex+1; j<N; j++) {
5518            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5519            if (r.task != jt) {
5520                if (affinity.equals(jt.affinity)) {
5521                    return j;
5522                }
5523                jt = r.task;
5524            }
5525        }
5526
5527        // Might it be at the top?
5528        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5529            return N-1;
5530        }
5531
5532        return -1;
5533    }
5534
5535    /**
5536     * TODO: Add mController hook
5537     */
5538    public void moveTaskToFront(int task, int flags) {
5539        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5540                "moveTaskToFront()");
5541
5542        synchronized(this) {
5543            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5544                    Binder.getCallingUid(), "Task to front")) {
5545                return;
5546            }
5547            final long origId = Binder.clearCallingIdentity();
5548            try {
5549                TaskRecord tr = taskForIdLocked(task);
5550                if (tr != null) {
5551                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5552                        mMainStack.mUserLeaving = true;
5553                    }
5554                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5555                        // Caller wants the home activity moved with it.  To accomplish this,
5556                        // we'll just move the home task to the top first.
5557                        mMainStack.moveHomeToFrontLocked();
5558                    }
5559                    mMainStack.moveTaskToFrontLocked(tr, null);
5560                    return;
5561                }
5562                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5563                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5564                    if (hr.task.taskId == task) {
5565                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5566                            mMainStack.mUserLeaving = true;
5567                        }
5568                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5569                            // Caller wants the home activity moved with it.  To accomplish this,
5570                            // we'll just move the home task to the top first.
5571                            mMainStack.moveHomeToFrontLocked();
5572                        }
5573                        mMainStack.moveTaskToFrontLocked(hr.task, null);
5574                        return;
5575                    }
5576                }
5577            } finally {
5578                Binder.restoreCallingIdentity(origId);
5579            }
5580        }
5581    }
5582
5583    public void moveTaskToBack(int task) {
5584        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5585                "moveTaskToBack()");
5586
5587        synchronized(this) {
5588            if (mMainStack.mResumedActivity != null
5589                    && mMainStack.mResumedActivity.task.taskId == task) {
5590                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5591                        Binder.getCallingUid(), "Task to back")) {
5592                    return;
5593                }
5594            }
5595            final long origId = Binder.clearCallingIdentity();
5596            mMainStack.moveTaskToBackLocked(task, null);
5597            Binder.restoreCallingIdentity(origId);
5598        }
5599    }
5600
5601    /**
5602     * Moves an activity, and all of the other activities within the same task, to the bottom
5603     * of the history stack.  The activity's order within the task is unchanged.
5604     *
5605     * @param token A reference to the activity we wish to move
5606     * @param nonRoot If false then this only works if the activity is the root
5607     *                of a task; if true it will work for any activity in a task.
5608     * @return Returns true if the move completed, false if not.
5609     */
5610    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5611        synchronized(this) {
5612            final long origId = Binder.clearCallingIdentity();
5613            int taskId = getTaskForActivityLocked(token, !nonRoot);
5614            if (taskId >= 0) {
5615                return mMainStack.moveTaskToBackLocked(taskId, null);
5616            }
5617            Binder.restoreCallingIdentity(origId);
5618        }
5619        return false;
5620    }
5621
5622    public void moveTaskBackwards(int task) {
5623        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5624                "moveTaskBackwards()");
5625
5626        synchronized(this) {
5627            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5628                    Binder.getCallingUid(), "Task backwards")) {
5629                return;
5630            }
5631            final long origId = Binder.clearCallingIdentity();
5632            moveTaskBackwardsLocked(task);
5633            Binder.restoreCallingIdentity(origId);
5634        }
5635    }
5636
5637    private final void moveTaskBackwardsLocked(int task) {
5638        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5639    }
5640
5641    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5642        synchronized(this) {
5643            return getTaskForActivityLocked(token, onlyRoot);
5644        }
5645    }
5646
5647    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5648        final int N = mMainStack.mHistory.size();
5649        TaskRecord lastTask = null;
5650        for (int i=0; i<N; i++) {
5651            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5652            if (r.appToken == token) {
5653                if (!onlyRoot || lastTask != r.task) {
5654                    return r.task.taskId;
5655                }
5656                return -1;
5657            }
5658            lastTask = r.task;
5659        }
5660
5661        return -1;
5662    }
5663
5664    public void finishOtherInstances(IBinder token, ComponentName className) {
5665        synchronized(this) {
5666            final long origId = Binder.clearCallingIdentity();
5667
5668            int N = mMainStack.mHistory.size();
5669            TaskRecord lastTask = null;
5670            for (int i=0; i<N; i++) {
5671                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5672                if (r.realActivity.equals(className)
5673                        && r.appToken != token && lastTask != r.task) {
5674                    if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
5675                            null, "others")) {
5676                        i--;
5677                        N--;
5678                    }
5679                }
5680                lastTask = r.task;
5681            }
5682
5683            Binder.restoreCallingIdentity(origId);
5684        }
5685    }
5686
5687    // =========================================================
5688    // THUMBNAILS
5689    // =========================================================
5690
5691    public void reportThumbnail(IBinder token,
5692            Bitmap thumbnail, CharSequence description) {
5693        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5694        final long origId = Binder.clearCallingIdentity();
5695        sendPendingThumbnail(null, token, thumbnail, description, true);
5696        Binder.restoreCallingIdentity(origId);
5697    }
5698
5699    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5700            Bitmap thumbnail, CharSequence description, boolean always) {
5701        TaskRecord task = null;
5702        ArrayList receivers = null;
5703
5704        //System.out.println("Send pending thumbnail: " + r);
5705
5706        synchronized(this) {
5707            if (r == null) {
5708                r = mMainStack.isInStackLocked(token);
5709                if (r == null) {
5710                    return;
5711                }
5712            }
5713            if (thumbnail == null && r.thumbHolder != null) {
5714                thumbnail = r.thumbHolder.lastThumbnail;
5715                description = r.thumbHolder.lastDescription;
5716            }
5717            if (thumbnail == null && !always) {
5718                // If there is no thumbnail, and this entry is not actually
5719                // going away, then abort for now and pick up the next
5720                // thumbnail we get.
5721                return;
5722            }
5723            task = r.task;
5724
5725            int N = mPendingThumbnails.size();
5726            int i=0;
5727            while (i<N) {
5728                PendingThumbnailsRecord pr =
5729                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5730                //System.out.println("Looking in " + pr.pendingRecords);
5731                if (pr.pendingRecords.remove(r)) {
5732                    if (receivers == null) {
5733                        receivers = new ArrayList();
5734                    }
5735                    receivers.add(pr);
5736                    if (pr.pendingRecords.size() == 0) {
5737                        pr.finished = true;
5738                        mPendingThumbnails.remove(i);
5739                        N--;
5740                        continue;
5741                    }
5742                }
5743                i++;
5744            }
5745        }
5746
5747        if (receivers != null) {
5748            final int N = receivers.size();
5749            for (int i=0; i<N; i++) {
5750                try {
5751                    PendingThumbnailsRecord pr =
5752                        (PendingThumbnailsRecord)receivers.get(i);
5753                    pr.receiver.newThumbnail(
5754                        task != null ? task.taskId : -1, thumbnail, description);
5755                    if (pr.finished) {
5756                        pr.receiver.finished();
5757                    }
5758                } catch (Exception e) {
5759                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
5760                }
5761            }
5762        }
5763    }
5764
5765    // =========================================================
5766    // CONTENT PROVIDERS
5767    // =========================================================
5768
5769    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5770        List<ProviderInfo> providers = null;
5771        try {
5772            providers = AppGlobals.getPackageManager().
5773                queryContentProviders(app.processName, app.info.uid,
5774                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
5775        } catch (RemoteException ex) {
5776        }
5777        if (providers != null) {
5778            final int N = providers.size();
5779            for (int i=0; i<N; i++) {
5780                ProviderInfo cpi =
5781                    (ProviderInfo)providers.get(i);
5782                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5783                ContentProviderRecord cpr = mProvidersByClass.get(comp);
5784                if (cpr == null) {
5785                    cpr = new ContentProviderRecord(cpi, app.info, comp);
5786                    mProvidersByClass.put(comp, cpr);
5787                }
5788                app.pubProviders.put(cpi.name, cpr);
5789                app.addPackage(cpi.applicationInfo.packageName);
5790                ensurePackageDexOpt(cpi.applicationInfo.packageName);
5791            }
5792        }
5793        return providers;
5794    }
5795
5796    private final String checkContentProviderPermissionLocked(
5797            ProviderInfo cpi, ProcessRecord r) {
5798        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5799        final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5800        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
5801                cpi.applicationInfo.uid, cpi.exported)
5802                == PackageManager.PERMISSION_GRANTED) {
5803            return null;
5804        }
5805        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
5806                cpi.applicationInfo.uid, cpi.exported)
5807                == PackageManager.PERMISSION_GRANTED) {
5808            return null;
5809        }
5810
5811        PathPermission[] pps = cpi.pathPermissions;
5812        if (pps != null) {
5813            int i = pps.length;
5814            while (i > 0) {
5815                i--;
5816                PathPermission pp = pps[i];
5817                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
5818                        cpi.applicationInfo.uid, cpi.exported)
5819                        == PackageManager.PERMISSION_GRANTED) {
5820                    return null;
5821                }
5822                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
5823                        cpi.applicationInfo.uid, cpi.exported)
5824                        == PackageManager.PERMISSION_GRANTED) {
5825                    return null;
5826                }
5827            }
5828        }
5829
5830        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5831        if (perms != null) {
5832            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5833                if (uri.getKey().getAuthority().equals(cpi.authority)) {
5834                    return null;
5835                }
5836            }
5837        }
5838
5839        String msg;
5840        if (!cpi.exported) {
5841            msg = "Permission Denial: opening provider " + cpi.name
5842                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5843                    + ", uid=" + callingUid + ") that is not exported from uid "
5844                    + cpi.applicationInfo.uid;
5845        } else {
5846            msg = "Permission Denial: opening provider " + cpi.name
5847                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5848                    + ", uid=" + callingUid + ") requires "
5849                    + cpi.readPermission + " or " + cpi.writePermission;
5850        }
5851        Slog.w(TAG, msg);
5852        return msg;
5853    }
5854
5855    boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5856        if (r != null) {
5857            Integer cnt = r.conProviders.get(cpr);
5858            if (DEBUG_PROVIDER) Slog.v(TAG,
5859                    "Adding provider requested by "
5860                    + r.processName + " from process "
5861                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5862                    + " cnt=" + (cnt == null ? 1 : cnt));
5863            if (cnt == null) {
5864                cpr.clients.add(r);
5865                r.conProviders.put(cpr, new Integer(1));
5866                return true;
5867            } else {
5868                r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5869            }
5870        } else {
5871            cpr.externals++;
5872        }
5873        return false;
5874    }
5875
5876    boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5877        if (r != null) {
5878            Integer cnt = r.conProviders.get(cpr);
5879            if (DEBUG_PROVIDER) Slog.v(TAG,
5880                    "Removing provider requested by "
5881                    + r.processName + " from process "
5882                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5883                    + " cnt=" + cnt);
5884            if (cnt == null || cnt.intValue() <= 1) {
5885                cpr.clients.remove(r);
5886                r.conProviders.remove(cpr);
5887                return true;
5888            } else {
5889                r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
5890            }
5891        } else {
5892            cpr.externals++;
5893        }
5894        return false;
5895    }
5896
5897    private final ContentProviderHolder getContentProviderImpl(
5898        IApplicationThread caller, String name) {
5899        ContentProviderRecord cpr;
5900        ProviderInfo cpi = null;
5901
5902        synchronized(this) {
5903            ProcessRecord r = null;
5904            if (caller != null) {
5905                r = getRecordForAppLocked(caller);
5906                if (r == null) {
5907                    throw new SecurityException(
5908                            "Unable to find app for caller " + caller
5909                          + " (pid=" + Binder.getCallingPid()
5910                          + ") when getting content provider " + name);
5911                }
5912            }
5913
5914            // First check if this content provider has been published...
5915            cpr = mProvidersByName.get(name);
5916            boolean providerRunning = cpr != null;
5917            if (providerRunning) {
5918                cpi = cpr.info;
5919                String msg;
5920                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5921                    throw new SecurityException(msg);
5922                }
5923
5924                if (r != null && cpr.canRunHere(r)) {
5925                    // This provider has been published or is in the process
5926                    // of being published...  but it is also allowed to run
5927                    // in the caller's process, so don't make a connection
5928                    // and just let the caller instantiate its own instance.
5929                    if (cpr.provider != null) {
5930                        // don't give caller the provider object, it needs
5931                        // to make its own.
5932                        cpr = new ContentProviderRecord(cpr);
5933                    }
5934                    return cpr;
5935                }
5936
5937                final long origId = Binder.clearCallingIdentity();
5938
5939                // In this case the provider instance already exists, so we can
5940                // return it right away.
5941                final boolean countChanged = incProviderCount(r, cpr);
5942                if (countChanged) {
5943                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
5944                        // If this is a perceptible app accessing the provider,
5945                        // make sure to count it as being accessed and thus
5946                        // back up on the LRU list.  This is good because
5947                        // content providers are often expensive to start.
5948                        updateLruProcessLocked(cpr.proc, false, true);
5949                    }
5950                }
5951
5952                if (cpr.proc != null) {
5953                    if (false) {
5954                        if (cpr.name.flattenToShortString().equals(
5955                                "com.android.providers.calendar/.CalendarProvider2")) {
5956                            Slog.v(TAG, "****************** KILLING "
5957                                + cpr.name.flattenToShortString());
5958                            Process.killProcess(cpr.proc.pid);
5959                        }
5960                    }
5961                    boolean success = updateOomAdjLocked(cpr.proc);
5962                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
5963                    // NOTE: there is still a race here where a signal could be
5964                    // pending on the process even though we managed to update its
5965                    // adj level.  Not sure what to do about this, but at least
5966                    // the race is now smaller.
5967                    if (!success) {
5968                        // Uh oh...  it looks like the provider's process
5969                        // has been killed on us.  We need to wait for a new
5970                        // process to be started, and make sure its death
5971                        // doesn't kill our process.
5972                        Slog.i(TAG,
5973                                "Existing provider " + cpr.name.flattenToShortString()
5974                                + " is crashing; detaching " + r);
5975                        boolean lastRef = decProviderCount(r, cpr);
5976                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
5977                        if (!lastRef) {
5978                            // This wasn't the last ref our process had on
5979                            // the provider...  we have now been killed, bail.
5980                            return null;
5981                        }
5982                        providerRunning = false;
5983                    }
5984                }
5985
5986                Binder.restoreCallingIdentity(origId);
5987            }
5988
5989            if (!providerRunning) {
5990                try {
5991                    cpi = AppGlobals.getPackageManager().
5992                        resolveContentProvider(name,
5993                                STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
5994                } catch (RemoteException ex) {
5995                }
5996                if (cpi == null) {
5997                    return null;
5998                }
5999
6000                String msg;
6001                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6002                    throw new SecurityException(msg);
6003                }
6004
6005                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6006                        && !cpi.processName.equals("system")) {
6007                    // If this content provider does not run in the system
6008                    // process, and the system is not yet ready to run other
6009                    // processes, then fail fast instead of hanging.
6010                    throw new IllegalArgumentException(
6011                            "Attempt to launch content provider before system ready");
6012                }
6013
6014                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6015                cpr = mProvidersByClass.get(comp);
6016                final boolean firstClass = cpr == null;
6017                if (firstClass) {
6018                    try {
6019                        ApplicationInfo ai =
6020                            AppGlobals.getPackageManager().
6021                                getApplicationInfo(
6022                                        cpi.applicationInfo.packageName,
6023                                        STOCK_PM_FLAGS);
6024                        if (ai == null) {
6025                            Slog.w(TAG, "No package info for content provider "
6026                                    + cpi.name);
6027                            return null;
6028                        }
6029                        cpr = new ContentProviderRecord(cpi, ai, comp);
6030                    } catch (RemoteException ex) {
6031                        // pm is in same process, this will never happen.
6032                    }
6033                }
6034
6035                if (r != null && cpr.canRunHere(r)) {
6036                    // If this is a multiprocess provider, then just return its
6037                    // info and allow the caller to instantiate it.  Only do
6038                    // this if the provider is the same user as the caller's
6039                    // process, or can run as root (so can be in any process).
6040                    return cpr;
6041                }
6042
6043                if (DEBUG_PROVIDER) {
6044                    RuntimeException e = new RuntimeException("here");
6045                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
6046                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6047                }
6048
6049                // This is single process, and our app is now connecting to it.
6050                // See if we are already in the process of launching this
6051                // provider.
6052                final int N = mLaunchingProviders.size();
6053                int i;
6054                for (i=0; i<N; i++) {
6055                    if (mLaunchingProviders.get(i) == cpr) {
6056                        break;
6057                    }
6058                }
6059
6060                // If the provider is not already being launched, then get it
6061                // started.
6062                if (i >= N) {
6063                    final long origId = Binder.clearCallingIdentity();
6064
6065                    try {
6066                        // Content provider is now in use, its package can't be stopped.
6067                        try {
6068                            AppGlobals.getPackageManager().setPackageStoppedState(
6069                                    cpr.appInfo.packageName, false);
6070                        } catch (RemoteException e) {
6071                        } catch (IllegalArgumentException e) {
6072                            Slog.w(TAG, "Failed trying to unstop package "
6073                                    + cpr.appInfo.packageName + ": " + e);
6074                        }
6075
6076                        ProcessRecord proc = startProcessLocked(cpi.processName,
6077                                cpr.appInfo, false, 0, "content provider",
6078                                new ComponentName(cpi.applicationInfo.packageName,
6079                                        cpi.name), false);
6080                        if (proc == null) {
6081                            Slog.w(TAG, "Unable to launch app "
6082                                    + cpi.applicationInfo.packageName + "/"
6083                                    + cpi.applicationInfo.uid + " for provider "
6084                                    + name + ": process is bad");
6085                            return null;
6086                        }
6087                        cpr.launchingApp = proc;
6088                        mLaunchingProviders.add(cpr);
6089                    } finally {
6090                        Binder.restoreCallingIdentity(origId);
6091                    }
6092                }
6093
6094                // Make sure the provider is published (the same provider class
6095                // may be published under multiple names).
6096                if (firstClass) {
6097                    mProvidersByClass.put(comp, cpr);
6098                }
6099                mProvidersByName.put(name, cpr);
6100                incProviderCount(r, cpr);
6101            }
6102        }
6103
6104        // Wait for the provider to be published...
6105        synchronized (cpr) {
6106            while (cpr.provider == null) {
6107                if (cpr.launchingApp == null) {
6108                    Slog.w(TAG, "Unable to launch app "
6109                            + cpi.applicationInfo.packageName + "/"
6110                            + cpi.applicationInfo.uid + " for provider "
6111                            + name + ": launching app became null");
6112                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6113                            cpi.applicationInfo.packageName,
6114                            cpi.applicationInfo.uid, name);
6115                    return null;
6116                }
6117                try {
6118                    cpr.wait();
6119                } catch (InterruptedException ex) {
6120                }
6121            }
6122        }
6123        return cpr;
6124    }
6125
6126    public final ContentProviderHolder getContentProvider(
6127            IApplicationThread caller, String name) {
6128        if (caller == null) {
6129            String msg = "null IApplicationThread when getting content provider "
6130                    + name;
6131            Slog.w(TAG, msg);
6132            throw new SecurityException(msg);
6133        }
6134
6135        return getContentProviderImpl(caller, name);
6136    }
6137
6138    private ContentProviderHolder getContentProviderExternal(String name) {
6139        return getContentProviderImpl(null, name);
6140    }
6141
6142    /**
6143     * Drop a content provider from a ProcessRecord's bookkeeping
6144     * @param cpr
6145     */
6146    public void removeContentProvider(IApplicationThread caller, String name) {
6147        synchronized (this) {
6148            ContentProviderRecord cpr = mProvidersByName.get(name);
6149            if(cpr == null) {
6150                // remove from mProvidersByClass
6151                if (DEBUG_PROVIDER) Slog.v(TAG, name +
6152                        " provider not found in providers list");
6153                return;
6154            }
6155            final ProcessRecord r = getRecordForAppLocked(caller);
6156            if (r == null) {
6157                throw new SecurityException(
6158                        "Unable to find app for caller " + caller +
6159                        " when removing content provider " + name);
6160            }
6161            //update content provider record entry info
6162            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6163            ContentProviderRecord localCpr = mProvidersByClass.get(comp);
6164            if (localCpr.proc == r) {
6165                //should not happen. taken care of as a local provider
6166                Slog.w(TAG, "removeContentProvider called on local provider: "
6167                        + cpr.info.name + " in process " + r.processName);
6168                return;
6169            } else {
6170                if (decProviderCount(r, localCpr)) {
6171                    updateOomAdjLocked();
6172                }
6173            }
6174        }
6175    }
6176
6177    private void removeContentProviderExternal(String name) {
6178        synchronized (this) {
6179            ContentProviderRecord cpr = mProvidersByName.get(name);
6180            if(cpr == null) {
6181                //remove from mProvidersByClass
6182                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6183                return;
6184            }
6185
6186            //update content provider record entry info
6187            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6188            ContentProviderRecord localCpr = mProvidersByClass.get(comp);
6189            localCpr.externals--;
6190            if (localCpr.externals < 0) {
6191                Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
6192            }
6193            updateOomAdjLocked();
6194        }
6195    }
6196
6197    public final void publishContentProviders(IApplicationThread caller,
6198            List<ContentProviderHolder> providers) {
6199        if (providers == null) {
6200            return;
6201        }
6202
6203        synchronized(this) {
6204            final ProcessRecord r = getRecordForAppLocked(caller);
6205            if (r == null) {
6206                throw new SecurityException(
6207                        "Unable to find app for caller " + caller
6208                      + " (pid=" + Binder.getCallingPid()
6209                      + ") when publishing content providers");
6210            }
6211
6212            final long origId = Binder.clearCallingIdentity();
6213
6214            final int N = providers.size();
6215            for (int i=0; i<N; i++) {
6216                ContentProviderHolder src = providers.get(i);
6217                if (src == null || src.info == null || src.provider == null) {
6218                    continue;
6219                }
6220                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6221                if (dst != null) {
6222                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6223                    mProvidersByClass.put(comp, dst);
6224                    String names[] = dst.info.authority.split(";");
6225                    for (int j = 0; j < names.length; j++) {
6226                        mProvidersByName.put(names[j], dst);
6227                    }
6228
6229                    int NL = mLaunchingProviders.size();
6230                    int j;
6231                    for (j=0; j<NL; j++) {
6232                        if (mLaunchingProviders.get(j) == dst) {
6233                            mLaunchingProviders.remove(j);
6234                            j--;
6235                            NL--;
6236                        }
6237                    }
6238                    synchronized (dst) {
6239                        dst.provider = src.provider;
6240                        dst.proc = r;
6241                        dst.notifyAll();
6242                    }
6243                    updateOomAdjLocked(r);
6244                }
6245            }
6246
6247            Binder.restoreCallingIdentity(origId);
6248        }
6249    }
6250
6251    public static final void installSystemProviders() {
6252        List<ProviderInfo> providers;
6253        synchronized (mSelf) {
6254            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6255            providers = mSelf.generateApplicationProvidersLocked(app);
6256            if (providers != null) {
6257                for (int i=providers.size()-1; i>=0; i--) {
6258                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6259                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6260                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6261                                + ": not system .apk");
6262                        providers.remove(i);
6263                    }
6264                }
6265            }
6266        }
6267        if (providers != null) {
6268            mSystemThread.installSystemProviders(providers);
6269        }
6270
6271        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6272
6273        mSelf.mUsageStatsService.monitorPackages();
6274    }
6275
6276    /**
6277     * Allows app to retrieve the MIME type of a URI without having permission
6278     * to access its content provider.
6279     *
6280     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6281     *
6282     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6283     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6284     */
6285    public String getProviderMimeType(Uri uri) {
6286        final String name = uri.getAuthority();
6287        final long ident = Binder.clearCallingIdentity();
6288        ContentProviderHolder holder = null;
6289
6290        try {
6291            holder = getContentProviderExternal(name);
6292            if (holder != null) {
6293                return holder.provider.getType(uri);
6294            }
6295        } catch (RemoteException e) {
6296            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6297            return null;
6298        } finally {
6299            if (holder != null) {
6300                removeContentProviderExternal(name);
6301            }
6302            Binder.restoreCallingIdentity(ident);
6303        }
6304
6305        return null;
6306    }
6307
6308    // =========================================================
6309    // GLOBAL MANAGEMENT
6310    // =========================================================
6311
6312    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6313            ApplicationInfo info, String customProcess) {
6314        String proc = customProcess != null ? customProcess : info.processName;
6315        BatteryStatsImpl.Uid.Proc ps = null;
6316        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6317        synchronized (stats) {
6318            ps = stats.getProcessStatsLocked(info.uid, proc);
6319        }
6320        return new ProcessRecord(ps, thread, info, proc);
6321    }
6322
6323    final ProcessRecord addAppLocked(ApplicationInfo info) {
6324        ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6325
6326        if (app == null) {
6327            app = newProcessRecordLocked(null, info, null);
6328            mProcessNames.put(info.processName, info.uid, app);
6329            updateLruProcessLocked(app, true, true);
6330        }
6331
6332        // This package really, really can not be stopped.
6333        try {
6334            AppGlobals.getPackageManager().setPackageStoppedState(
6335                    info.packageName, false);
6336        } catch (RemoteException e) {
6337        } catch (IllegalArgumentException e) {
6338            Slog.w(TAG, "Failed trying to unstop package "
6339                    + info.packageName + ": " + e);
6340        }
6341
6342        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6343                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6344            app.persistent = true;
6345            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6346        }
6347        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6348            mPersistentStartingProcesses.add(app);
6349            startProcessLocked(app, "added application", app.processName);
6350        }
6351
6352        return app;
6353    }
6354
6355    public void unhandledBack() {
6356        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6357                "unhandledBack()");
6358
6359        synchronized(this) {
6360            int count = mMainStack.mHistory.size();
6361            if (DEBUG_SWITCH) Slog.d(
6362                TAG, "Performing unhandledBack(): stack size = " + count);
6363            if (count > 1) {
6364                final long origId = Binder.clearCallingIdentity();
6365                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6366                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6367                Binder.restoreCallingIdentity(origId);
6368            }
6369        }
6370    }
6371
6372    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6373        String name = uri.getAuthority();
6374        ContentProviderHolder cph = getContentProviderExternal(name);
6375        ParcelFileDescriptor pfd = null;
6376        if (cph != null) {
6377            // We record the binder invoker's uid in thread-local storage before
6378            // going to the content provider to open the file.  Later, in the code
6379            // that handles all permissions checks, we look for this uid and use
6380            // that rather than the Activity Manager's own uid.  The effect is that
6381            // we do the check against the caller's permissions even though it looks
6382            // to the content provider like the Activity Manager itself is making
6383            // the request.
6384            sCallerIdentity.set(new Identity(
6385                    Binder.getCallingPid(), Binder.getCallingUid()));
6386            try {
6387                pfd = cph.provider.openFile(uri, "r");
6388            } catch (FileNotFoundException e) {
6389                // do nothing; pfd will be returned null
6390            } finally {
6391                // Ensure that whatever happens, we clean up the identity state
6392                sCallerIdentity.remove();
6393            }
6394
6395            // We've got the fd now, so we're done with the provider.
6396            removeContentProviderExternal(name);
6397        } else {
6398            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6399        }
6400        return pfd;
6401    }
6402
6403    // Actually is sleeping or shutting down or whatever else in the future
6404    // is an inactive state.
6405    public boolean isSleeping() {
6406        return mSleeping || mShuttingDown;
6407    }
6408
6409    public void goingToSleep() {
6410        synchronized(this) {
6411            mSleeping = true;
6412            mWindowManager.setEventDispatching(false);
6413
6414            mMainStack.stopIfSleepingLocked();
6415
6416            // Initialize the wake times of all processes.
6417            checkExcessivePowerUsageLocked(false);
6418            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6419            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6420            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6421        }
6422    }
6423
6424    public boolean shutdown(int timeout) {
6425        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6426                != PackageManager.PERMISSION_GRANTED) {
6427            throw new SecurityException("Requires permission "
6428                    + android.Manifest.permission.SHUTDOWN);
6429        }
6430
6431        boolean timedout = false;
6432
6433        synchronized(this) {
6434            mShuttingDown = true;
6435            mWindowManager.setEventDispatching(false);
6436
6437            if (mMainStack.mResumedActivity != null) {
6438                mMainStack.stopIfSleepingLocked();
6439                final long endTime = System.currentTimeMillis() + timeout;
6440                while (mMainStack.mResumedActivity != null
6441                        || mMainStack.mPausingActivity != null) {
6442                    long delay = endTime - System.currentTimeMillis();
6443                    if (delay <= 0) {
6444                        Slog.w(TAG, "Activity manager shutdown timed out");
6445                        timedout = true;
6446                        break;
6447                    }
6448                    try {
6449                        this.wait();
6450                    } catch (InterruptedException e) {
6451                    }
6452                }
6453            }
6454        }
6455
6456        mUsageStatsService.shutdown();
6457        mBatteryStatsService.shutdown();
6458
6459        return timedout;
6460    }
6461
6462    public final void activitySlept(IBinder token) {
6463        if (localLOGV) Slog.v(
6464            TAG, "Activity slept: token=" + token);
6465
6466        ActivityRecord r = null;
6467
6468        final long origId = Binder.clearCallingIdentity();
6469
6470        synchronized (this) {
6471            r = mMainStack.isInStackLocked(token);
6472            if (r != null) {
6473                mMainStack.activitySleptLocked(r);
6474            }
6475        }
6476
6477        Binder.restoreCallingIdentity(origId);
6478    }
6479
6480    public void wakingUp() {
6481        synchronized(this) {
6482            mWindowManager.setEventDispatching(true);
6483            mSleeping = false;
6484            mMainStack.awakeFromSleepingLocked();
6485            mMainStack.resumeTopActivityLocked(null);
6486        }
6487    }
6488
6489    public void stopAppSwitches() {
6490        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6491                != PackageManager.PERMISSION_GRANTED) {
6492            throw new SecurityException("Requires permission "
6493                    + android.Manifest.permission.STOP_APP_SWITCHES);
6494        }
6495
6496        synchronized(this) {
6497            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6498                    + APP_SWITCH_DELAY_TIME;
6499            mDidAppSwitch = false;
6500            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6501            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6502            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6503        }
6504    }
6505
6506    public void resumeAppSwitches() {
6507        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6508                != PackageManager.PERMISSION_GRANTED) {
6509            throw new SecurityException("Requires permission "
6510                    + android.Manifest.permission.STOP_APP_SWITCHES);
6511        }
6512
6513        synchronized(this) {
6514            // Note that we don't execute any pending app switches... we will
6515            // let those wait until either the timeout, or the next start
6516            // activity request.
6517            mAppSwitchesAllowedTime = 0;
6518        }
6519    }
6520
6521    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6522            String name) {
6523        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6524            return true;
6525        }
6526
6527        final int perm = checkComponentPermission(
6528                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
6529                callingUid, -1, true);
6530        if (perm == PackageManager.PERMISSION_GRANTED) {
6531            return true;
6532        }
6533
6534        Slog.w(TAG, name + " request from " + callingUid + " stopped");
6535        return false;
6536    }
6537
6538    public void setDebugApp(String packageName, boolean waitForDebugger,
6539            boolean persistent) {
6540        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6541                "setDebugApp()");
6542
6543        // Note that this is not really thread safe if there are multiple
6544        // callers into it at the same time, but that's not a situation we
6545        // care about.
6546        if (persistent) {
6547            final ContentResolver resolver = mContext.getContentResolver();
6548            Settings.System.putString(
6549                resolver, Settings.System.DEBUG_APP,
6550                packageName);
6551            Settings.System.putInt(
6552                resolver, Settings.System.WAIT_FOR_DEBUGGER,
6553                waitForDebugger ? 1 : 0);
6554        }
6555
6556        synchronized (this) {
6557            if (!persistent) {
6558                mOrigDebugApp = mDebugApp;
6559                mOrigWaitForDebugger = mWaitForDebugger;
6560            }
6561            mDebugApp = packageName;
6562            mWaitForDebugger = waitForDebugger;
6563            mDebugTransient = !persistent;
6564            if (packageName != null) {
6565                final long origId = Binder.clearCallingIdentity();
6566                forceStopPackageLocked(packageName, -1, false, false, true, true);
6567                Binder.restoreCallingIdentity(origId);
6568            }
6569        }
6570    }
6571
6572    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6573            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6574        synchronized (this) {
6575            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6576            if (!isDebuggable) {
6577                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6578                    throw new SecurityException("Process not debuggable: " + app.packageName);
6579                }
6580            }
6581            mProfileApp = processName;
6582            mProfileFile = profileFile;
6583            if (mProfileFd != null) {
6584                try {
6585                    mProfileFd.close();
6586                } catch (IOException e) {
6587                }
6588                mProfileFd = null;
6589            }
6590            mProfileFd = profileFd;
6591            mProfileType = 0;
6592            mAutoStopProfiler = autoStopProfiler;
6593        }
6594    }
6595
6596    public void setAlwaysFinish(boolean enabled) {
6597        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6598                "setAlwaysFinish()");
6599
6600        Settings.System.putInt(
6601                mContext.getContentResolver(),
6602                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6603
6604        synchronized (this) {
6605            mAlwaysFinishActivities = enabled;
6606        }
6607    }
6608
6609    public void setActivityController(IActivityController controller) {
6610        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
6611                "setActivityController()");
6612        synchronized (this) {
6613            mController = controller;
6614        }
6615    }
6616
6617    public boolean isUserAMonkey() {
6618        // For now the fact that there is a controller implies
6619        // we have a monkey.
6620        synchronized (this) {
6621            return mController != null;
6622        }
6623    }
6624
6625    public void registerActivityWatcher(IActivityWatcher watcher) {
6626        synchronized (this) {
6627            mWatchers.register(watcher);
6628        }
6629    }
6630
6631    public void unregisterActivityWatcher(IActivityWatcher watcher) {
6632        synchronized (this) {
6633            mWatchers.unregister(watcher);
6634        }
6635    }
6636
6637    public void registerProcessObserver(IProcessObserver observer) {
6638        mProcessObservers.register(observer);
6639    }
6640
6641    public void unregisterProcessObserver(IProcessObserver observer) {
6642        mProcessObservers.unregister(observer);
6643    }
6644
6645    public void setImmersive(IBinder token, boolean immersive) {
6646        synchronized(this) {
6647            ActivityRecord r = mMainStack.isInStackLocked(token);
6648            if (r == null) {
6649                throw new IllegalArgumentException();
6650            }
6651            r.immersive = immersive;
6652        }
6653    }
6654
6655    public boolean isImmersive(IBinder token) {
6656        synchronized (this) {
6657            ActivityRecord r = mMainStack.isInStackLocked(token);
6658            if (r == null) {
6659                throw new IllegalArgumentException();
6660            }
6661            return r.immersive;
6662        }
6663    }
6664
6665    public boolean isTopActivityImmersive() {
6666        synchronized (this) {
6667            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
6668            return (r != null) ? r.immersive : false;
6669        }
6670    }
6671
6672    public final void enterSafeMode() {
6673        synchronized(this) {
6674            // It only makes sense to do this before the system is ready
6675            // and started launching other packages.
6676            if (!mSystemReady) {
6677                try {
6678                    AppGlobals.getPackageManager().enterSafeMode();
6679                } catch (RemoteException e) {
6680                }
6681            }
6682        }
6683    }
6684
6685    public final void showSafeModeOverlay() {
6686        View v = LayoutInflater.from(mContext).inflate(
6687                com.android.internal.R.layout.safe_mode, null);
6688        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6689        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6690        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6691        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6692        lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6693        lp.format = v.getBackground().getOpacity();
6694        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6695                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6696        ((WindowManager)mContext.getSystemService(
6697                Context.WINDOW_SERVICE)).addView(v, lp);
6698    }
6699
6700    public void noteWakeupAlarm(IIntentSender sender) {
6701        if (!(sender instanceof PendingIntentRecord)) {
6702            return;
6703        }
6704        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6705        synchronized (stats) {
6706            if (mBatteryStatsService.isOnBattery()) {
6707                mBatteryStatsService.enforceCallingPermission();
6708                PendingIntentRecord rec = (PendingIntentRecord)sender;
6709                int MY_UID = Binder.getCallingUid();
6710                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6711                BatteryStatsImpl.Uid.Pkg pkg =
6712                    stats.getPackageStatsLocked(uid, rec.key.packageName);
6713                pkg.incWakeupsLocked();
6714            }
6715        }
6716    }
6717
6718    public boolean killPids(int[] pids, String pReason, boolean secure) {
6719        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
6720            throw new SecurityException("killPids only available to the system");
6721        }
6722        String reason = (pReason == null) ? "Unknown" : pReason;
6723        // XXX Note: don't acquire main activity lock here, because the window
6724        // manager calls in with its locks held.
6725
6726        boolean killed = false;
6727        synchronized (mPidsSelfLocked) {
6728            int[] types = new int[pids.length];
6729            int worstType = 0;
6730            for (int i=0; i<pids.length; i++) {
6731                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6732                if (proc != null) {
6733                    int type = proc.setAdj;
6734                    types[i] = type;
6735                    if (type > worstType) {
6736                        worstType = type;
6737                    }
6738                }
6739            }
6740
6741            // If the worst oom_adj is somewhere in the hidden proc LRU range,
6742            // then constrain it so we will kill all hidden procs.
6743            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
6744                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
6745                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
6746            }
6747
6748            // If this is not a secure call, don't let it kill processes that
6749            // are important.
6750            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
6751                worstType = ProcessList.SERVICE_ADJ;
6752            }
6753
6754            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
6755            for (int i=0; i<pids.length; i++) {
6756                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6757                if (proc == null) {
6758                    continue;
6759                }
6760                int adj = proc.setAdj;
6761                if (adj >= worstType && !proc.killedBackground) {
6762                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
6763                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6764                            proc.processName, adj, reason);
6765                    killed = true;
6766                    proc.killedBackground = true;
6767                    Process.killProcessQuiet(pids[i]);
6768                }
6769            }
6770        }
6771        return killed;
6772    }
6773
6774    public final void startRunning(String pkg, String cls, String action,
6775            String data) {
6776        synchronized(this) {
6777            if (mStartRunning) {
6778                return;
6779            }
6780            mStartRunning = true;
6781            mTopComponent = pkg != null && cls != null
6782                    ? new ComponentName(pkg, cls) : null;
6783            mTopAction = action != null ? action : Intent.ACTION_MAIN;
6784            mTopData = data;
6785            if (!mSystemReady) {
6786                return;
6787            }
6788        }
6789
6790        systemReady(null);
6791    }
6792
6793    private void retrieveSettings() {
6794        final ContentResolver resolver = mContext.getContentResolver();
6795        String debugApp = Settings.System.getString(
6796            resolver, Settings.System.DEBUG_APP);
6797        boolean waitForDebugger = Settings.System.getInt(
6798            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6799        boolean alwaysFinishActivities = Settings.System.getInt(
6800            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6801
6802        Configuration configuration = new Configuration();
6803        Settings.System.getConfiguration(resolver, configuration);
6804
6805        synchronized (this) {
6806            mDebugApp = mOrigDebugApp = debugApp;
6807            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6808            mAlwaysFinishActivities = alwaysFinishActivities;
6809            // This happens before any activities are started, so we can
6810            // change mConfiguration in-place.
6811            updateConfigurationLocked(configuration, null, false, true);
6812            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
6813        }
6814    }
6815
6816    public boolean testIsSystemReady() {
6817        // no need to synchronize(this) just to read & return the value
6818        return mSystemReady;
6819    }
6820
6821    private static File getCalledPreBootReceiversFile() {
6822        File dataDir = Environment.getDataDirectory();
6823        File systemDir = new File(dataDir, "system");
6824        File fname = new File(systemDir, "called_pre_boots.dat");
6825        return fname;
6826    }
6827
6828    static final int LAST_DONE_VERSION = 10000;
6829
6830    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6831        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6832        File file = getCalledPreBootReceiversFile();
6833        FileInputStream fis = null;
6834        try {
6835            fis = new FileInputStream(file);
6836            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6837            int fvers = dis.readInt();
6838            if (fvers == LAST_DONE_VERSION) {
6839                String vers = dis.readUTF();
6840                String codename = dis.readUTF();
6841                String build = dis.readUTF();
6842                if (android.os.Build.VERSION.RELEASE.equals(vers)
6843                        && android.os.Build.VERSION.CODENAME.equals(codename)
6844                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6845                    int num = dis.readInt();
6846                    while (num > 0) {
6847                        num--;
6848                        String pkg = dis.readUTF();
6849                        String cls = dis.readUTF();
6850                        lastDoneReceivers.add(new ComponentName(pkg, cls));
6851                    }
6852                }
6853            }
6854        } catch (FileNotFoundException e) {
6855        } catch (IOException e) {
6856            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6857        } finally {
6858            if (fis != null) {
6859                try {
6860                    fis.close();
6861                } catch (IOException e) {
6862                }
6863            }
6864        }
6865        return lastDoneReceivers;
6866    }
6867
6868    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6869        File file = getCalledPreBootReceiversFile();
6870        FileOutputStream fos = null;
6871        DataOutputStream dos = null;
6872        try {
6873            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6874            fos = new FileOutputStream(file);
6875            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6876            dos.writeInt(LAST_DONE_VERSION);
6877            dos.writeUTF(android.os.Build.VERSION.RELEASE);
6878            dos.writeUTF(android.os.Build.VERSION.CODENAME);
6879            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
6880            dos.writeInt(list.size());
6881            for (int i=0; i<list.size(); i++) {
6882                dos.writeUTF(list.get(i).getPackageName());
6883                dos.writeUTF(list.get(i).getClassName());
6884            }
6885        } catch (IOException e) {
6886            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6887            file.delete();
6888        } finally {
6889            FileUtils.sync(fos);
6890            if (dos != null) {
6891                try {
6892                    dos.close();
6893                } catch (IOException e) {
6894                    // TODO Auto-generated catch block
6895                    e.printStackTrace();
6896                }
6897            }
6898        }
6899    }
6900
6901    public void systemReady(final Runnable goingCallback) {
6902        synchronized(this) {
6903            if (mSystemReady) {
6904                if (goingCallback != null) goingCallback.run();
6905                return;
6906            }
6907
6908            // Check to see if there are any update receivers to run.
6909            if (!mDidUpdate) {
6910                if (mWaitingUpdate) {
6911                    return;
6912                }
6913                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6914                List<ResolveInfo> ris = null;
6915                try {
6916                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
6917                                intent, null, 0);
6918                } catch (RemoteException e) {
6919                }
6920                if (ris != null) {
6921                    for (int i=ris.size()-1; i>=0; i--) {
6922                        if ((ris.get(i).activityInfo.applicationInfo.flags
6923                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
6924                            ris.remove(i);
6925                        }
6926                    }
6927                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
6928
6929                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6930
6931                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
6932                    for (int i=0; i<ris.size(); i++) {
6933                        ActivityInfo ai = ris.get(i).activityInfo;
6934                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
6935                        if (lastDoneReceivers.contains(comp)) {
6936                            ris.remove(i);
6937                            i--;
6938                        }
6939                    }
6940
6941                    for (int i=0; i<ris.size(); i++) {
6942                        ActivityInfo ai = ris.get(i).activityInfo;
6943                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
6944                        doneReceivers.add(comp);
6945                        intent.setComponent(comp);
6946                        IIntentReceiver finisher = null;
6947                        if (i == ris.size()-1) {
6948                            finisher = new IIntentReceiver.Stub() {
6949                                public void performReceive(Intent intent, int resultCode,
6950                                        String data, Bundle extras, boolean ordered,
6951                                        boolean sticky) {
6952                                    // The raw IIntentReceiver interface is called
6953                                    // with the AM lock held, so redispatch to
6954                                    // execute our code without the lock.
6955                                    mHandler.post(new Runnable() {
6956                                        public void run() {
6957                                            synchronized (ActivityManagerService.this) {
6958                                                mDidUpdate = true;
6959                                            }
6960                                            writeLastDonePreBootReceivers(doneReceivers);
6961                                            showBootMessage(mContext.getText(
6962                                                    R.string.android_upgrading_complete),
6963                                                    false);
6964                                            systemReady(goingCallback);
6965                                        }
6966                                    });
6967                                }
6968                            };
6969                        }
6970                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
6971                        broadcastIntentLocked(null, null, intent, null, finisher,
6972                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
6973                        if (finisher != null) {
6974                            mWaitingUpdate = true;
6975                        }
6976                    }
6977                }
6978                if (mWaitingUpdate) {
6979                    return;
6980                }
6981                mDidUpdate = true;
6982            }
6983
6984            mSystemReady = true;
6985            if (!mStartRunning) {
6986                return;
6987            }
6988        }
6989
6990        ArrayList<ProcessRecord> procsToKill = null;
6991        synchronized(mPidsSelfLocked) {
6992            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6993                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6994                if (!isAllowedWhileBooting(proc.info)){
6995                    if (procsToKill == null) {
6996                        procsToKill = new ArrayList<ProcessRecord>();
6997                    }
6998                    procsToKill.add(proc);
6999                }
7000            }
7001        }
7002
7003        synchronized(this) {
7004            if (procsToKill != null) {
7005                for (int i=procsToKill.size()-1; i>=0; i--) {
7006                    ProcessRecord proc = procsToKill.get(i);
7007                    Slog.i(TAG, "Removing system update proc: " + proc);
7008                    removeProcessLocked(proc, true, false, "system update done");
7009                }
7010            }
7011
7012            // Now that we have cleaned up any update processes, we
7013            // are ready to start launching real processes and know that
7014            // we won't trample on them any more.
7015            mProcessesReady = true;
7016        }
7017
7018        Slog.i(TAG, "System now ready");
7019        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7020            SystemClock.uptimeMillis());
7021
7022        synchronized(this) {
7023            // Make sure we have no pre-ready processes sitting around.
7024
7025            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7026                ResolveInfo ri = mContext.getPackageManager()
7027                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7028                                STOCK_PM_FLAGS);
7029                CharSequence errorMsg = null;
7030                if (ri != null) {
7031                    ActivityInfo ai = ri.activityInfo;
7032                    ApplicationInfo app = ai.applicationInfo;
7033                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7034                        mTopAction = Intent.ACTION_FACTORY_TEST;
7035                        mTopData = null;
7036                        mTopComponent = new ComponentName(app.packageName,
7037                                ai.name);
7038                    } else {
7039                        errorMsg = mContext.getResources().getText(
7040                                com.android.internal.R.string.factorytest_not_system);
7041                    }
7042                } else {
7043                    errorMsg = mContext.getResources().getText(
7044                            com.android.internal.R.string.factorytest_no_action);
7045                }
7046                if (errorMsg != null) {
7047                    mTopAction = null;
7048                    mTopData = null;
7049                    mTopComponent = null;
7050                    Message msg = Message.obtain();
7051                    msg.what = SHOW_FACTORY_ERROR_MSG;
7052                    msg.getData().putCharSequence("msg", errorMsg);
7053                    mHandler.sendMessage(msg);
7054                }
7055            }
7056        }
7057
7058        retrieveSettings();
7059
7060        if (goingCallback != null) goingCallback.run();
7061
7062        synchronized (this) {
7063            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7064                try {
7065                    List apps = AppGlobals.getPackageManager().
7066                        getPersistentApplications(STOCK_PM_FLAGS);
7067                    if (apps != null) {
7068                        int N = apps.size();
7069                        int i;
7070                        for (i=0; i<N; i++) {
7071                            ApplicationInfo info
7072                                = (ApplicationInfo)apps.get(i);
7073                            if (info != null &&
7074                                    !info.packageName.equals("android")) {
7075                                addAppLocked(info);
7076                            }
7077                        }
7078                    }
7079                } catch (RemoteException ex) {
7080                    // pm is in same process, this will never happen.
7081                }
7082            }
7083
7084            // Start up initial activity.
7085            mBooting = true;
7086
7087            try {
7088                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7089                    Message msg = Message.obtain();
7090                    msg.what = SHOW_UID_ERROR_MSG;
7091                    mHandler.sendMessage(msg);
7092                }
7093            } catch (RemoteException e) {
7094            }
7095
7096            mMainStack.resumeTopActivityLocked(null);
7097        }
7098    }
7099
7100    private boolean makeAppCrashingLocked(ProcessRecord app,
7101            String shortMsg, String longMsg, String stackTrace) {
7102        app.crashing = true;
7103        app.crashingReport = generateProcessError(app,
7104                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7105        startAppProblemLocked(app);
7106        app.stopFreezingAllLocked();
7107        return handleAppCrashLocked(app);
7108    }
7109
7110    private void makeAppNotRespondingLocked(ProcessRecord app,
7111            String activity, String shortMsg, String longMsg) {
7112        app.notResponding = true;
7113        app.notRespondingReport = generateProcessError(app,
7114                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7115                activity, shortMsg, longMsg, null);
7116        startAppProblemLocked(app);
7117        app.stopFreezingAllLocked();
7118    }
7119
7120    /**
7121     * Generate a process error record, suitable for attachment to a ProcessRecord.
7122     *
7123     * @param app The ProcessRecord in which the error occurred.
7124     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7125     *                      ActivityManager.AppErrorStateInfo
7126     * @param activity The activity associated with the crash, if known.
7127     * @param shortMsg Short message describing the crash.
7128     * @param longMsg Long message describing the crash.
7129     * @param stackTrace Full crash stack trace, may be null.
7130     *
7131     * @return Returns a fully-formed AppErrorStateInfo record.
7132     */
7133    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7134            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7135        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7136
7137        report.condition = condition;
7138        report.processName = app.processName;
7139        report.pid = app.pid;
7140        report.uid = app.info.uid;
7141        report.tag = activity;
7142        report.shortMsg = shortMsg;
7143        report.longMsg = longMsg;
7144        report.stackTrace = stackTrace;
7145
7146        return report;
7147    }
7148
7149    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7150        synchronized (this) {
7151            app.crashing = false;
7152            app.crashingReport = null;
7153            app.notResponding = false;
7154            app.notRespondingReport = null;
7155            if (app.anrDialog == fromDialog) {
7156                app.anrDialog = null;
7157            }
7158            if (app.waitDialog == fromDialog) {
7159                app.waitDialog = null;
7160            }
7161            if (app.pid > 0 && app.pid != MY_PID) {
7162                handleAppCrashLocked(app);
7163                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7164                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7165                        app.processName, app.setAdj, "user's request after error");
7166                Process.killProcessQuiet(app.pid);
7167            }
7168        }
7169    }
7170
7171    private boolean handleAppCrashLocked(ProcessRecord app) {
7172        long now = SystemClock.uptimeMillis();
7173
7174        Long crashTime = mProcessCrashTimes.get(app.info.processName,
7175                app.info.uid);
7176        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7177            // This process loses!
7178            Slog.w(TAG, "Process " + app.info.processName
7179                    + " has crashed too many times: killing!");
7180            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7181                    app.info.processName, app.info.uid);
7182            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7183                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7184                if (r.app == app) {
7185                    Slog.w(TAG, "  Force finishing activity "
7186                        + r.intent.getComponent().flattenToShortString());
7187                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7188                }
7189            }
7190            if (!app.persistent) {
7191                // We don't want to start this process again until the user
7192                // explicitly does so...  but for persistent process, we really
7193                // need to keep it running.  If a persistent process is actually
7194                // repeatedly crashing, then badness for everyone.
7195                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
7196                        app.info.processName);
7197                mBadProcesses.put(app.info.processName, app.info.uid, now);
7198                app.bad = true;
7199                mProcessCrashTimes.remove(app.info.processName, app.info.uid);
7200                app.removed = true;
7201                // Don't let services in this process be restarted and potentially
7202                // annoy the user repeatedly.  Unless it is persistent, since those
7203                // processes run critical code.
7204                removeProcessLocked(app, false, false, "crash");
7205                mMainStack.resumeTopActivityLocked(null);
7206                return false;
7207            }
7208            mMainStack.resumeTopActivityLocked(null);
7209        } else {
7210            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7211            if (r.app == app) {
7212                // If the top running activity is from this crashing
7213                // process, then terminate it to avoid getting in a loop.
7214                Slog.w(TAG, "  Force finishing activity "
7215                        + r.intent.getComponent().flattenToShortString());
7216                int index = mMainStack.indexOfActivityLocked(r);
7217                r.stack.finishActivityLocked(r, index,
7218                        Activity.RESULT_CANCELED, null, "crashed");
7219                // Also terminate any activities below it that aren't yet
7220                // stopped, to avoid a situation where one will get
7221                // re-start our crashing activity once it gets resumed again.
7222                index--;
7223                if (index >= 0) {
7224                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7225                    if (r.state == ActivityState.RESUMED
7226                            || r.state == ActivityState.PAUSING
7227                            || r.state == ActivityState.PAUSED) {
7228                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7229                            Slog.w(TAG, "  Force finishing activity "
7230                                    + r.intent.getComponent().flattenToShortString());
7231                            r.stack.finishActivityLocked(r, index,
7232                                    Activity.RESULT_CANCELED, null, "crashed");
7233                        }
7234                    }
7235                }
7236            }
7237        }
7238
7239        // Bump up the crash count of any services currently running in the proc.
7240        if (app.services.size() != 0) {
7241            // Any services running in the application need to be placed
7242            // back in the pending list.
7243            Iterator<ServiceRecord> it = app.services.iterator();
7244            while (it.hasNext()) {
7245                ServiceRecord sr = it.next();
7246                sr.crashCount++;
7247            }
7248        }
7249
7250        // If the crashing process is what we consider to be the "home process" and it has been
7251        // replaced by a third-party app, clear the package preferred activities from packages
7252        // with a home activity running in the process to prevent a repeatedly crashing app
7253        // from blocking the user to manually clear the list.
7254        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7255                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7256            Iterator it = mHomeProcess.activities.iterator();
7257            while (it.hasNext()) {
7258                ActivityRecord r = (ActivityRecord)it.next();
7259                if (r.isHomeActivity) {
7260                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7261                    try {
7262                        ActivityThread.getPackageManager()
7263                                .clearPackagePreferredActivities(r.packageName);
7264                    } catch (RemoteException c) {
7265                        // pm is in same process, this will never happen.
7266                    }
7267                }
7268            }
7269        }
7270
7271        mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
7272        return true;
7273    }
7274
7275    void startAppProblemLocked(ProcessRecord app) {
7276        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7277                mContext, app.info.packageName, app.info.flags);
7278        skipCurrentReceiverLocked(app);
7279    }
7280
7281    void skipCurrentReceiverLocked(ProcessRecord app) {
7282        boolean reschedule = false;
7283        BroadcastRecord r = app.curReceiver;
7284        if (r != null) {
7285            // The current broadcast is waiting for this app's receiver
7286            // to be finished.  Looks like that's not going to happen, so
7287            // let the broadcast continue.
7288            logBroadcastReceiverDiscardLocked(r);
7289            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7290                    r.resultExtras, r.resultAbort, true);
7291            reschedule = true;
7292        }
7293        r = mPendingBroadcast;
7294        if (r != null && r.curApp == app) {
7295            if (DEBUG_BROADCAST) Slog.v(TAG,
7296                    "skip & discard pending app " + r);
7297            logBroadcastReceiverDiscardLocked(r);
7298            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7299                    r.resultExtras, r.resultAbort, true);
7300            reschedule = true;
7301        }
7302        if (reschedule) {
7303            scheduleBroadcastsLocked();
7304        }
7305    }
7306
7307    /**
7308     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7309     * The application process will exit immediately after this call returns.
7310     * @param app object of the crashing app, null for the system server
7311     * @param crashInfo describing the exception
7312     */
7313    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7314        ProcessRecord r = findAppProcess(app, "Crash");
7315        final String processName = app == null ? "system_server"
7316                : (r == null ? "unknown" : r.processName);
7317
7318        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7319                processName,
7320                r == null ? -1 : r.info.flags,
7321                crashInfo.exceptionClassName,
7322                crashInfo.exceptionMessage,
7323                crashInfo.throwFileName,
7324                crashInfo.throwLineNumber);
7325
7326        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7327
7328        crashApplication(r, crashInfo);
7329    }
7330
7331    public void handleApplicationStrictModeViolation(
7332            IBinder app,
7333            int violationMask,
7334            StrictMode.ViolationInfo info) {
7335        ProcessRecord r = findAppProcess(app, "StrictMode");
7336        if (r == null) {
7337            return;
7338        }
7339
7340        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7341            Integer stackFingerprint = info.hashCode();
7342            boolean logIt = true;
7343            synchronized (mAlreadyLoggedViolatedStacks) {
7344                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7345                    logIt = false;
7346                    // TODO: sub-sample into EventLog for these, with
7347                    // the info.durationMillis?  Then we'd get
7348                    // the relative pain numbers, without logging all
7349                    // the stack traces repeatedly.  We'd want to do
7350                    // likewise in the client code, which also does
7351                    // dup suppression, before the Binder call.
7352                } else {
7353                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7354                        mAlreadyLoggedViolatedStacks.clear();
7355                    }
7356                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7357                }
7358            }
7359            if (logIt) {
7360                logStrictModeViolationToDropBox(r, info);
7361            }
7362        }
7363
7364        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7365            AppErrorResult result = new AppErrorResult();
7366            synchronized (this) {
7367                final long origId = Binder.clearCallingIdentity();
7368
7369                Message msg = Message.obtain();
7370                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7371                HashMap<String, Object> data = new HashMap<String, Object>();
7372                data.put("result", result);
7373                data.put("app", r);
7374                data.put("violationMask", violationMask);
7375                data.put("info", info);
7376                msg.obj = data;
7377                mHandler.sendMessage(msg);
7378
7379                Binder.restoreCallingIdentity(origId);
7380            }
7381            int res = result.get();
7382            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7383        }
7384    }
7385
7386    // Depending on the policy in effect, there could be a bunch of
7387    // these in quick succession so we try to batch these together to
7388    // minimize disk writes, number of dropbox entries, and maximize
7389    // compression, by having more fewer, larger records.
7390    private void logStrictModeViolationToDropBox(
7391            ProcessRecord process,
7392            StrictMode.ViolationInfo info) {
7393        if (info == null) {
7394            return;
7395        }
7396        final boolean isSystemApp = process == null ||
7397                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7398                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7399        final String processName = process == null ? "unknown" : process.processName;
7400        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7401        final DropBoxManager dbox = (DropBoxManager)
7402                mContext.getSystemService(Context.DROPBOX_SERVICE);
7403
7404        // Exit early if the dropbox isn't configured to accept this report type.
7405        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7406
7407        boolean bufferWasEmpty;
7408        boolean needsFlush;
7409        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7410        synchronized (sb) {
7411            bufferWasEmpty = sb.length() == 0;
7412            appendDropBoxProcessHeaders(process, processName, sb);
7413            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7414            sb.append("System-App: ").append(isSystemApp).append("\n");
7415            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7416            if (info.violationNumThisLoop != 0) {
7417                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7418            }
7419            if (info.numAnimationsRunning != 0) {
7420                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7421            }
7422            if (info.broadcastIntentAction != null) {
7423                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7424            }
7425            if (info.durationMillis != -1) {
7426                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
7427            }
7428            if (info.numInstances != -1) {
7429                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7430            }
7431            if (info.tags != null) {
7432                for (String tag : info.tags) {
7433                    sb.append("Span-Tag: ").append(tag).append("\n");
7434                }
7435            }
7436            sb.append("\n");
7437            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7438                sb.append(info.crashInfo.stackTrace);
7439            }
7440            sb.append("\n");
7441
7442            // Only buffer up to ~64k.  Various logging bits truncate
7443            // things at 128k.
7444            needsFlush = (sb.length() > 64 * 1024);
7445        }
7446
7447        // Flush immediately if the buffer's grown too large, or this
7448        // is a non-system app.  Non-system apps are isolated with a
7449        // different tag & policy and not batched.
7450        //
7451        // Batching is useful during internal testing with
7452        // StrictMode settings turned up high.  Without batching,
7453        // thousands of separate files could be created on boot.
7454        if (!isSystemApp || needsFlush) {
7455            new Thread("Error dump: " + dropboxTag) {
7456                @Override
7457                public void run() {
7458                    String report;
7459                    synchronized (sb) {
7460                        report = sb.toString();
7461                        sb.delete(0, sb.length());
7462                        sb.trimToSize();
7463                    }
7464                    if (report.length() != 0) {
7465                        dbox.addText(dropboxTag, report);
7466                    }
7467                }
7468            }.start();
7469            return;
7470        }
7471
7472        // System app batching:
7473        if (!bufferWasEmpty) {
7474            // An existing dropbox-writing thread is outstanding, so
7475            // we don't need to start it up.  The existing thread will
7476            // catch the buffer appends we just did.
7477            return;
7478        }
7479
7480        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7481        // (After this point, we shouldn't access AMS internal data structures.)
7482        new Thread("Error dump: " + dropboxTag) {
7483            @Override
7484            public void run() {
7485                // 5 second sleep to let stacks arrive and be batched together
7486                try {
7487                    Thread.sleep(5000);  // 5 seconds
7488                } catch (InterruptedException e) {}
7489
7490                String errorReport;
7491                synchronized (mStrictModeBuffer) {
7492                    errorReport = mStrictModeBuffer.toString();
7493                    if (errorReport.length() == 0) {
7494                        return;
7495                    }
7496                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7497                    mStrictModeBuffer.trimToSize();
7498                }
7499                dbox.addText(dropboxTag, errorReport);
7500            }
7501        }.start();
7502    }
7503
7504    /**
7505     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7506     * @param app object of the crashing app, null for the system server
7507     * @param tag reported by the caller
7508     * @param crashInfo describing the context of the error
7509     * @return true if the process should exit immediately (WTF is fatal)
7510     */
7511    public boolean handleApplicationWtf(IBinder app, String tag,
7512            ApplicationErrorReport.CrashInfo crashInfo) {
7513        ProcessRecord r = findAppProcess(app, "WTF");
7514        final String processName = app == null ? "system_server"
7515                : (r == null ? "unknown" : r.processName);
7516
7517        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7518                processName,
7519                r == null ? -1 : r.info.flags,
7520                tag, crashInfo.exceptionMessage);
7521
7522        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
7523
7524        if (r != null && r.pid != Process.myPid() &&
7525                Settings.Secure.getInt(mContext.getContentResolver(),
7526                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
7527            crashApplication(r, crashInfo);
7528            return true;
7529        } else {
7530            return false;
7531        }
7532    }
7533
7534    /**
7535     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7536     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7537     */
7538    private ProcessRecord findAppProcess(IBinder app, String reason) {
7539        if (app == null) {
7540            return null;
7541        }
7542
7543        synchronized (this) {
7544            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7545                final int NA = apps.size();
7546                for (int ia=0; ia<NA; ia++) {
7547                    ProcessRecord p = apps.valueAt(ia);
7548                    if (p.thread != null && p.thread.asBinder() == app) {
7549                        return p;
7550                    }
7551                }
7552            }
7553
7554            Slog.w(TAG, "Can't find mystery application for " + reason
7555                    + " from pid=" + Binder.getCallingPid()
7556                    + " uid=" + Binder.getCallingUid() + ": " + app);
7557            return null;
7558        }
7559    }
7560
7561    /**
7562     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7563     * to append various headers to the dropbox log text.
7564     */
7565    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
7566            StringBuilder sb) {
7567        // Watchdog thread ends up invoking this function (with
7568        // a null ProcessRecord) to add the stack file to dropbox.
7569        // Do not acquire a lock on this (am) in such cases, as it
7570        // could cause a potential deadlock, if and when watchdog
7571        // is invoked due to unavailability of lock on am and it
7572        // would prevent watchdog from killing system_server.
7573        if (process == null) {
7574            sb.append("Process: ").append(processName).append("\n");
7575            return;
7576        }
7577        // Note: ProcessRecord 'process' is guarded by the service
7578        // instance.  (notably process.pkgList, which could otherwise change
7579        // concurrently during execution of this method)
7580        synchronized (this) {
7581            sb.append("Process: ").append(processName).append("\n");
7582            int flags = process.info.flags;
7583            IPackageManager pm = AppGlobals.getPackageManager();
7584            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7585            for (String pkg : process.pkgList) {
7586                sb.append("Package: ").append(pkg);
7587                try {
7588                    PackageInfo pi = pm.getPackageInfo(pkg, 0);
7589                    if (pi != null) {
7590                        sb.append(" v").append(pi.versionCode);
7591                        if (pi.versionName != null) {
7592                            sb.append(" (").append(pi.versionName).append(")");
7593                        }
7594                    }
7595                } catch (RemoteException e) {
7596                    Slog.e(TAG, "Error getting package info: " + pkg, e);
7597                }
7598                sb.append("\n");
7599            }
7600        }
7601    }
7602
7603    private static String processClass(ProcessRecord process) {
7604        if (process == null || process.pid == MY_PID) {
7605            return "system_server";
7606        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7607            return "system_app";
7608        } else {
7609            return "data_app";
7610        }
7611    }
7612
7613    /**
7614     * Write a description of an error (crash, WTF, ANR) to the drop box.
7615     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7616     * @param process which caused the error, null means the system server
7617     * @param activity which triggered the error, null if unknown
7618     * @param parent activity related to the error, null if unknown
7619     * @param subject line related to the error, null if absent
7620     * @param report in long form describing the error, null if absent
7621     * @param logFile to include in the report, null if none
7622     * @param crashInfo giving an application stack trace, null if absent
7623     */
7624    public void addErrorToDropBox(String eventType,
7625            ProcessRecord process, String processName, ActivityRecord activity,
7626            ActivityRecord parent, String subject,
7627            final String report, final File logFile,
7628            final ApplicationErrorReport.CrashInfo crashInfo) {
7629        // NOTE -- this must never acquire the ActivityManagerService lock,
7630        // otherwise the watchdog may be prevented from resetting the system.
7631
7632        final String dropboxTag = processClass(process) + "_" + eventType;
7633        final DropBoxManager dbox = (DropBoxManager)
7634                mContext.getSystemService(Context.DROPBOX_SERVICE);
7635
7636        // Exit early if the dropbox isn't configured to accept this report type.
7637        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7638
7639        final StringBuilder sb = new StringBuilder(1024);
7640        appendDropBoxProcessHeaders(process, processName, sb);
7641        if (activity != null) {
7642            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7643        }
7644        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7645            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7646        }
7647        if (parent != null && parent != activity) {
7648            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7649        }
7650        if (subject != null) {
7651            sb.append("Subject: ").append(subject).append("\n");
7652        }
7653        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7654        if (Debug.isDebuggerConnected()) {
7655            sb.append("Debugger: Connected\n");
7656        }
7657        sb.append("\n");
7658
7659        // Do the rest in a worker thread to avoid blocking the caller on I/O
7660        // (After this point, we shouldn't access AMS internal data structures.)
7661        Thread worker = new Thread("Error dump: " + dropboxTag) {
7662            @Override
7663            public void run() {
7664                if (report != null) {
7665                    sb.append(report);
7666                }
7667                if (logFile != null) {
7668                    try {
7669                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7670                    } catch (IOException e) {
7671                        Slog.e(TAG, "Error reading " + logFile, e);
7672                    }
7673                }
7674                if (crashInfo != null && crashInfo.stackTrace != null) {
7675                    sb.append(crashInfo.stackTrace);
7676                }
7677
7678                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7679                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7680                if (lines > 0) {
7681                    sb.append("\n");
7682
7683                    // Merge several logcat streams, and take the last N lines
7684                    InputStreamReader input = null;
7685                    try {
7686                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7687                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7688                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7689
7690                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
7691                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
7692                        input = new InputStreamReader(logcat.getInputStream());
7693
7694                        int num;
7695                        char[] buf = new char[8192];
7696                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7697                    } catch (IOException e) {
7698                        Slog.e(TAG, "Error running logcat", e);
7699                    } finally {
7700                        if (input != null) try { input.close(); } catch (IOException e) {}
7701                    }
7702                }
7703
7704                dbox.addText(dropboxTag, sb.toString());
7705            }
7706        };
7707
7708        if (process == null || process.pid == MY_PID) {
7709            worker.run();  // We may be about to die -- need to run this synchronously
7710        } else {
7711            worker.start();
7712        }
7713    }
7714
7715    /**
7716     * Bring up the "unexpected error" dialog box for a crashing app.
7717     * Deal with edge cases (intercepts from instrumented applications,
7718     * ActivityController, error intent receivers, that sort of thing).
7719     * @param r the application crashing
7720     * @param crashInfo describing the failure
7721     */
7722    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
7723        long timeMillis = System.currentTimeMillis();
7724        String shortMsg = crashInfo.exceptionClassName;
7725        String longMsg = crashInfo.exceptionMessage;
7726        String stackTrace = crashInfo.stackTrace;
7727        if (shortMsg != null && longMsg != null) {
7728            longMsg = shortMsg + ": " + longMsg;
7729        } else if (shortMsg != null) {
7730            longMsg = shortMsg;
7731        }
7732
7733        AppErrorResult result = new AppErrorResult();
7734        synchronized (this) {
7735            if (mController != null) {
7736                try {
7737                    String name = r != null ? r.processName : null;
7738                    int pid = r != null ? r.pid : Binder.getCallingPid();
7739                    if (!mController.appCrashed(name, pid,
7740                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
7741                        Slog.w(TAG, "Force-killing crashed app " + name
7742                                + " at watcher's request");
7743                        Process.killProcess(pid);
7744                        return;
7745                    }
7746                } catch (RemoteException e) {
7747                    mController = null;
7748                }
7749            }
7750
7751            final long origId = Binder.clearCallingIdentity();
7752
7753            // If this process is running instrumentation, finish it.
7754            if (r != null && r.instrumentationClass != null) {
7755                Slog.w(TAG, "Error in app " + r.processName
7756                      + " running instrumentation " + r.instrumentationClass + ":");
7757                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
7758                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
7759                Bundle info = new Bundle();
7760                info.putString("shortMsg", shortMsg);
7761                info.putString("longMsg", longMsg);
7762                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7763                Binder.restoreCallingIdentity(origId);
7764                return;
7765            }
7766
7767            // If we can't identify the process or it's already exceeded its crash quota,
7768            // quit right away without showing a crash dialog.
7769            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
7770                Binder.restoreCallingIdentity(origId);
7771                return;
7772            }
7773
7774            Message msg = Message.obtain();
7775            msg.what = SHOW_ERROR_MSG;
7776            HashMap data = new HashMap();
7777            data.put("result", result);
7778            data.put("app", r);
7779            msg.obj = data;
7780            mHandler.sendMessage(msg);
7781
7782            Binder.restoreCallingIdentity(origId);
7783        }
7784
7785        int res = result.get();
7786
7787        Intent appErrorIntent = null;
7788        synchronized (this) {
7789            if (r != null) {
7790                mProcessCrashTimes.put(r.info.processName, r.info.uid,
7791                        SystemClock.uptimeMillis());
7792            }
7793            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
7794                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
7795            }
7796        }
7797
7798        if (appErrorIntent != null) {
7799            try {
7800                mContext.startActivity(appErrorIntent);
7801            } catch (ActivityNotFoundException e) {
7802                Slog.w(TAG, "bug report receiver dissappeared", e);
7803            }
7804        }
7805    }
7806
7807    Intent createAppErrorIntentLocked(ProcessRecord r,
7808            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7809        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
7810        if (report == null) {
7811            return null;
7812        }
7813        Intent result = new Intent(Intent.ACTION_APP_ERROR);
7814        result.setComponent(r.errorReportReceiver);
7815        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7816        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7817        return result;
7818    }
7819
7820    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7821            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7822        if (r.errorReportReceiver == null) {
7823            return null;
7824        }
7825
7826        if (!r.crashing && !r.notResponding) {
7827            return null;
7828        }
7829
7830        ApplicationErrorReport report = new ApplicationErrorReport();
7831        report.packageName = r.info.packageName;
7832        report.installerPackageName = r.errorReportReceiver.getPackageName();
7833        report.processName = r.processName;
7834        report.time = timeMillis;
7835        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
7836
7837        if (r.crashing) {
7838            report.type = ApplicationErrorReport.TYPE_CRASH;
7839            report.crashInfo = crashInfo;
7840        } else if (r.notResponding) {
7841            report.type = ApplicationErrorReport.TYPE_ANR;
7842            report.anrInfo = new ApplicationErrorReport.AnrInfo();
7843
7844            report.anrInfo.activity = r.notRespondingReport.tag;
7845            report.anrInfo.cause = r.notRespondingReport.shortMsg;
7846            report.anrInfo.info = r.notRespondingReport.longMsg;
7847        }
7848
7849        return report;
7850    }
7851
7852    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7853        // assume our apps are happy - lazy create the list
7854        List<ActivityManager.ProcessErrorStateInfo> errList = null;
7855
7856        synchronized (this) {
7857
7858            // iterate across all processes
7859            for (int i=mLruProcesses.size()-1; i>=0; i--) {
7860                ProcessRecord app = mLruProcesses.get(i);
7861                if ((app.thread != null) && (app.crashing || app.notResponding)) {
7862                    // This one's in trouble, so we'll generate a report for it
7863                    // crashes are higher priority (in case there's a crash *and* an anr)
7864                    ActivityManager.ProcessErrorStateInfo report = null;
7865                    if (app.crashing) {
7866                        report = app.crashingReport;
7867                    } else if (app.notResponding) {
7868                        report = app.notRespondingReport;
7869                    }
7870
7871                    if (report != null) {
7872                        if (errList == null) {
7873                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7874                        }
7875                        errList.add(report);
7876                    } else {
7877                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
7878                                " crashing = " + app.crashing +
7879                                " notResponding = " + app.notResponding);
7880                    }
7881                }
7882            }
7883        }
7884
7885        return errList;
7886    }
7887
7888    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
7889        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
7890            if (currApp != null) {
7891                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7892            }
7893            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7894        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
7895            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7896        } else if (adj >= ProcessList.HOME_APP_ADJ) {
7897            if (currApp != null) {
7898                currApp.lru = 0;
7899            }
7900            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7901        } else if (adj >= ProcessList.SERVICE_ADJ) {
7902            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7903        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
7904            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7905        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
7906            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7907        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
7908            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7909        } else {
7910            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7911        }
7912    }
7913
7914    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7915        // Lazy instantiation of list
7916        List<ActivityManager.RunningAppProcessInfo> runList = null;
7917        synchronized (this) {
7918            // Iterate across all processes
7919            for (int i=mLruProcesses.size()-1; i>=0; i--) {
7920                ProcessRecord app = mLruProcesses.get(i);
7921                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7922                    // Generate process state info for running application
7923                    ActivityManager.RunningAppProcessInfo currApp =
7924                        new ActivityManager.RunningAppProcessInfo(app.processName,
7925                                app.pid, app.getPackageList());
7926                    currApp.uid = app.info.uid;
7927                    if (mHeavyWeightProcess == app) {
7928                        currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
7929                    }
7930                    if (app.persistent) {
7931                        currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7932                    }
7933                    int adj = app.curAdj;
7934                    currApp.importance = oomAdjToImportance(adj, currApp);
7935                    currApp.importanceReasonCode = app.adjTypeCode;
7936                    if (app.adjSource instanceof ProcessRecord) {
7937                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
7938                        currApp.importanceReasonImportance = oomAdjToImportance(
7939                                app.adjSourceOom, null);
7940                    } else if (app.adjSource instanceof ActivityRecord) {
7941                        ActivityRecord r = (ActivityRecord)app.adjSource;
7942                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7943                    }
7944                    if (app.adjTarget instanceof ComponentName) {
7945                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7946                    }
7947                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
7948                    //        + " lru=" + currApp.lru);
7949                    if (runList == null) {
7950                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7951                    }
7952                    runList.add(currApp);
7953                }
7954            }
7955        }
7956        return runList;
7957    }
7958
7959    public List<ApplicationInfo> getRunningExternalApplications() {
7960        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7961        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7962        if (runningApps != null && runningApps.size() > 0) {
7963            Set<String> extList = new HashSet<String>();
7964            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7965                if (app.pkgList != null) {
7966                    for (String pkg : app.pkgList) {
7967                        extList.add(pkg);
7968                    }
7969                }
7970            }
7971            IPackageManager pm = AppGlobals.getPackageManager();
7972            for (String pkg : extList) {
7973                try {
7974                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7975                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7976                        retList.add(info);
7977                    }
7978                } catch (RemoteException e) {
7979                }
7980            }
7981        }
7982        return retList;
7983    }
7984
7985    @Override
7986    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
7987        if (checkCallingPermission(android.Manifest.permission.DUMP)
7988                != PackageManager.PERMISSION_GRANTED) {
7989            pw.println("Permission Denial: can't dump ActivityManager from from pid="
7990                    + Binder.getCallingPid()
7991                    + ", uid=" + Binder.getCallingUid()
7992                    + " without permission "
7993                    + android.Manifest.permission.DUMP);
7994            return;
7995        }
7996
7997        boolean dumpAll = false;
7998        boolean dumpClient = false;
7999        String dumpPackage = null;
8000
8001        int opti = 0;
8002        while (opti < args.length) {
8003            String opt = args[opti];
8004            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8005                break;
8006            }
8007            opti++;
8008            if ("-a".equals(opt)) {
8009                dumpAll = true;
8010            } else if ("-c".equals(opt)) {
8011                dumpClient = true;
8012            } else if ("-h".equals(opt)) {
8013                pw.println("Activity manager dump options:");
8014                pw.println("  [-a] [-c] [-h] [cmd] ...");
8015                pw.println("  cmd may be one of:");
8016                pw.println("    a[ctivities]: activity stack state");
8017                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8018                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8019                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8020                pw.println("    o[om]: out of memory management");
8021                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8022                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8023                pw.println("    service [COMP_SPEC]: service client-side state");
8024                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8025                pw.println("    all: dump all activities");
8026                pw.println("    top: dump the top activity");
8027                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8028                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8029                pw.println("    a partial substring in a component name, a");
8030                pw.println("    hex object identifier.");
8031                pw.println("  -a: include all available server state.");
8032                pw.println("  -c: include client state.");
8033                return;
8034            } else {
8035                pw.println("Unknown argument: " + opt + "; use -h for help");
8036            }
8037        }
8038
8039        // Is the caller requesting to dump a particular piece of data?
8040        if (opti < args.length) {
8041            String cmd = args[opti];
8042            opti++;
8043            if ("activities".equals(cmd) || "a".equals(cmd)) {
8044                synchronized (this) {
8045                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8046                }
8047                return;
8048            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8049                String[] newArgs;
8050                String name;
8051                if (opti >= args.length) {
8052                    name = null;
8053                    newArgs = EMPTY_STRING_ARRAY;
8054                } else {
8055                    name = args[opti];
8056                    opti++;
8057                    newArgs = new String[args.length - opti];
8058                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8059                            args.length - opti);
8060                }
8061                synchronized (this) {
8062                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8063                }
8064                return;
8065            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8066                String[] newArgs;
8067                String name;
8068                if (opti >= args.length) {
8069                    name = null;
8070                    newArgs = EMPTY_STRING_ARRAY;
8071                } else {
8072                    name = args[opti];
8073                    opti++;
8074                    newArgs = new String[args.length - opti];
8075                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8076                            args.length - opti);
8077                }
8078                synchronized (this) {
8079                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8080                }
8081                return;
8082            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8083                String[] newArgs;
8084                String name;
8085                if (opti >= args.length) {
8086                    name = null;
8087                    newArgs = EMPTY_STRING_ARRAY;
8088                } else {
8089                    name = args[opti];
8090                    opti++;
8091                    newArgs = new String[args.length - opti];
8092                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8093                            args.length - opti);
8094                }
8095                synchronized (this) {
8096                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8097                }
8098                return;
8099            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8100                synchronized (this) {
8101                    dumpOomLocked(fd, pw, args, opti, true);
8102                }
8103                return;
8104            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8105                synchronized (this) {
8106                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8107                }
8108                return;
8109            } else if ("service".equals(cmd)) {
8110                String[] newArgs;
8111                String name;
8112                if (opti >= args.length) {
8113                    name = null;
8114                    newArgs = EMPTY_STRING_ARRAY;
8115                } else {
8116                    name = args[opti];
8117                    opti++;
8118                    newArgs = new String[args.length - opti];
8119                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8120                            args.length - opti);
8121                }
8122                if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8123                    pw.println("No services match: " + name);
8124                    pw.println("Use -h for help.");
8125                }
8126                return;
8127            } else if ("package".equals(cmd)) {
8128                String[] newArgs;
8129                if (opti >= args.length) {
8130                    pw.println("package: no package name specified");
8131                    pw.println("Use -h for help.");
8132                    return;
8133                } else {
8134                    dumpPackage = args[opti];
8135                    opti++;
8136                    newArgs = new String[args.length - opti];
8137                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8138                            args.length - opti);
8139                    args = newArgs;
8140                    opti = 0;
8141                }
8142            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8143                synchronized (this) {
8144                    dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8145                }
8146                return;
8147            } else {
8148                // Dumping a single activity?
8149                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8150                    pw.println("Bad activity command, or no activities match: " + cmd);
8151                    pw.println("Use -h for help.");
8152                }
8153                return;
8154            }
8155        }
8156
8157        // No piece of data specified, dump everything.
8158        synchronized (this) {
8159            boolean needSep;
8160            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8161            if (needSep) {
8162                pw.println(" ");
8163            }
8164            if (dumpAll) {
8165                pw.println("-------------------------------------------------------------------------------");
8166            }
8167            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8168            if (needSep) {
8169                pw.println(" ");
8170            }
8171            if (dumpAll) {
8172                pw.println("-------------------------------------------------------------------------------");
8173            }
8174            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8175            if (needSep) {
8176                pw.println(" ");
8177            }
8178            if (dumpAll) {
8179                pw.println("-------------------------------------------------------------------------------");
8180            }
8181            needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8182            if (needSep) {
8183                pw.println(" ");
8184            }
8185            if (dumpAll) {
8186                pw.println("-------------------------------------------------------------------------------");
8187            }
8188            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8189            if (needSep) {
8190                pw.println(" ");
8191            }
8192            if (dumpAll) {
8193                pw.println("-------------------------------------------------------------------------------");
8194            }
8195            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8196        }
8197    }
8198
8199    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8200            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8201        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8202        pw.println("  Main stack:");
8203        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8204                dumpPackage);
8205        pw.println(" ");
8206        pw.println("  Running activities (most recent first):");
8207        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8208                dumpPackage);
8209        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8210            pw.println(" ");
8211            pw.println("  Activities waiting for another to become visible:");
8212            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8213                    !dumpAll, false, dumpPackage);
8214        }
8215        if (mMainStack.mStoppingActivities.size() > 0) {
8216            pw.println(" ");
8217            pw.println("  Activities waiting to stop:");
8218            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8219                    !dumpAll, false, dumpPackage);
8220        }
8221        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8222            pw.println(" ");
8223            pw.println("  Activities waiting to sleep:");
8224            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8225                    !dumpAll, false, dumpPackage);
8226        }
8227        if (mMainStack.mFinishingActivities.size() > 0) {
8228            pw.println(" ");
8229            pw.println("  Activities waiting to finish:");
8230            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8231                    !dumpAll, false, dumpPackage);
8232        }
8233
8234        pw.println(" ");
8235        if (mMainStack.mPausingActivity != null) {
8236            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8237        }
8238        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8239        pw.println("  mFocusedActivity: " + mFocusedActivity);
8240        if (dumpAll) {
8241            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8242            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8243            pw.println("  mDismissKeyguardOnNextActivity: "
8244                    + mMainStack.mDismissKeyguardOnNextActivity);
8245        }
8246
8247        if (mRecentTasks.size() > 0) {
8248            pw.println();
8249            pw.println("  Recent tasks:");
8250
8251            final int N = mRecentTasks.size();
8252            for (int i=0; i<N; i++) {
8253                TaskRecord tr = mRecentTasks.get(i);
8254                if (dumpPackage != null) {
8255                    if (tr.realActivity == null ||
8256                            !dumpPackage.equals(tr.realActivity)) {
8257                        continue;
8258                    }
8259                }
8260                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8261                        pw.println(tr);
8262                if (dumpAll) {
8263                    mRecentTasks.get(i).dump(pw, "    ");
8264                }
8265            }
8266        }
8267
8268        if (dumpAll) {
8269            pw.println(" ");
8270            pw.println("  mCurTask: " + mCurTask);
8271        }
8272
8273        return true;
8274    }
8275
8276    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8277            int opti, boolean dumpAll, String dumpPackage) {
8278        boolean needSep = false;
8279        int numPers = 0;
8280
8281        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8282
8283        if (dumpAll) {
8284            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8285                final int NA = procs.size();
8286                for (int ia=0; ia<NA; ia++) {
8287                    ProcessRecord r = procs.valueAt(ia);
8288                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8289                        continue;
8290                    }
8291                    if (!needSep) {
8292                        pw.println("  All known processes:");
8293                        needSep = true;
8294                    }
8295                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8296                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8297                        pw.print(" "); pw.println(r);
8298                    r.dump(pw, "    ");
8299                    if (r.persistent) {
8300                        numPers++;
8301                    }
8302                }
8303            }
8304        }
8305
8306        if (mLruProcesses.size() > 0) {
8307            if (needSep) pw.println(" ");
8308            needSep = true;
8309            pw.println("  Process LRU list (sorted by oom_adj):");
8310            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8311                    "Proc", "PERS", false, dumpPackage);
8312            needSep = true;
8313        }
8314
8315        if (dumpAll) {
8316            synchronized (mPidsSelfLocked) {
8317                boolean printed = false;
8318                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8319                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8320                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8321                        continue;
8322                    }
8323                    if (!printed) {
8324                        if (needSep) pw.println(" ");
8325                        needSep = true;
8326                        pw.println("  PID mappings:");
8327                        printed = true;
8328                    }
8329                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8330                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8331                }
8332            }
8333        }
8334
8335        if (mForegroundProcesses.size() > 0) {
8336            synchronized (mPidsSelfLocked) {
8337                boolean printed = false;
8338                for (int i=0; i<mForegroundProcesses.size(); i++) {
8339                    ProcessRecord r = mPidsSelfLocked.get(
8340                            mForegroundProcesses.valueAt(i).pid);
8341                    if (dumpPackage != null && (r == null
8342                            || !dumpPackage.equals(r.info.packageName))) {
8343                        continue;
8344                    }
8345                    if (!printed) {
8346                        if (needSep) pw.println(" ");
8347                        needSep = true;
8348                        pw.println("  Foreground Processes:");
8349                        printed = true;
8350                    }
8351                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
8352                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8353                }
8354            }
8355        }
8356
8357        if (mPersistentStartingProcesses.size() > 0) {
8358            if (needSep) pw.println(" ");
8359            needSep = true;
8360            pw.println("  Persisent processes that are starting:");
8361            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
8362                    "Starting Norm", "Restarting PERS", dumpPackage);
8363        }
8364
8365        if (mRemovedProcesses.size() > 0) {
8366            if (needSep) pw.println(" ");
8367            needSep = true;
8368            pw.println("  Processes that are being removed:");
8369            dumpProcessList(pw, this, mRemovedProcesses, "    ",
8370                    "Removed Norm", "Removed PERS", dumpPackage);
8371        }
8372
8373        if (mProcessesOnHold.size() > 0) {
8374            if (needSep) pw.println(" ");
8375            needSep = true;
8376            pw.println("  Processes that are on old until the system is ready:");
8377            dumpProcessList(pw, this, mProcessesOnHold, "    ",
8378                    "OnHold Norm", "OnHold PERS", dumpPackage);
8379        }
8380
8381        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
8382
8383        if (mProcessCrashTimes.getMap().size() > 0) {
8384            boolean printed = false;
8385            long now = SystemClock.uptimeMillis();
8386            for (Map.Entry<String, SparseArray<Long>> procs
8387                    : mProcessCrashTimes.getMap().entrySet()) {
8388                String pname = procs.getKey();
8389                SparseArray<Long> uids = procs.getValue();
8390                final int N = uids.size();
8391                for (int i=0; i<N; i++) {
8392                    int puid = uids.keyAt(i);
8393                    ProcessRecord r = mProcessNames.get(pname, puid);
8394                    if (dumpPackage != null && (r == null
8395                            || !dumpPackage.equals(r.info.packageName))) {
8396                        continue;
8397                    }
8398                    if (!printed) {
8399                        if (needSep) pw.println(" ");
8400                        needSep = true;
8401                        pw.println("  Time since processes crashed:");
8402                        printed = true;
8403                    }
8404                    pw.print("    Process "); pw.print(pname);
8405                            pw.print(" uid "); pw.print(puid);
8406                            pw.print(": last crashed ");
8407                            pw.print((now-uids.valueAt(i)));
8408                            pw.println(" ms ago");
8409                }
8410            }
8411        }
8412
8413        if (mBadProcesses.getMap().size() > 0) {
8414            boolean printed = false;
8415            for (Map.Entry<String, SparseArray<Long>> procs
8416                    : mBadProcesses.getMap().entrySet()) {
8417                String pname = procs.getKey();
8418                SparseArray<Long> uids = procs.getValue();
8419                final int N = uids.size();
8420                for (int i=0; i<N; i++) {
8421                    int puid = uids.keyAt(i);
8422                    ProcessRecord r = mProcessNames.get(pname, puid);
8423                    if (dumpPackage != null && (r == null
8424                            || !dumpPackage.equals(r.info.packageName))) {
8425                        continue;
8426                    }
8427                    if (!printed) {
8428                        if (needSep) pw.println(" ");
8429                        needSep = true;
8430                        pw.println("  Bad processes:");
8431                    }
8432                    pw.print("    Bad process "); pw.print(pname);
8433                            pw.print(" uid "); pw.print(puid);
8434                            pw.print(": crashed at time ");
8435                            pw.println(uids.valueAt(i));
8436                }
8437            }
8438        }
8439
8440        pw.println();
8441        pw.println("  mHomeProcess: " + mHomeProcess);
8442        pw.println("  mPreviousProcess: " + mPreviousProcess);
8443        if (dumpAll) {
8444            StringBuilder sb = new StringBuilder(128);
8445            sb.append("  mPreviousProcessVisibleTime: ");
8446            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
8447            pw.println(sb);
8448        }
8449        if (mHeavyWeightProcess != null) {
8450            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
8451        }
8452        pw.println("  mConfiguration: " + mConfiguration);
8453        if (dumpAll) {
8454            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
8455            if (mCompatModePackages.getPackages().size() > 0) {
8456                boolean printed = false;
8457                for (Map.Entry<String, Integer> entry
8458                        : mCompatModePackages.getPackages().entrySet()) {
8459                    String pkg = entry.getKey();
8460                    int mode = entry.getValue();
8461                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
8462                        continue;
8463                    }
8464                    if (!printed) {
8465                        pw.println("  mScreenCompatPackages:");
8466                        printed = true;
8467                    }
8468                    pw.print("    "); pw.print(pkg); pw.print(": ");
8469                            pw.print(mode); pw.println();
8470                }
8471            }
8472        }
8473        pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8474        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8475                || mOrigWaitForDebugger) {
8476            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8477                    + " mDebugTransient=" + mDebugTransient
8478                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8479        }
8480        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8481                || mProfileFd != null) {
8482            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8483            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8484            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
8485                    + mAutoStopProfiler);
8486        }
8487        if (mAlwaysFinishActivities || mController != null) {
8488            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
8489                    + " mController=" + mController);
8490        }
8491        if (dumpAll) {
8492            pw.println("  Total persistent processes: " + numPers);
8493            pw.println("  mStartRunning=" + mStartRunning
8494                    + " mProcessesReady=" + mProcessesReady
8495                    + " mSystemReady=" + mSystemReady);
8496            pw.println("  mBooting=" + mBooting
8497                    + " mBooted=" + mBooted
8498                    + " mFactoryTest=" + mFactoryTest);
8499            pw.print("  mLastPowerCheckRealtime=");
8500                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8501                    pw.println("");
8502            pw.print("  mLastPowerCheckUptime=");
8503                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8504                    pw.println("");
8505            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
8506            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
8507            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
8508            pw.println("  mNumServiceProcs=" + mNumServiceProcs
8509                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
8510        }
8511
8512        return true;
8513    }
8514
8515    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8516            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
8517        if (mProcessesToGc.size() > 0) {
8518            boolean printed = false;
8519            long now = SystemClock.uptimeMillis();
8520            for (int i=0; i<mProcessesToGc.size(); i++) {
8521                ProcessRecord proc = mProcessesToGc.get(i);
8522                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
8523                    continue;
8524                }
8525                if (!printed) {
8526                    if (needSep) pw.println(" ");
8527                    needSep = true;
8528                    pw.println("  Processes that are waiting to GC:");
8529                    printed = true;
8530                }
8531                pw.print("    Process "); pw.println(proc);
8532                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
8533                        pw.print(", last gced=");
8534                        pw.print(now-proc.lastRequestedGc);
8535                        pw.print(" ms ago, last lowMem=");
8536                        pw.print(now-proc.lastLowMemory);
8537                        pw.println(" ms ago");
8538
8539            }
8540        }
8541        return needSep;
8542    }
8543
8544    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8545            int opti, boolean dumpAll) {
8546        boolean needSep = false;
8547
8548        if (mLruProcesses.size() > 0) {
8549            if (needSep) pw.println(" ");
8550            needSep = true;
8551            pw.println("  OOM levels:");
8552            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
8553            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
8554            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8555            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8556            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8557            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8558            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
8559            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
8560            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
8561            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
8562            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
8563            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
8564            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
8565
8566            if (needSep) pw.println(" ");
8567            needSep = true;
8568            pw.println("  Process OOM control:");
8569            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8570                    "Proc", "PERS", true, null);
8571            needSep = true;
8572        }
8573
8574        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
8575
8576        pw.println();
8577        pw.println("  mHomeProcess: " + mHomeProcess);
8578        pw.println("  mPreviousProcess: " + mPreviousProcess);
8579        if (mHeavyWeightProcess != null) {
8580            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
8581        }
8582
8583        return true;
8584    }
8585
8586    /**
8587     * There are three ways to call this:
8588     *  - no service specified: dump all the services
8589     *  - a flattened component name that matched an existing service was specified as the
8590     *    first arg: dump that one service
8591     *  - the first arg isn't the flattened component name of an existing service:
8592     *    dump all services whose component contains the first arg as a substring
8593     */
8594    protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8595            int opti, boolean dumpAll) {
8596        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
8597
8598        if ("all".equals(name)) {
8599            synchronized (this) {
8600                for (ServiceRecord r1 : mServices.values()) {
8601                    services.add(r1);
8602                }
8603            }
8604        } else {
8605            ComponentName componentName = name != null
8606                    ? ComponentName.unflattenFromString(name) : null;
8607            int objectId = 0;
8608            if (componentName == null) {
8609                // Not a '/' separated full component name; maybe an object ID?
8610                try {
8611                    objectId = Integer.parseInt(name, 16);
8612                    name = null;
8613                    componentName = null;
8614                } catch (RuntimeException e) {
8615                }
8616            }
8617
8618            synchronized (this) {
8619                for (ServiceRecord r1 : mServices.values()) {
8620                    if (componentName != null) {
8621                        if (r1.name.equals(componentName)) {
8622                            services.add(r1);
8623                        }
8624                    } else if (name != null) {
8625                        if (r1.name.flattenToString().contains(name)) {
8626                            services.add(r1);
8627                        }
8628                    } else if (System.identityHashCode(r1) == objectId) {
8629                        services.add(r1);
8630                    }
8631                }
8632            }
8633        }
8634
8635        if (services.size() <= 0) {
8636            return false;
8637        }
8638
8639        boolean needSep = false;
8640        for (int i=0; i<services.size(); i++) {
8641            if (needSep) {
8642                pw.println();
8643            }
8644            needSep = true;
8645            dumpService("", fd, pw, services.get(i), args, dumpAll);
8646        }
8647        return true;
8648    }
8649
8650    /**
8651     * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8652     * there is a thread associated with the service.
8653     */
8654    private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8655            final ServiceRecord r, String[] args, boolean dumpAll) {
8656        String innerPrefix = prefix + "  ";
8657        synchronized (this) {
8658            pw.print(prefix); pw.print("SERVICE ");
8659                    pw.print(r.shortName); pw.print(" ");
8660                    pw.print(Integer.toHexString(System.identityHashCode(r)));
8661                    pw.print(" pid=");
8662                    if (r.app != null) pw.println(r.app.pid);
8663                    else pw.println("(not running)");
8664            if (dumpAll) {
8665                r.dump(pw, innerPrefix);
8666            }
8667        }
8668        if (r.app != null && r.app.thread != null) {
8669            pw.print(prefix); pw.println("  Client:");
8670            pw.flush();
8671            try {
8672                TransferPipe tp = new TransferPipe();
8673                try {
8674                    r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8675                    tp.setBufferPrefix(prefix + "    ");
8676                    tp.go(fd);
8677                } finally {
8678                    tp.kill();
8679                }
8680            } catch (IOException e) {
8681                pw.println(prefix + "    Failure while dumping the service: " + e);
8682            } catch (RemoteException e) {
8683                pw.println(prefix + "    Got a RemoteException while dumping the service");
8684            }
8685        }
8686    }
8687
8688    static class ItemMatcher {
8689        ArrayList<ComponentName> components;
8690        ArrayList<String> strings;
8691        ArrayList<Integer> objects;
8692        boolean all;
8693
8694        ItemMatcher() {
8695            all = true;
8696        }
8697
8698        void build(String name) {
8699            ComponentName componentName = ComponentName.unflattenFromString(name);
8700            if (componentName != null) {
8701                if (components == null) {
8702                    components = new ArrayList<ComponentName>();
8703                }
8704                components.add(componentName);
8705                all = false;
8706            } else {
8707                int objectId = 0;
8708                // Not a '/' separated full component name; maybe an object ID?
8709                try {
8710                    objectId = Integer.parseInt(name, 16);
8711                    if (objects == null) {
8712                        objects = new ArrayList<Integer>();
8713                    }
8714                    objects.add(objectId);
8715                    all = false;
8716                } catch (RuntimeException e) {
8717                    // Not an integer; just do string match.
8718                    if (strings == null) {
8719                        strings = new ArrayList<String>();
8720                    }
8721                    strings.add(name);
8722                    all = false;
8723                }
8724            }
8725        }
8726
8727        int build(String[] args, int opti) {
8728            for (; opti<args.length; opti++) {
8729                String name = args[opti];
8730                if ("--".equals(name)) {
8731                    return opti+1;
8732                }
8733                build(name);
8734            }
8735            return opti;
8736        }
8737
8738        boolean match(Object object, ComponentName comp) {
8739            if (all) {
8740                return true;
8741            }
8742            if (components != null) {
8743                for (int i=0; i<components.size(); i++) {
8744                    if (components.get(i).equals(comp)) {
8745                        return true;
8746                    }
8747                }
8748            }
8749            if (objects != null) {
8750                for (int i=0; i<objects.size(); i++) {
8751                    if (System.identityHashCode(object) == objects.get(i)) {
8752                        return true;
8753                    }
8754                }
8755            }
8756            if (strings != null) {
8757                String flat = comp.flattenToString();
8758                for (int i=0; i<strings.size(); i++) {
8759                    if (flat.contains(strings.get(i))) {
8760                        return true;
8761                    }
8762                }
8763            }
8764            return false;
8765        }
8766    }
8767
8768    /**
8769     * There are three things that cmd can be:
8770     *  - a flattened component name that matches an existing activity
8771     *  - the cmd arg isn't the flattened component name of an existing activity:
8772     *    dump all activity whose component contains the cmd as a substring
8773     *  - A hex number of the ActivityRecord object instance.
8774     */
8775    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8776            int opti, boolean dumpAll) {
8777        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
8778
8779        if ("all".equals(name)) {
8780            synchronized (this) {
8781                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8782                    activities.add(r1);
8783                }
8784            }
8785        } else if ("top".equals(name)) {
8786            synchronized (this) {
8787                final int N = mMainStack.mHistory.size();
8788                if (N > 0) {
8789                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8790                }
8791            }
8792        } else {
8793            ItemMatcher matcher = new ItemMatcher();
8794            matcher.build(name);
8795
8796            synchronized (this) {
8797                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8798                    if (matcher.match(r1, r1.intent.getComponent())) {
8799                        activities.add(r1);
8800                    }
8801                }
8802            }
8803        }
8804
8805        if (activities.size() <= 0) {
8806            return false;
8807        }
8808
8809        String[] newArgs = new String[args.length - opti];
8810        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8811
8812        TaskRecord lastTask = null;
8813        boolean needSep = false;
8814        for (int i=activities.size()-1; i>=0; i--) {
8815            ActivityRecord r = (ActivityRecord)activities.get(i);
8816            if (needSep) {
8817                pw.println();
8818            }
8819            needSep = true;
8820            synchronized (this) {
8821                if (lastTask != r.task) {
8822                    lastTask = r.task;
8823                    pw.print("TASK "); pw.print(lastTask.affinity);
8824                            pw.print(" id="); pw.println(lastTask.taskId);
8825                    if (dumpAll) {
8826                        lastTask.dump(pw, "  ");
8827                    }
8828                }
8829            }
8830            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
8831        }
8832        return true;
8833    }
8834
8835    /**
8836     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8837     * there is a thread associated with the activity.
8838     */
8839    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
8840            final ActivityRecord r, String[] args, boolean dumpAll) {
8841        String innerPrefix = prefix + "  ";
8842        synchronized (this) {
8843            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8844                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8845                    pw.print(" pid=");
8846                    if (r.app != null) pw.println(r.app.pid);
8847                    else pw.println("(not running)");
8848            if (dumpAll) {
8849                r.dump(pw, innerPrefix);
8850            }
8851        }
8852        if (r.app != null && r.app.thread != null) {
8853            // flush anything that is already in the PrintWriter since the thread is going
8854            // to write to the file descriptor directly
8855            pw.flush();
8856            try {
8857                TransferPipe tp = new TransferPipe();
8858                try {
8859                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
8860                            r.appToken, innerPrefix, args);
8861                    tp.go(fd);
8862                } finally {
8863                    tp.kill();
8864                }
8865            } catch (IOException e) {
8866                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8867            } catch (RemoteException e) {
8868                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8869            }
8870        }
8871    }
8872
8873    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8874            int opti, boolean dumpAll, String dumpPackage) {
8875        boolean needSep = false;
8876
8877        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
8878        if (dumpAll) {
8879            if (mRegisteredReceivers.size() > 0) {
8880                boolean printed = false;
8881                Iterator it = mRegisteredReceivers.values().iterator();
8882                while (it.hasNext()) {
8883                    ReceiverList r = (ReceiverList)it.next();
8884                    if (dumpPackage != null && (r.app == null ||
8885                            !dumpPackage.equals(r.app.info.packageName))) {
8886                        continue;
8887                    }
8888                    if (!printed) {
8889                        pw.println("  Registered Receivers:");
8890                        needSep = true;
8891                        printed = true;
8892                    }
8893                    pw.print("  * "); pw.println(r);
8894                    r.dump(pw, "    ");
8895                }
8896            }
8897
8898            if (mReceiverResolver.dump(pw, needSep ?
8899                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
8900                    "    ", dumpPackage, false)) {
8901                needSep = true;
8902            }
8903        }
8904
8905        if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8906                || mPendingBroadcast != null) {
8907            boolean printed = false;
8908            for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8909                BroadcastRecord br = mParallelBroadcasts.get(i);
8910                if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
8911                    continue;
8912                }
8913                if (!printed) {
8914                    if (needSep) {
8915                        pw.println();
8916                    }
8917                    needSep = true;
8918                    pw.println("  Active broadcasts:");
8919                }
8920                pw.println("  Broadcast #" + i + ":");
8921                br.dump(pw, "    ");
8922            }
8923            printed = false;
8924            for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8925                BroadcastRecord br = mOrderedBroadcasts.get(i);
8926                if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
8927                    continue;
8928                }
8929                if (!printed) {
8930                    if (needSep) {
8931                        pw.println();
8932                    }
8933                    needSep = true;
8934                    pw.println("  Active ordered broadcasts:");
8935                }
8936                pw.println("  Ordered Broadcast #" + i + ":");
8937                mOrderedBroadcasts.get(i).dump(pw, "    ");
8938            }
8939            if (dumpPackage == null || (mPendingBroadcast != null
8940                    && dumpPackage.equals(mPendingBroadcast.callerPackage))) {
8941                if (needSep) {
8942                    pw.println();
8943                }
8944                pw.println("  Pending broadcast:");
8945                if (mPendingBroadcast != null) {
8946                    mPendingBroadcast.dump(pw, "    ");
8947                } else {
8948                    pw.println("    (null)");
8949                }
8950                needSep = true;
8951            }
8952        }
8953
8954        boolean printed = false;
8955        for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8956            BroadcastRecord r = mBroadcastHistory[i];
8957            if (r == null) {
8958                break;
8959            }
8960            if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) {
8961                continue;
8962            }
8963            if (!printed) {
8964                if (needSep) {
8965                    pw.println();
8966                }
8967                needSep = true;
8968                pw.println("  Historical broadcasts:");
8969                printed = true;
8970            }
8971            if (dumpAll) {
8972                pw.print("  Historical Broadcast #"); pw.print(i); pw.println(":");
8973                r.dump(pw, "    ");
8974            } else {
8975                if (i >= 50) {
8976                    pw.println("  ...");
8977                    break;
8978                }
8979                pw.print("  #"); pw.print(i); pw.print(": "); pw.println(r);
8980            }
8981        }
8982        needSep = true;
8983
8984        if (mStickyBroadcasts != null && dumpPackage == null) {
8985            if (needSep) {
8986                pw.println();
8987            }
8988            needSep = true;
8989            pw.println("  Sticky broadcasts:");
8990            StringBuilder sb = new StringBuilder(128);
8991            for (Map.Entry<String, ArrayList<Intent>> ent
8992                    : mStickyBroadcasts.entrySet()) {
8993                pw.print("  * Sticky action "); pw.print(ent.getKey());
8994                if (dumpAll) {
8995                    pw.println(":");
8996                    ArrayList<Intent> intents = ent.getValue();
8997                    final int N = intents.size();
8998                    for (int i=0; i<N; i++) {
8999                        sb.setLength(0);
9000                        sb.append("    Intent: ");
9001                        intents.get(i).toShortString(sb, false, true, false);
9002                        pw.println(sb.toString());
9003                        Bundle bundle = intents.get(i).getExtras();
9004                        if (bundle != null) {
9005                            pw.print("      ");
9006                            pw.println(bundle.toString());
9007                        }
9008                    }
9009                } else {
9010                    pw.println("");
9011                }
9012            }
9013            needSep = true;
9014        }
9015
9016        if (dumpAll) {
9017            pw.println();
9018            pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
9019            pw.println("  mHandler:");
9020            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9021            needSep = true;
9022        }
9023
9024        return needSep;
9025    }
9026
9027    boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9028            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9029        boolean needSep = false;
9030
9031        ItemMatcher matcher = new ItemMatcher();
9032        matcher.build(args, opti);
9033
9034        pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
9035        if (mServices.size() > 0) {
9036            boolean printed = false;
9037            long nowReal = SystemClock.elapsedRealtime();
9038            Iterator<ServiceRecord> it = mServices.values().iterator();
9039            needSep = false;
9040            while (it.hasNext()) {
9041                ServiceRecord r = it.next();
9042                if (!matcher.match(r, r.name)) {
9043                    continue;
9044                }
9045                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9046                    continue;
9047                }
9048                if (!printed) {
9049                    pw.println("  Active services:");
9050                    printed = true;
9051                }
9052                if (needSep) {
9053                    pw.println();
9054                }
9055                pw.print("  * "); pw.println(r);
9056                if (dumpAll) {
9057                    r.dump(pw, "    ");
9058                    needSep = true;
9059                } else {
9060                    pw.print("    app="); pw.println(r.app);
9061                    pw.print("    created=");
9062                        TimeUtils.formatDuration(r.createTime, nowReal, pw);
9063                        pw.print(" started="); pw.print(r.startRequested);
9064                        pw.print(" connections="); pw.println(r.connections.size());
9065                    if (r.connections.size() > 0) {
9066                        pw.println("    Connections:");
9067                        for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
9068                            for (int i=0; i<clist.size(); i++) {
9069                                ConnectionRecord conn = clist.get(i);
9070                                pw.print("      ");
9071                                pw.print(conn.binding.intent.intent.getIntent().toShortString(
9072                                        false, false, false));
9073                                pw.print(" -> ");
9074                                ProcessRecord proc = conn.binding.client;
9075                                pw.println(proc != null ? proc.toShortString() : "null");
9076                            }
9077                        }
9078                    }
9079                }
9080                if (dumpClient && r.app != null && r.app.thread != null) {
9081                    pw.println("    Client:");
9082                    pw.flush();
9083                    try {
9084                        TransferPipe tp = new TransferPipe();
9085                        try {
9086                            r.app.thread.dumpService(
9087                                    tp.getWriteFd().getFileDescriptor(), r, args);
9088                            tp.setBufferPrefix("      ");
9089                            // Short timeout, since blocking here can
9090                            // deadlock with the application.
9091                            tp.go(fd, 2000);
9092                        } finally {
9093                            tp.kill();
9094                        }
9095                    } catch (IOException e) {
9096                        pw.println("      Failure while dumping the service: " + e);
9097                    } catch (RemoteException e) {
9098                        pw.println("      Got a RemoteException while dumping the service");
9099                    }
9100                    needSep = true;
9101                }
9102            }
9103            needSep = printed;
9104        }
9105
9106        if (mPendingServices.size() > 0) {
9107            boolean printed = false;
9108            for (int i=0; i<mPendingServices.size(); i++) {
9109                ServiceRecord r = mPendingServices.get(i);
9110                if (!matcher.match(r, r.name)) {
9111                    continue;
9112                }
9113                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9114                    continue;
9115                }
9116                if (!printed) {
9117                    if (needSep) pw.println(" ");
9118                    needSep = true;
9119                    pw.println("  Pending services:");
9120                    printed = true;
9121                }
9122                pw.print("  * Pending "); pw.println(r);
9123                r.dump(pw, "    ");
9124            }
9125            needSep = true;
9126        }
9127
9128        if (mRestartingServices.size() > 0) {
9129            boolean printed = false;
9130            for (int i=0; i<mRestartingServices.size(); i++) {
9131                ServiceRecord r = mRestartingServices.get(i);
9132                if (!matcher.match(r, r.name)) {
9133                    continue;
9134                }
9135                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9136                    continue;
9137                }
9138                if (!printed) {
9139                    if (needSep) pw.println(" ");
9140                    needSep = true;
9141                    pw.println("  Restarting services:");
9142                    printed = true;
9143                }
9144                pw.print("  * Restarting "); pw.println(r);
9145                r.dump(pw, "    ");
9146            }
9147            needSep = true;
9148        }
9149
9150        if (mStoppingServices.size() > 0) {
9151            boolean printed = false;
9152            for (int i=0; i<mStoppingServices.size(); i++) {
9153                ServiceRecord r = mStoppingServices.get(i);
9154                if (!matcher.match(r, r.name)) {
9155                    continue;
9156                }
9157                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9158                    continue;
9159                }
9160                if (!printed) {
9161                    if (needSep) pw.println(" ");
9162                    needSep = true;
9163                    pw.println("  Stopping services:");
9164                    printed = true;
9165                }
9166                pw.print("  * Stopping "); pw.println(r);
9167                r.dump(pw, "    ");
9168            }
9169            needSep = true;
9170        }
9171
9172        if (dumpAll) {
9173            if (mServiceConnections.size() > 0) {
9174                boolean printed = false;
9175                Iterator<ArrayList<ConnectionRecord>> it
9176                        = mServiceConnections.values().iterator();
9177                while (it.hasNext()) {
9178                    ArrayList<ConnectionRecord> r = it.next();
9179                    for (int i=0; i<r.size(); i++) {
9180                        ConnectionRecord cr = r.get(i);
9181                        if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
9182                            continue;
9183                        }
9184                        if (dumpPackage != null && (cr.binding.client == null
9185                                || !dumpPackage.equals(cr.binding.client.info.packageName))) {
9186                            continue;
9187                        }
9188                        if (!printed) {
9189                            if (needSep) pw.println(" ");
9190                            needSep = true;
9191                            pw.println("  Connection bindings to services:");
9192                            printed = true;
9193                        }
9194                        pw.print("  * "); pw.println(cr);
9195                        cr.dump(pw, "    ");
9196                    }
9197                }
9198                needSep = true;
9199            }
9200        }
9201
9202        return needSep;
9203    }
9204
9205    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9206            int opti, boolean dumpAll, String dumpPackage) {
9207        boolean needSep = false;
9208
9209        ItemMatcher matcher = new ItemMatcher();
9210        matcher.build(args, opti);
9211
9212        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9213        if (mProvidersByClass.size() > 0) {
9214            boolean printed = false;
9215            Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
9216                    = mProvidersByClass.entrySet().iterator();
9217            while (it.hasNext()) {
9218                Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
9219                ContentProviderRecord r = e.getValue();
9220                ComponentName comp = e.getKey();
9221                String cls = comp.getClassName();
9222                int end = cls.lastIndexOf('.');
9223                if (end > 0 && end < (cls.length()-2)) {
9224                    cls = cls.substring(end+1);
9225                }
9226                if (!matcher.match(r, comp)) {
9227                    continue;
9228                }
9229                if (dumpPackage != null && !dumpPackage.equals(comp.getPackageName())) {
9230                    continue;
9231                }
9232                if (!printed) {
9233                    if (needSep) pw.println(" ");
9234                    needSep = true;
9235                    pw.println("  Published content providers (by class):");
9236                    printed = true;
9237                }
9238                pw.print("  * "); pw.print(cls); pw.print(" (");
9239                        pw.print(comp.flattenToShortString()); pw.println(")");
9240                if (dumpAll) {
9241                    r.dump(pw, "      ");
9242                } else {
9243                    if (r.proc != null) {
9244                        pw.print("      "); pw.println(r.proc);
9245                    } else {
9246                        pw.println();
9247                    }
9248                    if (r.clients.size() > 0) {
9249                        pw.println("      Clients:");
9250                        for (ProcessRecord cproc : r.clients) {
9251                            pw.print("        - "); pw.println(cproc);
9252                        }
9253                    }
9254                }
9255            }
9256        }
9257
9258        if (dumpAll) {
9259            if (mProvidersByName.size() > 0) {
9260                boolean printed = false;
9261                Iterator<Map.Entry<String, ContentProviderRecord>> it
9262                        = mProvidersByName.entrySet().iterator();
9263                while (it.hasNext()) {
9264                    Map.Entry<String, ContentProviderRecord> e = it.next();
9265                    ContentProviderRecord r = e.getValue();
9266                    if (!matcher.match(r, r.name)) {
9267                        continue;
9268                    }
9269                    if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9270                        continue;
9271                    }
9272                    if (!printed) {
9273                        if (needSep) pw.println(" ");
9274                        needSep = true;
9275                        pw.println("  Authority to provider mappings:");
9276                        printed = true;
9277                    }
9278                    pw.print("  "); pw.print(e.getKey()); pw.println(":");
9279                    pw.print("    "); pw.println(r);
9280                }
9281            }
9282        }
9283
9284        if (mLaunchingProviders.size() > 0) {
9285            boolean printed = false;
9286            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9287                ContentProviderRecord r = mLaunchingProviders.get(i);
9288                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9289                    continue;
9290                }
9291                if (!printed) {
9292                    if (needSep) pw.println(" ");
9293                    needSep = true;
9294                    pw.println("  Launching content providers:");
9295                    printed = true;
9296                }
9297                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9298                        pw.println(r);
9299            }
9300        }
9301
9302        if (mGrantedUriPermissions.size() > 0) {
9303            if (needSep) pw.println();
9304            needSep = true;
9305            pw.println("Granted Uri Permissions:");
9306            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9307                int uid = mGrantedUriPermissions.keyAt(i);
9308                HashMap<Uri, UriPermission> perms
9309                        = mGrantedUriPermissions.valueAt(i);
9310                pw.print("  * UID "); pw.print(uid);
9311                        pw.println(" holds:");
9312                for (UriPermission perm : perms.values()) {
9313                    pw.print("    "); pw.println(perm);
9314                    if (dumpAll) {
9315                        perm.dump(pw, "      ");
9316                    }
9317                }
9318            }
9319            needSep = true;
9320        }
9321
9322        return needSep;
9323    }
9324
9325    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9326            int opti, boolean dumpAll, String dumpPackage) {
9327        boolean needSep = false;
9328
9329        if (mIntentSenderRecords.size() > 0) {
9330            boolean printed = false;
9331            Iterator<WeakReference<PendingIntentRecord>> it
9332                    = mIntentSenderRecords.values().iterator();
9333            while (it.hasNext()) {
9334                WeakReference<PendingIntentRecord> ref = it.next();
9335                PendingIntentRecord rec = ref != null ? ref.get(): null;
9336                if (dumpPackage != null && (rec == null
9337                        || !dumpPackage.equals(rec.key.packageName))) {
9338                    continue;
9339                }
9340                if (!printed) {
9341                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9342                    printed = true;
9343                }
9344                needSep = true;
9345                if (rec != null) {
9346                    pw.print("  * "); pw.println(rec);
9347                    if (dumpAll) {
9348                        rec.dump(pw, "    ");
9349                    }
9350                } else {
9351                    pw.print("  * "); pw.println(ref);
9352                }
9353            }
9354        }
9355
9356        return needSep;
9357    }
9358
9359    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9360            String prefix, String label, boolean complete, boolean brief, boolean client,
9361            String dumpPackage) {
9362        TaskRecord lastTask = null;
9363        boolean needNL = false;
9364        final String innerPrefix = prefix + "      ";
9365        final String[] args = new String[0];
9366        for (int i=list.size()-1; i>=0; i--) {
9367            final ActivityRecord r = (ActivityRecord)list.get(i);
9368            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9369                continue;
9370            }
9371            final boolean full = !brief && (complete || !r.isInHistory());
9372            if (needNL) {
9373                pw.println(" ");
9374                needNL = false;
9375            }
9376            if (lastTask != r.task) {
9377                lastTask = r.task;
9378                pw.print(prefix);
9379                pw.print(full ? "* " : "  ");
9380                pw.println(lastTask);
9381                if (full) {
9382                    lastTask.dump(pw, prefix + "  ");
9383                } else if (complete) {
9384                    // Complete + brief == give a summary.  Isn't that obvious?!?
9385                    if (lastTask.intent != null) {
9386                        pw.print(prefix); pw.print("  ");
9387                                pw.println(lastTask.intent.toInsecureString());
9388                    }
9389                }
9390            }
9391            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9392            pw.print(" #"); pw.print(i); pw.print(": ");
9393            pw.println(r);
9394            if (full) {
9395                r.dump(pw, innerPrefix);
9396            } else if (complete) {
9397                // Complete + brief == give a summary.  Isn't that obvious?!?
9398                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9399                if (r.app != null) {
9400                    pw.print(innerPrefix); pw.println(r.app);
9401                }
9402            }
9403            if (client && r.app != null && r.app.thread != null) {
9404                // flush anything that is already in the PrintWriter since the thread is going
9405                // to write to the file descriptor directly
9406                pw.flush();
9407                try {
9408                    TransferPipe tp = new TransferPipe();
9409                    try {
9410                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9411                                r.appToken, innerPrefix, args);
9412                        // Short timeout, since blocking here can
9413                        // deadlock with the application.
9414                        tp.go(fd, 2000);
9415                    } finally {
9416                        tp.kill();
9417                    }
9418                } catch (IOException e) {
9419                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9420                } catch (RemoteException e) {
9421                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9422                }
9423                needNL = true;
9424            }
9425        }
9426    }
9427
9428    private static String buildOomTag(String prefix, String space, int val, int base) {
9429        if (val == base) {
9430            if (space == null) return prefix;
9431            return prefix + "  ";
9432        }
9433        return prefix + "+" + Integer.toString(val-base);
9434    }
9435
9436    private static final int dumpProcessList(PrintWriter pw,
9437            ActivityManagerService service, List list,
9438            String prefix, String normalLabel, String persistentLabel,
9439            String dumpPackage) {
9440        int numPers = 0;
9441        final int N = list.size()-1;
9442        for (int i=N; i>=0; i--) {
9443            ProcessRecord r = (ProcessRecord)list.get(i);
9444            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9445                continue;
9446            }
9447            pw.println(String.format("%s%s #%2d: %s",
9448                    prefix, (r.persistent ? persistentLabel : normalLabel),
9449                    i, r.toString()));
9450            if (r.persistent) {
9451                numPers++;
9452            }
9453        }
9454        return numPers;
9455    }
9456
9457    private static final boolean dumpProcessOomList(PrintWriter pw,
9458            ActivityManagerService service, List<ProcessRecord> origList,
9459            String prefix, String normalLabel, String persistentLabel,
9460            boolean inclDetails, String dumpPackage) {
9461
9462        ArrayList<Pair<ProcessRecord, Integer>> list
9463                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9464        for (int i=0; i<origList.size(); i++) {
9465            ProcessRecord r = origList.get(i);
9466            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9467                continue;
9468            }
9469            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9470        }
9471
9472        if (list.size() <= 0) {
9473            return false;
9474        }
9475
9476        Comparator<Pair<ProcessRecord, Integer>> comparator
9477                = new Comparator<Pair<ProcessRecord, Integer>>() {
9478            @Override
9479            public int compare(Pair<ProcessRecord, Integer> object1,
9480                    Pair<ProcessRecord, Integer> object2) {
9481                if (object1.first.setAdj != object2.first.setAdj) {
9482                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9483                }
9484                if (object1.second.intValue() != object2.second.intValue()) {
9485                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9486                }
9487                return 0;
9488            }
9489        };
9490
9491        Collections.sort(list, comparator);
9492
9493        final long curRealtime = SystemClock.elapsedRealtime();
9494        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9495        final long curUptime = SystemClock.uptimeMillis();
9496        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9497
9498        for (int i=list.size()-1; i>=0; i--) {
9499            ProcessRecord r = list.get(i).first;
9500            String oomAdj;
9501            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9502                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9503            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9504                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9505            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9506                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9507            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9508                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9509            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9510                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9511            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9512                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9513            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9514                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9515            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9516                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9517            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9518                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9519            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9520                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9521            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9522                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9523            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9524                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9525            } else {
9526                oomAdj = Integer.toString(r.setAdj);
9527            }
9528            String schedGroup;
9529            switch (r.setSchedGroup) {
9530                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9531                    schedGroup = "B";
9532                    break;
9533                case Process.THREAD_GROUP_DEFAULT:
9534                    schedGroup = "F";
9535                    break;
9536                default:
9537                    schedGroup = Integer.toString(r.setSchedGroup);
9538                    break;
9539            }
9540            String foreground;
9541            if (r.foregroundActivities) {
9542                foreground = "A";
9543            } else if (r.foregroundServices) {
9544                foreground = "S";
9545            } else {
9546                foreground = " ";
9547            }
9548            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9549                    prefix, (r.persistent ? persistentLabel : normalLabel),
9550                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9551                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9552            if (r.adjSource != null || r.adjTarget != null) {
9553                pw.print(prefix);
9554                pw.print("    ");
9555                if (r.adjTarget instanceof ComponentName) {
9556                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9557                } else if (r.adjTarget != null) {
9558                    pw.print(r.adjTarget.toString());
9559                } else {
9560                    pw.print("{null}");
9561                }
9562                pw.print("<=");
9563                if (r.adjSource instanceof ProcessRecord) {
9564                    pw.print("Proc{");
9565                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9566                    pw.println("}");
9567                } else if (r.adjSource != null) {
9568                    pw.println(r.adjSource.toString());
9569                } else {
9570                    pw.println("{null}");
9571                }
9572            }
9573            if (inclDetails) {
9574                pw.print(prefix);
9575                pw.print("    ");
9576                pw.print("oom: max="); pw.print(r.maxAdj);
9577                pw.print(" hidden="); pw.print(r.hiddenAdj);
9578                pw.print(" curRaw="); pw.print(r.curRawAdj);
9579                pw.print(" setRaw="); pw.print(r.setRawAdj);
9580                pw.print(" cur="); pw.print(r.curAdj);
9581                pw.print(" set="); pw.println(r.setAdj);
9582                pw.print(prefix);
9583                pw.print("    ");
9584                pw.print("keeping="); pw.print(r.keeping);
9585                pw.print(" hidden="); pw.print(r.hidden);
9586                pw.print(" empty="); pw.print(r.empty);
9587                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9588
9589                if (!r.keeping) {
9590                    if (r.lastWakeTime != 0) {
9591                        long wtime;
9592                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9593                        synchronized (stats) {
9594                            wtime = stats.getProcessWakeTime(r.info.uid,
9595                                    r.pid, curRealtime);
9596                        }
9597                        long timeUsed = wtime - r.lastWakeTime;
9598                        pw.print(prefix);
9599                        pw.print("    ");
9600                        pw.print("keep awake over ");
9601                        TimeUtils.formatDuration(realtimeSince, pw);
9602                        pw.print(" used ");
9603                        TimeUtils.formatDuration(timeUsed, pw);
9604                        pw.print(" (");
9605                        pw.print((timeUsed*100)/realtimeSince);
9606                        pw.println("%)");
9607                    }
9608                    if (r.lastCpuTime != 0) {
9609                        long timeUsed = r.curCpuTime - r.lastCpuTime;
9610                        pw.print(prefix);
9611                        pw.print("    ");
9612                        pw.print("run cpu over ");
9613                        TimeUtils.formatDuration(uptimeSince, pw);
9614                        pw.print(" used ");
9615                        TimeUtils.formatDuration(timeUsed, pw);
9616                        pw.print(" (");
9617                        pw.print((timeUsed*100)/uptimeSince);
9618                        pw.println("%)");
9619                    }
9620                }
9621            }
9622        }
9623        return true;
9624    }
9625
9626    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
9627        ArrayList<ProcessRecord> procs;
9628        synchronized (this) {
9629            if (args != null && args.length > start
9630                    && args[start].charAt(0) != '-') {
9631                procs = new ArrayList<ProcessRecord>();
9632                int pid = -1;
9633                try {
9634                    pid = Integer.parseInt(args[start]);
9635                } catch (NumberFormatException e) {
9636
9637                }
9638                for (int i=mLruProcesses.size()-1; i>=0; i--) {
9639                    ProcessRecord proc = mLruProcesses.get(i);
9640                    if (proc.pid == pid) {
9641                        procs.add(proc);
9642                    } else if (proc.processName.equals(args[start])) {
9643                        procs.add(proc);
9644                    }
9645                }
9646                if (procs.size() <= 0) {
9647                    pw.println("No process found for: " + args[start]);
9648                    return null;
9649                }
9650            } else {
9651                procs = new ArrayList<ProcessRecord>(mLruProcesses);
9652            }
9653        }
9654        return procs;
9655    }
9656
9657    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9658            PrintWriter pw, String[] args) {
9659        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9660        if (procs == null) {
9661            return;
9662        }
9663
9664        long uptime = SystemClock.uptimeMillis();
9665        long realtime = SystemClock.elapsedRealtime();
9666        pw.println("Applications Graphics Acceleration Info:");
9667        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9668
9669        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9670            ProcessRecord r = procs.get(i);
9671            if (r.thread != null) {
9672                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9673                pw.flush();
9674                try {
9675                    TransferPipe tp = new TransferPipe();
9676                    try {
9677                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9678                        tp.go(fd);
9679                    } finally {
9680                        tp.kill();
9681                    }
9682                } catch (IOException e) {
9683                    pw.println("Failure while dumping the app: " + r);
9684                    pw.flush();
9685                } catch (RemoteException e) {
9686                    pw.println("Got a RemoteException while dumping the app " + r);
9687                    pw.flush();
9688                }
9689            }
9690        }
9691    }
9692
9693    final static class MemItem {
9694        final String label;
9695        final String shortLabel;
9696        final long pss;
9697        final int id;
9698        ArrayList<MemItem> subitems;
9699
9700        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
9701            label = _label;
9702            shortLabel = _shortLabel;
9703            pss = _pss;
9704            id = _id;
9705        }
9706    }
9707
9708    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9709            boolean sort) {
9710        if (sort) {
9711            Collections.sort(items, new Comparator<MemItem>() {
9712                @Override
9713                public int compare(MemItem lhs, MemItem rhs) {
9714                    if (lhs.pss < rhs.pss) {
9715                        return 1;
9716                    } else if (lhs.pss > rhs.pss) {
9717                        return -1;
9718                    }
9719                    return 0;
9720                }
9721            });
9722        }
9723
9724        for (int i=0; i<items.size(); i++) {
9725            MemItem mi = items.get(i);
9726            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
9727            if (mi.subitems != null) {
9728                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
9729            }
9730        }
9731    }
9732
9733    // These are in KB.
9734    static final long[] DUMP_MEM_BUCKETS = new long[] {
9735        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9736        120*1024, 160*1024, 200*1024,
9737        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9738        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9739    };
9740
9741    static final void appendMemBucket(StringBuilder out, long memKB, String label,
9742            boolean stackLike) {
9743        int start = label.lastIndexOf('.');
9744        if (start >= 0) start++;
9745        else start = 0;
9746        int end = label.length();
9747        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
9748            if (DUMP_MEM_BUCKETS[i] >= memKB) {
9749                long bucket = DUMP_MEM_BUCKETS[i]/1024;
9750                out.append(bucket);
9751                out.append(stackLike ? "MB." : "MB ");
9752                out.append(label, start, end);
9753                return;
9754            }
9755        }
9756        out.append(memKB/1024);
9757        out.append(stackLike ? "MB." : "MB ");
9758        out.append(label, start, end);
9759    }
9760
9761    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
9762            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9763            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9764            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
9765            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
9766    };
9767    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
9768            "System", "Persistent", "Foreground",
9769            "Visible", "Perceptible", "Heavy Weight",
9770            "Backup", "A Services", "Home", "Previous",
9771            "B Services", "Background"
9772    };
9773
9774    final void dumpApplicationMemoryUsage(FileDescriptor fd,
9775            PrintWriter pw, String prefix, String[] args, boolean brief,
9776            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
9777        boolean dumpAll = false;
9778        boolean oomOnly = false;
9779
9780        int opti = 0;
9781        while (opti < args.length) {
9782            String opt = args[opti];
9783            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9784                break;
9785            }
9786            opti++;
9787            if ("-a".equals(opt)) {
9788                dumpAll = true;
9789            } else if ("--oom".equals(opt)) {
9790                oomOnly = true;
9791            } else if ("-h".equals(opt)) {
9792                pw.println("meminfo dump options: [-a] [--oom] [process]");
9793                pw.println("  -a: include all available information for each process.");
9794                pw.println("  --oom: only show processes organized by oom adj.");
9795                pw.println("If [process] is specified it can be the name or ");
9796                pw.println("pid of a specific process to dump.");
9797                return;
9798            } else {
9799                pw.println("Unknown argument: " + opt + "; use -h for help");
9800            }
9801        }
9802
9803        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
9804        if (procs == null) {
9805            return;
9806        }
9807
9808        final boolean isCheckinRequest = scanArgs(args, "--checkin");
9809        long uptime = SystemClock.uptimeMillis();
9810        long realtime = SystemClock.elapsedRealtime();
9811
9812        if (procs.size() == 1 || isCheckinRequest) {
9813            dumpAll = true;
9814        }
9815
9816        if (isCheckinRequest) {
9817            // short checkin version
9818            pw.println(uptime + "," + realtime);
9819            pw.flush();
9820        } else {
9821            pw.println("Applications Memory Usage (kB):");
9822            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9823        }
9824
9825        String[] innerArgs = new String[args.length-opti];
9826        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9827
9828        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9829        long nativePss=0, dalvikPss=0, otherPss=0;
9830        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9831
9832        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
9833        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
9834                new ArrayList[DUMP_MEM_OOM_LABEL.length];
9835
9836        long totalPss = 0;
9837
9838        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9839            ProcessRecord r = procs.get(i);
9840            if (r.thread != null) {
9841                if (!isCheckinRequest && dumpAll) {
9842                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9843                    pw.flush();
9844                }
9845                Debug.MemoryInfo mi = null;
9846                if (dumpAll) {
9847                    try {
9848                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9849                    } catch (RemoteException e) {
9850                        if (!isCheckinRequest) {
9851                            pw.println("Got RemoteException!");
9852                            pw.flush();
9853                        }
9854                    }
9855                } else {
9856                    mi = new Debug.MemoryInfo();
9857                    Debug.getMemoryInfo(r.pid, mi);
9858                }
9859
9860                if (!isCheckinRequest && mi != null) {
9861                    long myTotalPss = mi.getTotalPss();
9862                    totalPss += myTotalPss;
9863                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
9864                            r.processName, myTotalPss, 0);
9865                    procMems.add(pssItem);
9866
9867                    nativePss += mi.nativePss;
9868                    dalvikPss += mi.dalvikPss;
9869                    otherPss += mi.otherPss;
9870                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9871                        long mem = mi.getOtherPss(j);
9872                        miscPss[j] += mem;
9873                        otherPss -= mem;
9874                    }
9875
9876                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
9877                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
9878                                || oomIndex == (oomPss.length-1)) {
9879                            oomPss[oomIndex] += myTotalPss;
9880                            if (oomProcs[oomIndex] == null) {
9881                                oomProcs[oomIndex] = new ArrayList<MemItem>();
9882                            }
9883                            oomProcs[oomIndex].add(pssItem);
9884                            break;
9885                        }
9886                    }
9887                }
9888            }
9889        }
9890
9891        if (!isCheckinRequest && procs.size() > 1) {
9892            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9893
9894            catMems.add(new MemItem("Native", "Native", nativePss, -1));
9895            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
9896            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
9897            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9898                String label = Debug.MemoryInfo.getOtherLabel(j);
9899                catMems.add(new MemItem(label, label, miscPss[j], j));
9900            }
9901
9902            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9903            for (int j=0; j<oomPss.length; j++) {
9904                if (oomPss[j] != 0) {
9905                    String label = DUMP_MEM_OOM_LABEL[j];
9906                    MemItem item = new MemItem(label, label, oomPss[j],
9907                            DUMP_MEM_OOM_ADJ[j]);
9908                    item.subitems = oomProcs[j];
9909                    oomMems.add(item);
9910                }
9911            }
9912
9913            if (outTag != null || outStack != null) {
9914                if (outTag != null) {
9915                    appendMemBucket(outTag, totalPss, "total", false);
9916                }
9917                if (outStack != null) {
9918                    appendMemBucket(outStack, totalPss, "total", true);
9919                }
9920                boolean firstLine = true;
9921                for (int i=0; i<oomMems.size(); i++) {
9922                    MemItem miCat = oomMems.get(i);
9923                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
9924                        continue;
9925                    }
9926                    if (miCat.id < ProcessList.SERVICE_ADJ
9927                            || miCat.id == ProcessList.HOME_APP_ADJ
9928                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
9929                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
9930                            outTag.append(" / ");
9931                        }
9932                        if (outStack != null) {
9933                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
9934                                if (firstLine) {
9935                                    outStack.append(":");
9936                                    firstLine = false;
9937                                }
9938                                outStack.append("\n\t at ");
9939                            } else {
9940                                outStack.append("$");
9941                            }
9942                        }
9943                        for (int j=0; j<miCat.subitems.size(); j++) {
9944                            MemItem mi = miCat.subitems.get(j);
9945                            if (j > 0) {
9946                                if (outTag != null) {
9947                                    outTag.append(" ");
9948                                }
9949                                if (outStack != null) {
9950                                    outStack.append("$");
9951                                }
9952                            }
9953                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
9954                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
9955                            }
9956                            if (outStack != null) {
9957                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
9958                            }
9959                        }
9960                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
9961                            outStack.append("(");
9962                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
9963                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
9964                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
9965                                    outStack.append(":");
9966                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
9967                                }
9968                            }
9969                            outStack.append(")");
9970                        }
9971                    }
9972                }
9973            }
9974
9975            if (!brief && !oomOnly) {
9976                pw.println();
9977                pw.println("Total PSS by process:");
9978                dumpMemItems(pw, "  ", procMems, true);
9979                pw.println();
9980            }
9981            pw.println("Total PSS by OOM adjustment:");
9982            dumpMemItems(pw, "  ", oomMems, false);
9983            if (!oomOnly) {
9984                PrintWriter out = categoryPw != null ? categoryPw : pw;
9985                out.println();
9986                out.println("Total PSS by category:");
9987                dumpMemItems(out, "  ", catMems, true);
9988            }
9989            pw.println();
9990            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
9991        }
9992    }
9993
9994    /**
9995     * Searches array of arguments for the specified string
9996     * @param args array of argument strings
9997     * @param value value to search for
9998     * @return true if the value is contained in the array
9999     */
10000    private static boolean scanArgs(String[] args, String value) {
10001        if (args != null) {
10002            for (String arg : args) {
10003                if (value.equals(arg)) {
10004                    return true;
10005                }
10006            }
10007        }
10008        return false;
10009    }
10010
10011    private final void killServicesLocked(ProcessRecord app,
10012            boolean allowRestart) {
10013        // Report disconnected services.
10014        if (false) {
10015            // XXX we are letting the client link to the service for
10016            // death notifications.
10017            if (app.services.size() > 0) {
10018                Iterator<ServiceRecord> it = app.services.iterator();
10019                while (it.hasNext()) {
10020                    ServiceRecord r = it.next();
10021                    if (r.connections.size() > 0) {
10022                        Iterator<ArrayList<ConnectionRecord>> jt
10023                                = r.connections.values().iterator();
10024                        while (jt.hasNext()) {
10025                            ArrayList<ConnectionRecord> cl = jt.next();
10026                            for (int i=0; i<cl.size(); i++) {
10027                                ConnectionRecord c = cl.get(i);
10028                                if (c.binding.client != app) {
10029                                    try {
10030                                        //c.conn.connected(r.className, null);
10031                                    } catch (Exception e) {
10032                                        // todo: this should be asynchronous!
10033                                        Slog.w(TAG, "Exception thrown disconnected servce "
10034                                              + r.shortName
10035                                              + " from app " + app.processName, e);
10036                                    }
10037                                }
10038                            }
10039                        }
10040                    }
10041                }
10042            }
10043        }
10044
10045        // Clean up any connections this application has to other services.
10046        if (app.connections.size() > 0) {
10047            Iterator<ConnectionRecord> it = app.connections.iterator();
10048            while (it.hasNext()) {
10049                ConnectionRecord r = it.next();
10050                removeConnectionLocked(r, app, null);
10051            }
10052        }
10053        app.connections.clear();
10054
10055        if (app.services.size() != 0) {
10056            // Any services running in the application need to be placed
10057            // back in the pending list.
10058            Iterator<ServiceRecord> it = app.services.iterator();
10059            while (it.hasNext()) {
10060                ServiceRecord sr = it.next();
10061                synchronized (sr.stats.getBatteryStats()) {
10062                    sr.stats.stopLaunchedLocked();
10063                }
10064                sr.app = null;
10065                sr.executeNesting = 0;
10066                if (mStoppingServices.remove(sr)) {
10067                    if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
10068                }
10069
10070                boolean hasClients = sr.bindings.size() > 0;
10071                if (hasClients) {
10072                    Iterator<IntentBindRecord> bindings
10073                            = sr.bindings.values().iterator();
10074                    while (bindings.hasNext()) {
10075                        IntentBindRecord b = bindings.next();
10076                        if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
10077                                + ": shouldUnbind=" + b.hasBound);
10078                        b.binder = null;
10079                        b.requested = b.received = b.hasBound = false;
10080                    }
10081                }
10082
10083                if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
10084                        &ApplicationInfo.FLAG_PERSISTENT) == 0) {
10085                    Slog.w(TAG, "Service crashed " + sr.crashCount
10086                            + " times, stopping: " + sr);
10087                    EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
10088                            sr.crashCount, sr.shortName, app.pid);
10089                    bringDownServiceLocked(sr, true);
10090                } else if (!allowRestart) {
10091                    bringDownServiceLocked(sr, true);
10092                } else {
10093                    boolean canceled = scheduleServiceRestartLocked(sr, true);
10094
10095                    // Should the service remain running?  Note that in the
10096                    // extreme case of so many attempts to deliver a command
10097                    // that it failed we also will stop it here.
10098                    if (sr.startRequested && (sr.stopIfKilled || canceled)) {
10099                        if (sr.pendingStarts.size() == 0) {
10100                            sr.startRequested = false;
10101                            if (!hasClients) {
10102                                // Whoops, no reason to restart!
10103                                bringDownServiceLocked(sr, true);
10104                            }
10105                        }
10106                    }
10107                }
10108            }
10109
10110            if (!allowRestart) {
10111                app.services.clear();
10112            }
10113        }
10114
10115        // Make sure we have no more records on the stopping list.
10116        int i = mStoppingServices.size();
10117        while (i > 0) {
10118            i--;
10119            ServiceRecord sr = mStoppingServices.get(i);
10120            if (sr.app == app) {
10121                mStoppingServices.remove(i);
10122                if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
10123            }
10124        }
10125
10126        app.executingServices.clear();
10127    }
10128
10129    private final void removeDyingProviderLocked(ProcessRecord proc,
10130            ContentProviderRecord cpr) {
10131        synchronized (cpr) {
10132            cpr.launchingApp = null;
10133            cpr.notifyAll();
10134        }
10135
10136        mProvidersByClass.remove(cpr.name);
10137        String names[] = cpr.info.authority.split(";");
10138        for (int j = 0; j < names.length; j++) {
10139            mProvidersByName.remove(names[j]);
10140        }
10141
10142        Iterator<ProcessRecord> cit = cpr.clients.iterator();
10143        while (cit.hasNext()) {
10144            ProcessRecord capp = cit.next();
10145            if (!capp.persistent && capp.thread != null
10146                    && capp.pid != 0
10147                    && capp.pid != MY_PID) {
10148                Slog.i(TAG, "Kill " + capp.processName
10149                        + " (pid " + capp.pid + "): provider " + cpr.info.name
10150                        + " in dying process " + (proc != null ? proc.processName : "??"));
10151                EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10152                        capp.processName, capp.setAdj, "dying provider "
10153                                + cpr.name.toShortString());
10154                Process.killProcessQuiet(capp.pid);
10155            }
10156        }
10157
10158        mLaunchingProviders.remove(cpr);
10159    }
10160
10161    /**
10162     * Main code for cleaning up a process when it has gone away.  This is
10163     * called both as a result of the process dying, or directly when stopping
10164     * a process when running in single process mode.
10165     */
10166    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10167            boolean restarting, boolean allowRestart, int index) {
10168        if (index >= 0) {
10169            mLruProcesses.remove(index);
10170        }
10171
10172        mProcessesToGc.remove(app);
10173
10174        // Dismiss any open dialogs.
10175        if (app.crashDialog != null) {
10176            app.crashDialog.dismiss();
10177            app.crashDialog = null;
10178        }
10179        if (app.anrDialog != null) {
10180            app.anrDialog.dismiss();
10181            app.anrDialog = null;
10182        }
10183        if (app.waitDialog != null) {
10184            app.waitDialog.dismiss();
10185            app.waitDialog = null;
10186        }
10187
10188        app.crashing = false;
10189        app.notResponding = false;
10190
10191        app.resetPackageList();
10192        app.unlinkDeathRecipient();
10193        app.thread = null;
10194        app.forcingToForeground = null;
10195        app.foregroundServices = false;
10196        app.foregroundActivities = false;
10197        app.hasShownUi = false;
10198        app.hasAboveClient = false;
10199
10200        killServicesLocked(app, allowRestart);
10201
10202        boolean restart = false;
10203
10204        int NL = mLaunchingProviders.size();
10205
10206        // Remove published content providers.
10207        if (!app.pubProviders.isEmpty()) {
10208            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10209            while (it.hasNext()) {
10210                ContentProviderRecord cpr = it.next();
10211                cpr.provider = null;
10212                cpr.proc = null;
10213
10214                // See if someone is waiting for this provider...  in which
10215                // case we don't remove it, but just let it restart.
10216                int i = 0;
10217                if (!app.bad && allowRestart) {
10218                    for (; i<NL; i++) {
10219                        if (mLaunchingProviders.get(i) == cpr) {
10220                            restart = true;
10221                            break;
10222                        }
10223                    }
10224                } else {
10225                    i = NL;
10226                }
10227
10228                if (i >= NL) {
10229                    removeDyingProviderLocked(app, cpr);
10230                    NL = mLaunchingProviders.size();
10231                }
10232            }
10233            app.pubProviders.clear();
10234        }
10235
10236        // Take care of any launching providers waiting for this process.
10237        if (checkAppInLaunchingProvidersLocked(app, false)) {
10238            restart = true;
10239        }
10240
10241        // Unregister from connected content providers.
10242        if (!app.conProviders.isEmpty()) {
10243            Iterator it = app.conProviders.keySet().iterator();
10244            while (it.hasNext()) {
10245                ContentProviderRecord cpr = (ContentProviderRecord)it.next();
10246                cpr.clients.remove(app);
10247            }
10248            app.conProviders.clear();
10249        }
10250
10251        // At this point there may be remaining entries in mLaunchingProviders
10252        // where we were the only one waiting, so they are no longer of use.
10253        // Look for these and clean up if found.
10254        // XXX Commented out for now.  Trying to figure out a way to reproduce
10255        // the actual situation to identify what is actually going on.
10256        if (false) {
10257            for (int i=0; i<NL; i++) {
10258                ContentProviderRecord cpr = (ContentProviderRecord)
10259                        mLaunchingProviders.get(i);
10260                if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
10261                    synchronized (cpr) {
10262                        cpr.launchingApp = null;
10263                        cpr.notifyAll();
10264                    }
10265                }
10266            }
10267        }
10268
10269        skipCurrentReceiverLocked(app);
10270
10271        // Unregister any receivers.
10272        if (app.receivers.size() > 0) {
10273            Iterator<ReceiverList> it = app.receivers.iterator();
10274            while (it.hasNext()) {
10275                removeReceiverLocked(it.next());
10276            }
10277            app.receivers.clear();
10278        }
10279
10280        // If the app is undergoing backup, tell the backup manager about it
10281        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10282            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10283            try {
10284                IBackupManager bm = IBackupManager.Stub.asInterface(
10285                        ServiceManager.getService(Context.BACKUP_SERVICE));
10286                bm.agentDisconnected(app.info.packageName);
10287            } catch (RemoteException e) {
10288                // can't happen; backup manager is local
10289            }
10290        }
10291
10292        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10293
10294        // If the caller is restarting this app, then leave it in its
10295        // current lists and let the caller take care of it.
10296        if (restarting) {
10297            return;
10298        }
10299
10300        if (!app.persistent) {
10301            if (DEBUG_PROCESSES) Slog.v(TAG,
10302                    "Removing non-persistent process during cleanup: " + app);
10303            mProcessNames.remove(app.processName, app.info.uid);
10304            if (mHeavyWeightProcess == app) {
10305                mHeavyWeightProcess = null;
10306                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10307            }
10308        } else if (!app.removed) {
10309            // This app is persistent, so we need to keep its record around.
10310            // If it is not already on the pending app list, add it there
10311            // and start a new process for it.
10312            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10313                mPersistentStartingProcesses.add(app);
10314                restart = true;
10315            }
10316        }
10317        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10318                "Clean-up removing on hold: " + app);
10319        mProcessesOnHold.remove(app);
10320
10321        if (app == mHomeProcess) {
10322            mHomeProcess = null;
10323        }
10324        if (app == mPreviousProcess) {
10325            mPreviousProcess = null;
10326        }
10327
10328        if (restart) {
10329            // We have components that still need to be running in the
10330            // process, so re-launch it.
10331            mProcessNames.put(app.processName, app.info.uid, app);
10332            startProcessLocked(app, "restart", app.processName);
10333        } else if (app.pid > 0 && app.pid != MY_PID) {
10334            // Goodbye!
10335            synchronized (mPidsSelfLocked) {
10336                mPidsSelfLocked.remove(app.pid);
10337                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10338            }
10339            app.setPid(0);
10340        }
10341    }
10342
10343    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10344        // Look through the content providers we are waiting to have launched,
10345        // and if any run in this process then either schedule a restart of
10346        // the process or kill the client waiting for it if this process has
10347        // gone bad.
10348        int NL = mLaunchingProviders.size();
10349        boolean restart = false;
10350        for (int i=0; i<NL; i++) {
10351            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10352            if (cpr.launchingApp == app) {
10353                if (!alwaysBad && !app.bad) {
10354                    restart = true;
10355                } else {
10356                    removeDyingProviderLocked(app, cpr);
10357                    NL = mLaunchingProviders.size();
10358                }
10359            }
10360        }
10361        return restart;
10362    }
10363
10364    // =========================================================
10365    // SERVICES
10366    // =========================================================
10367
10368    ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
10369        ActivityManager.RunningServiceInfo info =
10370            new ActivityManager.RunningServiceInfo();
10371        info.service = r.name;
10372        if (r.app != null) {
10373            info.pid = r.app.pid;
10374        }
10375        info.uid = r.appInfo.uid;
10376        info.process = r.processName;
10377        info.foreground = r.isForeground;
10378        info.activeSince = r.createTime;
10379        info.started = r.startRequested;
10380        info.clientCount = r.connections.size();
10381        info.crashCount = r.crashCount;
10382        info.lastActivityTime = r.lastActivity;
10383        if (r.isForeground) {
10384            info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
10385        }
10386        if (r.startRequested) {
10387            info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
10388        }
10389        if (r.app != null && r.app.pid == MY_PID) {
10390            info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
10391        }
10392        if (r.app != null && r.app.persistent) {
10393            info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
10394        }
10395
10396        for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
10397            for (int i=0; i<connl.size(); i++) {
10398                ConnectionRecord conn = connl.get(i);
10399                if (conn.clientLabel != 0) {
10400                    info.clientPackage = conn.binding.client.info.packageName;
10401                    info.clientLabel = conn.clientLabel;
10402                    return info;
10403                }
10404            }
10405        }
10406        return info;
10407    }
10408
10409    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10410            int flags) {
10411        synchronized (this) {
10412            ArrayList<ActivityManager.RunningServiceInfo> res
10413                    = new ArrayList<ActivityManager.RunningServiceInfo>();
10414
10415            if (mServices.size() > 0) {
10416                Iterator<ServiceRecord> it = mServices.values().iterator();
10417                while (it.hasNext() && res.size() < maxNum) {
10418                    res.add(makeRunningServiceInfoLocked(it.next()));
10419                }
10420            }
10421
10422            for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
10423                ServiceRecord r = mRestartingServices.get(i);
10424                ActivityManager.RunningServiceInfo info =
10425                        makeRunningServiceInfoLocked(r);
10426                info.restarting = r.nextRestartTime;
10427                res.add(info);
10428            }
10429
10430            return res;
10431        }
10432    }
10433
10434    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10435        synchronized (this) {
10436            ServiceRecord r = mServices.get(name);
10437            if (r != null) {
10438                for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
10439                    for (int i=0; i<conn.size(); i++) {
10440                        if (conn.get(i).clientIntent != null) {
10441                            return conn.get(i).clientIntent;
10442                        }
10443                    }
10444                }
10445            }
10446        }
10447        return null;
10448    }
10449
10450    private final ServiceRecord findServiceLocked(ComponentName name,
10451            IBinder token) {
10452        ServiceRecord r = mServices.get(name);
10453        return r == token ? r : null;
10454    }
10455
10456    private final class ServiceLookupResult {
10457        final ServiceRecord record;
10458        final String permission;
10459
10460        ServiceLookupResult(ServiceRecord _record, String _permission) {
10461            record = _record;
10462            permission = _permission;
10463        }
10464    };
10465
10466    private ServiceLookupResult findServiceLocked(Intent service,
10467            String resolvedType) {
10468        ServiceRecord r = null;
10469        if (service.getComponent() != null) {
10470            r = mServices.get(service.getComponent());
10471        }
10472        if (r == null) {
10473            Intent.FilterComparison filter = new Intent.FilterComparison(service);
10474            r = mServicesByIntent.get(filter);
10475        }
10476
10477        if (r == null) {
10478            try {
10479                ResolveInfo rInfo =
10480                    AppGlobals.getPackageManager().resolveService(
10481                            service, resolvedType, 0);
10482                ServiceInfo sInfo =
10483                    rInfo != null ? rInfo.serviceInfo : null;
10484                if (sInfo == null) {
10485                    return null;
10486                }
10487
10488                ComponentName name = new ComponentName(
10489                        sInfo.applicationInfo.packageName, sInfo.name);
10490                r = mServices.get(name);
10491            } catch (RemoteException ex) {
10492                // pm is in same process, this will never happen.
10493            }
10494        }
10495        if (r != null) {
10496            int callingPid = Binder.getCallingPid();
10497            int callingUid = Binder.getCallingUid();
10498            if (checkComponentPermission(r.permission,
10499                    callingPid, callingUid, r.appInfo.uid, r.exported)
10500                    != PackageManager.PERMISSION_GRANTED) {
10501                if (!r.exported) {
10502                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10503                            + " from pid=" + callingPid
10504                            + ", uid=" + callingUid
10505                            + " that is not exported from uid " + r.appInfo.uid);
10506                    return new ServiceLookupResult(null, "not exported from uid "
10507                            + r.appInfo.uid);
10508                }
10509                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10510                        + " from pid=" + callingPid
10511                        + ", uid=" + callingUid
10512                        + " requires " + r.permission);
10513                return new ServiceLookupResult(null, r.permission);
10514            }
10515            return new ServiceLookupResult(r, null);
10516        }
10517        return null;
10518    }
10519
10520    private class ServiceRestarter implements Runnable {
10521        private ServiceRecord mService;
10522
10523        void setService(ServiceRecord service) {
10524            mService = service;
10525        }
10526
10527        public void run() {
10528            synchronized(ActivityManagerService.this) {
10529                performServiceRestartLocked(mService);
10530            }
10531        }
10532    }
10533
10534    private ServiceLookupResult retrieveServiceLocked(Intent service,
10535            String resolvedType, int callingPid, int callingUid) {
10536        ServiceRecord r = null;
10537        if (service.getComponent() != null) {
10538            r = mServices.get(service.getComponent());
10539        }
10540        Intent.FilterComparison filter = new Intent.FilterComparison(service);
10541        r = mServicesByIntent.get(filter);
10542        if (r == null) {
10543            try {
10544                ResolveInfo rInfo =
10545                    AppGlobals.getPackageManager().resolveService(
10546                            service, resolvedType, STOCK_PM_FLAGS);
10547                ServiceInfo sInfo =
10548                    rInfo != null ? rInfo.serviceInfo : null;
10549                if (sInfo == null) {
10550                    Slog.w(TAG, "Unable to start service " + service +
10551                          ": not found");
10552                    return null;
10553                }
10554
10555                ComponentName name = new ComponentName(
10556                        sInfo.applicationInfo.packageName, sInfo.name);
10557                r = mServices.get(name);
10558                if (r == null) {
10559                    filter = new Intent.FilterComparison(service.cloneFilter());
10560                    ServiceRestarter res = new ServiceRestarter();
10561                    BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10562                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10563                    synchronized (stats) {
10564                        ss = stats.getServiceStatsLocked(
10565                                sInfo.applicationInfo.uid, sInfo.packageName,
10566                                sInfo.name);
10567                    }
10568                    r = new ServiceRecord(this, ss, name, filter, sInfo, res);
10569                    res.setService(r);
10570                    mServices.put(name, r);
10571                    mServicesByIntent.put(filter, r);
10572
10573                    // Make sure this component isn't in the pending list.
10574                    int N = mPendingServices.size();
10575                    for (int i=0; i<N; i++) {
10576                        ServiceRecord pr = mPendingServices.get(i);
10577                        if (pr.name.equals(name)) {
10578                            mPendingServices.remove(i);
10579                            i--;
10580                            N--;
10581                        }
10582                    }
10583                }
10584            } catch (RemoteException ex) {
10585                // pm is in same process, this will never happen.
10586            }
10587        }
10588        if (r != null) {
10589            if (checkComponentPermission(r.permission,
10590                    callingPid, callingUid, r.appInfo.uid, r.exported)
10591                    != PackageManager.PERMISSION_GRANTED) {
10592                if (!r.exported) {
10593                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10594                            + " from pid=" + callingPid
10595                            + ", uid=" + callingUid
10596                            + " that is not exported from uid " + r.appInfo.uid);
10597                    return new ServiceLookupResult(null, "not exported from uid "
10598                            + r.appInfo.uid);
10599                }
10600                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10601                        + " from pid=" + callingPid
10602                        + ", uid=" + callingUid
10603                        + " requires " + r.permission);
10604                return new ServiceLookupResult(null, r.permission);
10605            }
10606            return new ServiceLookupResult(r, null);
10607        }
10608        return null;
10609    }
10610
10611    private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
10612        if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
10613                + why + " of " + r + " in app " + r.app);
10614        else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
10615                + why + " of " + r.shortName);
10616        long now = SystemClock.uptimeMillis();
10617        if (r.executeNesting == 0 && r.app != null) {
10618            if (r.app.executingServices.size() == 0) {
10619                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10620                msg.obj = r.app;
10621                mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
10622            }
10623            r.app.executingServices.add(r);
10624        }
10625        r.executeNesting++;
10626        r.executingStart = now;
10627    }
10628
10629    private final void sendServiceArgsLocked(ServiceRecord r,
10630            boolean oomAdjusted) {
10631        final int N = r.pendingStarts.size();
10632        if (N == 0) {
10633            return;
10634        }
10635
10636        while (r.pendingStarts.size() > 0) {
10637            try {
10638                ServiceRecord.StartItem si = r.pendingStarts.remove(0);
10639                if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
10640                        + r + " " + r.intent + " args=" + si.intent);
10641                if (si.intent == null && N > 1) {
10642                    // If somehow we got a dummy null intent in the middle,
10643                    // then skip it.  DO NOT skip a null intent when it is
10644                    // the only one in the list -- this is to support the
10645                    // onStartCommand(null) case.
10646                    continue;
10647                }
10648                si.deliveredTime = SystemClock.uptimeMillis();
10649                r.deliveredStarts.add(si);
10650                si.deliveryCount++;
10651                if (si.targetPermissionUid >= 0 && si.intent != null) {
10652                    grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
10653                            r.packageName, si.intent, si.getUriPermissionsLocked());
10654                }
10655                bumpServiceExecutingLocked(r, "start");
10656                if (!oomAdjusted) {
10657                    oomAdjusted = true;
10658                    updateOomAdjLocked(r.app);
10659                }
10660                int flags = 0;
10661                if (si.deliveryCount > 0) {
10662                    flags |= Service.START_FLAG_RETRY;
10663                }
10664                if (si.doneExecutingCount > 0) {
10665                    flags |= Service.START_FLAG_REDELIVERY;
10666                }
10667                r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
10668            } catch (RemoteException e) {
10669                // Remote process gone...  we'll let the normal cleanup take
10670                // care of this.
10671                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
10672                break;
10673            } catch (Exception e) {
10674                Slog.w(TAG, "Unexpected exception", e);
10675                break;
10676            }
10677        }
10678    }
10679
10680    private final boolean requestServiceBindingLocked(ServiceRecord r,
10681            IntentBindRecord i, boolean rebind) {
10682        if (r.app == null || r.app.thread == null) {
10683            // If service is not currently running, can't yet bind.
10684            return false;
10685        }
10686        if ((!i.requested || rebind) && i.apps.size() > 0) {
10687            try {
10688                bumpServiceExecutingLocked(r, "bind");
10689                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10690                if (!rebind) {
10691                    i.requested = true;
10692                }
10693                i.hasBound = true;
10694                i.doRebind = false;
10695            } catch (RemoteException e) {
10696                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
10697                return false;
10698            }
10699        }
10700        return true;
10701    }
10702
10703    private final void requestServiceBindingsLocked(ServiceRecord r) {
10704        Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10705        while (bindings.hasNext()) {
10706            IntentBindRecord i = bindings.next();
10707            if (!requestServiceBindingLocked(r, i, false)) {
10708                break;
10709            }
10710        }
10711    }
10712
10713    private final void realStartServiceLocked(ServiceRecord r,
10714            ProcessRecord app) throws RemoteException {
10715        if (app.thread == null) {
10716            throw new RemoteException();
10717        }
10718
10719        r.app = app;
10720        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
10721
10722        app.services.add(r);
10723        bumpServiceExecutingLocked(r, "create");
10724        updateLruProcessLocked(app, true, true);
10725
10726        boolean created = false;
10727        try {
10728            mStringBuilder.setLength(0);
10729            r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
10730            EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
10731                    System.identityHashCode(r), r.shortName,
10732                    mStringBuilder.toString(), r.app.pid);
10733            synchronized (r.stats.getBatteryStats()) {
10734                r.stats.startLaunchedLocked();
10735            }
10736            ensurePackageDexOpt(r.serviceInfo.packageName);
10737            app.thread.scheduleCreateService(r, r.serviceInfo,
10738                    compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
10739            r.postNotification();
10740            created = true;
10741        } finally {
10742            if (!created) {
10743                app.services.remove(r);
10744                scheduleServiceRestartLocked(r, false);
10745            }
10746        }
10747
10748        requestServiceBindingsLocked(r);
10749
10750        // If the service is in the started state, and there are no
10751        // pending arguments, then fake up one so its onStartCommand() will
10752        // be called.
10753        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
10754            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10755                    null, -1));
10756        }
10757
10758        sendServiceArgsLocked(r, true);
10759    }
10760
10761    private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10762            boolean allowCancel) {
10763        boolean canceled = false;
10764
10765        final long now = SystemClock.uptimeMillis();
10766        long minDuration = SERVICE_RESTART_DURATION;
10767        long resetTime = SERVICE_RESET_RUN_DURATION;
10768
10769        if ((r.serviceInfo.applicationInfo.flags
10770                &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10771            minDuration /= 4;
10772        }
10773
10774        // Any delivered but not yet finished starts should be put back
10775        // on the pending list.
10776        final int N = r.deliveredStarts.size();
10777        if (N > 0) {
10778            for (int i=N-1; i>=0; i--) {
10779                ServiceRecord.StartItem si = r.deliveredStarts.get(i);
10780                si.removeUriPermissionsLocked();
10781                if (si.intent == null) {
10782                    // We'll generate this again if needed.
10783                } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10784                        && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10785                    r.pendingStarts.add(0, si);
10786                    long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10787                    dur *= 2;
10788                    if (minDuration < dur) minDuration = dur;
10789                    if (resetTime < dur) resetTime = dur;
10790                } else {
10791                    Slog.w(TAG, "Canceling start item " + si.intent + " in service "
10792                            + r.name);
10793                    canceled = true;
10794                }
10795            }
10796            r.deliveredStarts.clear();
10797        }
10798
10799        r.totalRestartCount++;
10800        if (r.restartDelay == 0) {
10801            r.restartCount++;
10802            r.restartDelay = minDuration;
10803        } else {
10804            // If it has been a "reasonably long time" since the service
10805            // was started, then reset our restart duration back to
10806            // the beginning, so we don't infinitely increase the duration
10807            // on a service that just occasionally gets killed (which is
10808            // a normal case, due to process being killed to reclaim memory).
10809            if (now > (r.restartTime+resetTime)) {
10810                r.restartCount = 1;
10811                r.restartDelay = minDuration;
10812            } else {
10813                if ((r.serviceInfo.applicationInfo.flags
10814                        &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10815                    // Services in peristent processes will restart much more
10816                    // quickly, since they are pretty important.  (Think SystemUI).
10817                    r.restartDelay += minDuration/2;
10818                } else {
10819                    r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10820                    if (r.restartDelay < minDuration) {
10821                        r.restartDelay = minDuration;
10822                    }
10823                }
10824            }
10825        }
10826
10827        r.nextRestartTime = now + r.restartDelay;
10828
10829        // Make sure that we don't end up restarting a bunch of services
10830        // all at the same time.
10831        boolean repeat;
10832        do {
10833            repeat = false;
10834            for (int i=mRestartingServices.size()-1; i>=0; i--) {
10835                ServiceRecord r2 = mRestartingServices.get(i);
10836                if (r2 != r && r.nextRestartTime
10837                        >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10838                        && r.nextRestartTime
10839                        < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10840                    r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10841                    r.restartDelay = r.nextRestartTime - now;
10842                    repeat = true;
10843                    break;
10844                }
10845            }
10846        } while (repeat);
10847
10848        if (!mRestartingServices.contains(r)) {
10849            mRestartingServices.add(r);
10850        }
10851
10852        r.cancelNotification();
10853
10854        mHandler.removeCallbacks(r.restarter);
10855        mHandler.postAtTime(r.restarter, r.nextRestartTime);
10856        r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
10857        Slog.w(TAG, "Scheduling restart of crashed service "
10858                + r.shortName + " in " + r.restartDelay + "ms");
10859        EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
10860                r.shortName, r.restartDelay);
10861
10862        return canceled;
10863    }
10864
10865    final void performServiceRestartLocked(ServiceRecord r) {
10866        if (!mRestartingServices.contains(r)) {
10867            return;
10868        }
10869        bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10870    }
10871
10872    private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10873        if (r.restartDelay == 0) {
10874            return false;
10875        }
10876        r.resetRestartCounter();
10877        mRestartingServices.remove(r);
10878        mHandler.removeCallbacks(r.restarter);
10879        return true;
10880    }
10881
10882    private final boolean bringUpServiceLocked(ServiceRecord r,
10883            int intentFlags, boolean whileRestarting) {
10884        //Slog.i(TAG, "Bring up service:");
10885        //r.dump("  ");
10886
10887        if (r.app != null && r.app.thread != null) {
10888            sendServiceArgsLocked(r, false);
10889            return true;
10890        }
10891
10892        if (!whileRestarting && r.restartDelay > 0) {
10893            // If waiting for a restart, then do nothing.
10894            return true;
10895        }
10896
10897        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
10898
10899        // We are now bringing the service up, so no longer in the
10900        // restarting state.
10901        mRestartingServices.remove(r);
10902
10903        // Service is now being launched, its package can't be stopped.
10904        try {
10905            AppGlobals.getPackageManager().setPackageStoppedState(
10906                    r.packageName, false);
10907        } catch (RemoteException e) {
10908        } catch (IllegalArgumentException e) {
10909            Slog.w(TAG, "Failed trying to unstop package "
10910                    + r.packageName + ": " + e);
10911        }
10912
10913        final String appName = r.processName;
10914        ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10915        if (app != null && app.thread != null) {
10916            try {
10917                app.addPackage(r.appInfo.packageName);
10918                realStartServiceLocked(r, app);
10919                return true;
10920            } catch (RemoteException e) {
10921                Slog.w(TAG, "Exception when starting service " + r.shortName, e);
10922            }
10923
10924            // If a dead object exception was thrown -- fall through to
10925            // restart the application.
10926        }
10927
10928        // Not running -- get it started, and enqueue this service record
10929        // to be executed when the app comes up.
10930        if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10931                "service", r.name, false) == null) {
10932            Slog.w(TAG, "Unable to launch app "
10933                    + r.appInfo.packageName + "/"
10934                    + r.appInfo.uid + " for service "
10935                    + r.intent.getIntent() + ": process is bad");
10936            bringDownServiceLocked(r, true);
10937            return false;
10938        }
10939
10940        if (!mPendingServices.contains(r)) {
10941            mPendingServices.add(r);
10942        }
10943
10944        return true;
10945    }
10946
10947    private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
10948        //Slog.i(TAG, "Bring down service:");
10949        //r.dump("  ");
10950
10951        // Does it still need to run?
10952        if (!force && r.startRequested) {
10953            return;
10954        }
10955        if (r.connections.size() > 0) {
10956            if (!force) {
10957                // XXX should probably keep a count of the number of auto-create
10958                // connections directly in the service.
10959                Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
10960                while (it.hasNext()) {
10961                    ArrayList<ConnectionRecord> cr = it.next();
10962                    for (int i=0; i<cr.size(); i++) {
10963                        if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10964                            return;
10965                        }
10966                    }
10967                }
10968            }
10969
10970            // Report to all of the connections that the service is no longer
10971            // available.
10972            Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
10973            while (it.hasNext()) {
10974                ArrayList<ConnectionRecord> c = it.next();
10975                for (int i=0; i<c.size(); i++) {
10976                    ConnectionRecord cr = c.get(i);
10977                    // There is still a connection to the service that is
10978                    // being brought down.  Mark it as dead.
10979                    cr.serviceDead = true;
10980                    try {
10981                        cr.conn.connected(r.name, null);
10982                    } catch (Exception e) {
10983                        Slog.w(TAG, "Failure disconnecting service " + r.name +
10984                              " to connection " + c.get(i).conn.asBinder() +
10985                              " (in " + c.get(i).binding.client.processName + ")", e);
10986                    }
10987                }
10988            }
10989        }
10990
10991        // Tell the service that it has been unbound.
10992        if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10993            Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10994            while (it.hasNext()) {
10995                IntentBindRecord ibr = it.next();
10996                if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
10997                        + ": hasBound=" + ibr.hasBound);
10998                if (r.app != null && r.app.thread != null && ibr.hasBound) {
10999                    try {
11000                        bumpServiceExecutingLocked(r, "bring down unbind");
11001                        updateOomAdjLocked(r.app);
11002                        ibr.hasBound = false;
11003                        r.app.thread.scheduleUnbindService(r,
11004                                ibr.intent.getIntent());
11005                    } catch (Exception e) {
11006                        Slog.w(TAG, "Exception when unbinding service "
11007                                + r.shortName, e);
11008                        serviceDoneExecutingLocked(r, true);
11009                    }
11010                }
11011            }
11012        }
11013
11014        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
11015        EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
11016                System.identityHashCode(r), r.shortName,
11017                (r.app != null) ? r.app.pid : -1);
11018
11019        mServices.remove(r.name);
11020        mServicesByIntent.remove(r.intent);
11021        r.totalRestartCount = 0;
11022        unscheduleServiceRestartLocked(r);
11023
11024        // Also make sure it is not on the pending list.
11025        int N = mPendingServices.size();
11026        for (int i=0; i<N; i++) {
11027            if (mPendingServices.get(i) == r) {
11028                mPendingServices.remove(i);
11029                if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
11030                i--;
11031                N--;
11032            }
11033        }
11034
11035        r.cancelNotification();
11036        r.isForeground = false;
11037        r.foregroundId = 0;
11038        r.foregroundNoti = null;
11039
11040        // Clear start entries.
11041        r.clearDeliveredStartsLocked();
11042        r.pendingStarts.clear();
11043
11044        if (r.app != null) {
11045            synchronized (r.stats.getBatteryStats()) {
11046                r.stats.stopLaunchedLocked();
11047            }
11048            r.app.services.remove(r);
11049            if (r.app.thread != null) {
11050                try {
11051                    bumpServiceExecutingLocked(r, "stop");
11052                    mStoppingServices.add(r);
11053                    updateOomAdjLocked(r.app);
11054                    r.app.thread.scheduleStopService(r);
11055                } catch (Exception e) {
11056                    Slog.w(TAG, "Exception when stopping service "
11057                            + r.shortName, e);
11058                    serviceDoneExecutingLocked(r, true);
11059                }
11060                updateServiceForegroundLocked(r.app, false);
11061            } else {
11062                if (DEBUG_SERVICE) Slog.v(
11063                    TAG, "Removed service that has no process: " + r);
11064            }
11065        } else {
11066            if (DEBUG_SERVICE) Slog.v(
11067                TAG, "Removed service that is not running: " + r);
11068        }
11069
11070        if (r.bindings.size() > 0) {
11071            r.bindings.clear();
11072        }
11073
11074        if (r.restarter instanceof ServiceRestarter) {
11075           ((ServiceRestarter)r.restarter).setService(null);
11076        }
11077    }
11078
11079    ComponentName startServiceLocked(IApplicationThread caller,
11080            Intent service, String resolvedType,
11081            int callingPid, int callingUid) {
11082        synchronized(this) {
11083            if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
11084                    + " type=" + resolvedType + " args=" + service.getExtras());
11085
11086            if (caller != null) {
11087                final ProcessRecord callerApp = getRecordForAppLocked(caller);
11088                if (callerApp == null) {
11089                    throw new SecurityException(
11090                            "Unable to find app for caller " + caller
11091                            + " (pid=" + Binder.getCallingPid()
11092                            + ") when starting service " + service);
11093                }
11094            }
11095
11096            ServiceLookupResult res =
11097                retrieveServiceLocked(service, resolvedType,
11098                        callingPid, callingUid);
11099            if (res == null) {
11100                return null;
11101            }
11102            if (res.record == null) {
11103                return new ComponentName("!", res.permission != null
11104                        ? res.permission : "private to package");
11105            }
11106            ServiceRecord r = res.record;
11107            int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
11108                    callingUid, r.packageName, service);
11109            if (unscheduleServiceRestartLocked(r)) {
11110                if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
11111            }
11112            r.startRequested = true;
11113            r.callStart = false;
11114            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
11115                    service, targetPermissionUid));
11116            r.lastActivity = SystemClock.uptimeMillis();
11117            synchronized (r.stats.getBatteryStats()) {
11118                r.stats.startRunningLocked();
11119            }
11120            if (!bringUpServiceLocked(r, service.getFlags(), false)) {
11121                return new ComponentName("!", "Service process is bad");
11122            }
11123            return r.name;
11124        }
11125    }
11126
11127    public ComponentName startService(IApplicationThread caller, Intent service,
11128            String resolvedType) {
11129        // Refuse possible leaked file descriptors
11130        if (service != null && service.hasFileDescriptors() == true) {
11131            throw new IllegalArgumentException("File descriptors passed in Intent");
11132        }
11133
11134        synchronized(this) {
11135            final int callingPid = Binder.getCallingPid();
11136            final int callingUid = Binder.getCallingUid();
11137            final long origId = Binder.clearCallingIdentity();
11138            ComponentName res = startServiceLocked(caller, service,
11139                    resolvedType, callingPid, callingUid);
11140            Binder.restoreCallingIdentity(origId);
11141            return res;
11142        }
11143    }
11144
11145    ComponentName startServiceInPackage(int uid,
11146            Intent service, String resolvedType) {
11147        synchronized(this) {
11148            final long origId = Binder.clearCallingIdentity();
11149            ComponentName res = startServiceLocked(null, service,
11150                    resolvedType, -1, uid);
11151            Binder.restoreCallingIdentity(origId);
11152            return res;
11153        }
11154    }
11155
11156    private void stopServiceLocked(ServiceRecord service) {
11157        synchronized (service.stats.getBatteryStats()) {
11158            service.stats.stopRunningLocked();
11159        }
11160        service.startRequested = false;
11161        service.callStart = false;
11162        bringDownServiceLocked(service, false);
11163    }
11164
11165    public int stopService(IApplicationThread caller, Intent service,
11166            String resolvedType) {
11167        // Refuse possible leaked file descriptors
11168        if (service != null && service.hasFileDescriptors() == true) {
11169            throw new IllegalArgumentException("File descriptors passed in Intent");
11170        }
11171
11172        synchronized(this) {
11173            if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
11174                    + " type=" + resolvedType);
11175
11176            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11177            if (caller != null && callerApp == null) {
11178                throw new SecurityException(
11179                        "Unable to find app for caller " + caller
11180                        + " (pid=" + Binder.getCallingPid()
11181                        + ") when stopping service " + service);
11182            }
11183
11184            // If this service is active, make sure it is stopped.
11185            ServiceLookupResult r = findServiceLocked(service, resolvedType);
11186            if (r != null) {
11187                if (r.record != null) {
11188                    final long origId = Binder.clearCallingIdentity();
11189                    try {
11190                        stopServiceLocked(r.record);
11191                    } finally {
11192                        Binder.restoreCallingIdentity(origId);
11193                    }
11194                    return 1;
11195                }
11196                return -1;
11197            }
11198        }
11199
11200        return 0;
11201    }
11202
11203    public IBinder peekService(Intent service, String resolvedType) {
11204        // Refuse possible leaked file descriptors
11205        if (service != null && service.hasFileDescriptors() == true) {
11206            throw new IllegalArgumentException("File descriptors passed in Intent");
11207        }
11208
11209        IBinder ret = null;
11210
11211        synchronized(this) {
11212            ServiceLookupResult r = findServiceLocked(service, resolvedType);
11213
11214            if (r != null) {
11215                // r.record is null if findServiceLocked() failed the caller permission check
11216                if (r.record == null) {
11217                    throw new SecurityException(
11218                            "Permission Denial: Accessing service " + r.record.name
11219                            + " from pid=" + Binder.getCallingPid()
11220                            + ", uid=" + Binder.getCallingUid()
11221                            + " requires " + r.permission);
11222                }
11223                IntentBindRecord ib = r.record.bindings.get(r.record.intent);
11224                if (ib != null) {
11225                    ret = ib.binder;
11226                }
11227            }
11228        }
11229
11230        return ret;
11231    }
11232
11233    public boolean stopServiceToken(ComponentName className, IBinder token,
11234            int startId) {
11235        synchronized(this) {
11236            if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
11237                    + " " + token + " startId=" + startId);
11238            ServiceRecord r = findServiceLocked(className, token);
11239            if (r != null) {
11240                if (startId >= 0) {
11241                    // Asked to only stop if done with all work.  Note that
11242                    // to avoid leaks, we will take this as dropping all
11243                    // start items up to and including this one.
11244                    ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11245                    if (si != null) {
11246                        while (r.deliveredStarts.size() > 0) {
11247                            ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
11248                            cur.removeUriPermissionsLocked();
11249                            if (cur == si) {
11250                                break;
11251                            }
11252                        }
11253                    }
11254
11255                    if (r.getLastStartId() != startId) {
11256                        return false;
11257                    }
11258
11259                    if (r.deliveredStarts.size() > 0) {
11260                        Slog.w(TAG, "stopServiceToken startId " + startId
11261                                + " is last, but have " + r.deliveredStarts.size()
11262                                + " remaining args");
11263                    }
11264                }
11265
11266                synchronized (r.stats.getBatteryStats()) {
11267                    r.stats.stopRunningLocked();
11268                    r.startRequested = false;
11269                    r.callStart = false;
11270                }
11271                final long origId = Binder.clearCallingIdentity();
11272                bringDownServiceLocked(r, false);
11273                Binder.restoreCallingIdentity(origId);
11274                return true;
11275            }
11276        }
11277        return false;
11278    }
11279
11280    public void setServiceForeground(ComponentName className, IBinder token,
11281            int id, Notification notification, boolean removeNotification) {
11282        final long origId = Binder.clearCallingIdentity();
11283        try {
11284        synchronized(this) {
11285            ServiceRecord r = findServiceLocked(className, token);
11286            if (r != null) {
11287                if (id != 0) {
11288                    if (notification == null) {
11289                        throw new IllegalArgumentException("null notification");
11290                    }
11291                    if (r.foregroundId != id) {
11292                        r.cancelNotification();
11293                        r.foregroundId = id;
11294                    }
11295                    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
11296                    r.foregroundNoti = notification;
11297                    r.isForeground = true;
11298                    r.postNotification();
11299                    if (r.app != null) {
11300                        updateServiceForegroundLocked(r.app, true);
11301                    }
11302                } else {
11303                    if (r.isForeground) {
11304                        r.isForeground = false;
11305                        if (r.app != null) {
11306                            updateLruProcessLocked(r.app, false, true);
11307                            updateServiceForegroundLocked(r.app, true);
11308                        }
11309                    }
11310                    if (removeNotification) {
11311                        r.cancelNotification();
11312                        r.foregroundId = 0;
11313                        r.foregroundNoti = null;
11314                    }
11315                }
11316            }
11317        }
11318        } finally {
11319            Binder.restoreCallingIdentity(origId);
11320        }
11321    }
11322
11323    public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
11324        boolean anyForeground = false;
11325        for (ServiceRecord sr : proc.services) {
11326            if (sr.isForeground) {
11327                anyForeground = true;
11328                break;
11329            }
11330        }
11331        if (anyForeground != proc.foregroundServices) {
11332            proc.foregroundServices = anyForeground;
11333            if (oomAdj) {
11334                updateOomAdjLocked();
11335            }
11336        }
11337    }
11338
11339    public int bindService(IApplicationThread caller, IBinder token,
11340            Intent service, String resolvedType,
11341            IServiceConnection connection, int flags) {
11342        // Refuse possible leaked file descriptors
11343        if (service != null && service.hasFileDescriptors() == true) {
11344            throw new IllegalArgumentException("File descriptors passed in Intent");
11345        }
11346
11347        synchronized(this) {
11348            if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
11349                    + " type=" + resolvedType + " conn=" + connection.asBinder()
11350                    + " flags=0x" + Integer.toHexString(flags));
11351            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11352            if (callerApp == null) {
11353                throw new SecurityException(
11354                        "Unable to find app for caller " + caller
11355                        + " (pid=" + Binder.getCallingPid()
11356                        + ") when binding service " + service);
11357            }
11358
11359            ActivityRecord activity = null;
11360            if (token != null) {
11361                activity = mMainStack.isInStackLocked(token);
11362                if (activity == null) {
11363                    Slog.w(TAG, "Binding with unknown activity: " + token);
11364                    return 0;
11365                }
11366            }
11367
11368            int clientLabel = 0;
11369            PendingIntent clientIntent = null;
11370
11371            if (callerApp.info.uid == Process.SYSTEM_UID) {
11372                // Hacky kind of thing -- allow system stuff to tell us
11373                // what they are, so we can report this elsewhere for
11374                // others to know why certain services are running.
11375                try {
11376                    clientIntent = (PendingIntent)service.getParcelableExtra(
11377                            Intent.EXTRA_CLIENT_INTENT);
11378                } catch (RuntimeException e) {
11379                }
11380                if (clientIntent != null) {
11381                    clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
11382                    if (clientLabel != 0) {
11383                        // There are no useful extras in the intent, trash them.
11384                        // System code calling with this stuff just needs to know
11385                        // this will happen.
11386                        service = service.cloneFilter();
11387                    }
11388                }
11389            }
11390
11391            ServiceLookupResult res =
11392                retrieveServiceLocked(service, resolvedType,
11393                        Binder.getCallingPid(), Binder.getCallingUid());
11394            if (res == null) {
11395                return 0;
11396            }
11397            if (res.record == null) {
11398                return -1;
11399            }
11400            ServiceRecord s = res.record;
11401
11402            final long origId = Binder.clearCallingIdentity();
11403
11404            if (unscheduleServiceRestartLocked(s)) {
11405                if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
11406                        + s);
11407            }
11408
11409            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
11410            ConnectionRecord c = new ConnectionRecord(b, activity,
11411                    connection, flags, clientLabel, clientIntent);
11412
11413            IBinder binder = connection.asBinder();
11414            ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11415            if (clist == null) {
11416                clist = new ArrayList<ConnectionRecord>();
11417                s.connections.put(binder, clist);
11418            }
11419            clist.add(c);
11420            b.connections.add(c);
11421            if (activity != null) {
11422                if (activity.connections == null) {
11423                    activity.connections = new HashSet<ConnectionRecord>();
11424                }
11425                activity.connections.add(c);
11426            }
11427            b.client.connections.add(c);
11428            if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11429                b.client.hasAboveClient = true;
11430            }
11431            clist = mServiceConnections.get(binder);
11432            if (clist == null) {
11433                clist = new ArrayList<ConnectionRecord>();
11434                mServiceConnections.put(binder, clist);
11435            }
11436            clist.add(c);
11437
11438            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
11439                s.lastActivity = SystemClock.uptimeMillis();
11440                if (!bringUpServiceLocked(s, service.getFlags(), false)) {
11441                    return 0;
11442                }
11443            }
11444
11445            if (s.app != null) {
11446                // This could have made the service more important.
11447                updateOomAdjLocked(s.app);
11448            }
11449
11450            if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
11451                    + ": received=" + b.intent.received
11452                    + " apps=" + b.intent.apps.size()
11453                    + " doRebind=" + b.intent.doRebind);
11454
11455            if (s.app != null && b.intent.received) {
11456                // Service is already running, so we can immediately
11457                // publish the connection.
11458                try {
11459                    c.conn.connected(s.name, b.intent.binder);
11460                } catch (Exception e) {
11461                    Slog.w(TAG, "Failure sending service " + s.shortName
11462                            + " to connection " + c.conn.asBinder()
11463                            + " (in " + c.binding.client.processName + ")", e);
11464                }
11465
11466                // If this is the first app connected back to this binding,
11467                // and the service had previously asked to be told when
11468                // rebound, then do so.
11469                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
11470                    requestServiceBindingLocked(s, b.intent, true);
11471                }
11472            } else if (!b.intent.requested) {
11473                requestServiceBindingLocked(s, b.intent, false);
11474            }
11475
11476            Binder.restoreCallingIdentity(origId);
11477        }
11478
11479        return 1;
11480    }
11481
11482    void removeConnectionLocked(
11483        ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
11484        IBinder binder = c.conn.asBinder();
11485        AppBindRecord b = c.binding;
11486        ServiceRecord s = b.service;
11487        ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11488        if (clist != null) {
11489            clist.remove(c);
11490            if (clist.size() == 0) {
11491                s.connections.remove(binder);
11492            }
11493        }
11494        b.connections.remove(c);
11495        if (c.activity != null && c.activity != skipAct) {
11496            if (c.activity.connections != null) {
11497                c.activity.connections.remove(c);
11498            }
11499        }
11500        if (b.client != skipApp) {
11501            b.client.connections.remove(c);
11502            if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11503                b.client.updateHasAboveClientLocked();
11504            }
11505        }
11506        clist = mServiceConnections.get(binder);
11507        if (clist != null) {
11508            clist.remove(c);
11509            if (clist.size() == 0) {
11510                mServiceConnections.remove(binder);
11511            }
11512        }
11513
11514        if (b.connections.size() == 0) {
11515            b.intent.apps.remove(b.client);
11516        }
11517
11518        if (!c.serviceDead) {
11519            if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
11520                    + ": shouldUnbind=" + b.intent.hasBound);
11521            if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
11522                    && b.intent.hasBound) {
11523                try {
11524                    bumpServiceExecutingLocked(s, "unbind");
11525                    updateOomAdjLocked(s.app);
11526                    b.intent.hasBound = false;
11527                    // Assume the client doesn't want to know about a rebind;
11528                    // we will deal with that later if it asks for one.
11529                    b.intent.doRebind = false;
11530                    s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
11531                } catch (Exception e) {
11532                    Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
11533                    serviceDoneExecutingLocked(s, true);
11534                }
11535            }
11536
11537            if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
11538                bringDownServiceLocked(s, false);
11539            }
11540        }
11541    }
11542
11543    public boolean unbindService(IServiceConnection connection) {
11544        synchronized (this) {
11545            IBinder binder = connection.asBinder();
11546            if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
11547            ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
11548            if (clist == null) {
11549                Slog.w(TAG, "Unbind failed: could not find connection for "
11550                      + connection.asBinder());
11551                return false;
11552            }
11553
11554            final long origId = Binder.clearCallingIdentity();
11555
11556            while (clist.size() > 0) {
11557                ConnectionRecord r = clist.get(0);
11558                removeConnectionLocked(r, null, null);
11559
11560                if (r.binding.service.app != null) {
11561                    // This could have made the service less important.
11562                    updateOomAdjLocked(r.binding.service.app);
11563                }
11564            }
11565
11566            Binder.restoreCallingIdentity(origId);
11567        }
11568
11569        return true;
11570    }
11571
11572    public void publishService(IBinder token, Intent intent, IBinder service) {
11573        // Refuse possible leaked file descriptors
11574        if (intent != null && intent.hasFileDescriptors() == true) {
11575            throw new IllegalArgumentException("File descriptors passed in Intent");
11576        }
11577
11578        synchronized(this) {
11579            if (!(token instanceof ServiceRecord)) {
11580                throw new IllegalArgumentException("Invalid service token");
11581            }
11582            ServiceRecord r = (ServiceRecord)token;
11583
11584            final long origId = Binder.clearCallingIdentity();
11585
11586            if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
11587                    + " " + intent + ": " + service);
11588            if (r != null) {
11589                Intent.FilterComparison filter
11590                        = new Intent.FilterComparison(intent);
11591                IntentBindRecord b = r.bindings.get(filter);
11592                if (b != null && !b.received) {
11593                    b.binder = service;
11594                    b.requested = true;
11595                    b.received = true;
11596                    if (r.connections.size() > 0) {
11597                        Iterator<ArrayList<ConnectionRecord>> it
11598                                = r.connections.values().iterator();
11599                        while (it.hasNext()) {
11600                            ArrayList<ConnectionRecord> clist = it.next();
11601                            for (int i=0; i<clist.size(); i++) {
11602                                ConnectionRecord c = clist.get(i);
11603                                if (!filter.equals(c.binding.intent.intent)) {
11604                                    if (DEBUG_SERVICE) Slog.v(
11605                                            TAG, "Not publishing to: " + c);
11606                                    if (DEBUG_SERVICE) Slog.v(
11607                                            TAG, "Bound intent: " + c.binding.intent.intent);
11608                                    if (DEBUG_SERVICE) Slog.v(
11609                                            TAG, "Published intent: " + intent);
11610                                    continue;
11611                                }
11612                                if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
11613                                try {
11614                                    c.conn.connected(r.name, service);
11615                                } catch (Exception e) {
11616                                    Slog.w(TAG, "Failure sending service " + r.name +
11617                                          " to connection " + c.conn.asBinder() +
11618                                          " (in " + c.binding.client.processName + ")", e);
11619                                }
11620                            }
11621                        }
11622                    }
11623                }
11624
11625                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11626
11627                Binder.restoreCallingIdentity(origId);
11628            }
11629        }
11630    }
11631
11632    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11633        // Refuse possible leaked file descriptors
11634        if (intent != null && intent.hasFileDescriptors() == true) {
11635            throw new IllegalArgumentException("File descriptors passed in Intent");
11636        }
11637
11638        synchronized(this) {
11639            if (!(token instanceof ServiceRecord)) {
11640                throw new IllegalArgumentException("Invalid service token");
11641            }
11642            ServiceRecord r = (ServiceRecord)token;
11643
11644            final long origId = Binder.clearCallingIdentity();
11645
11646            if (r != null) {
11647                Intent.FilterComparison filter
11648                        = new Intent.FilterComparison(intent);
11649                IntentBindRecord b = r.bindings.get(filter);
11650                if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
11651                        + " at " + b + ": apps="
11652                        + (b != null ? b.apps.size() : 0));
11653
11654                boolean inStopping = mStoppingServices.contains(r);
11655                if (b != null) {
11656                    if (b.apps.size() > 0 && !inStopping) {
11657                        // Applications have already bound since the last
11658                        // unbind, so just rebind right here.
11659                        requestServiceBindingLocked(r, b, true);
11660                    } else {
11661                        // Note to tell the service the next time there is
11662                        // a new client.
11663                        b.doRebind = true;
11664                    }
11665                }
11666
11667                serviceDoneExecutingLocked(r, inStopping);
11668
11669                Binder.restoreCallingIdentity(origId);
11670            }
11671        }
11672    }
11673
11674    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11675        synchronized(this) {
11676            if (!(token instanceof ServiceRecord)) {
11677                throw new IllegalArgumentException("Invalid service token");
11678            }
11679            ServiceRecord r = (ServiceRecord)token;
11680            boolean inStopping = mStoppingServices.contains(token);
11681            if (r != null) {
11682                if (r != token) {
11683                    Slog.w(TAG, "Done executing service " + r.name
11684                          + " with incorrect token: given " + token
11685                          + ", expected " + r);
11686                    return;
11687                }
11688
11689                if (type == 1) {
11690                    // This is a call from a service start...  take care of
11691                    // book-keeping.
11692                    r.callStart = true;
11693                    switch (res) {
11694                        case Service.START_STICKY_COMPATIBILITY:
11695                        case Service.START_STICKY: {
11696                            // We are done with the associated start arguments.
11697                            r.findDeliveredStart(startId, true);
11698                            // Don't stop if killed.
11699                            r.stopIfKilled = false;
11700                            break;
11701                        }
11702                        case Service.START_NOT_STICKY: {
11703                            // We are done with the associated start arguments.
11704                            r.findDeliveredStart(startId, true);
11705                            if (r.getLastStartId() == startId) {
11706                                // There is no more work, and this service
11707                                // doesn't want to hang around if killed.
11708                                r.stopIfKilled = true;
11709                            }
11710                            break;
11711                        }
11712                        case Service.START_REDELIVER_INTENT: {
11713                            // We'll keep this item until they explicitly
11714                            // call stop for it, but keep track of the fact
11715                            // that it was delivered.
11716                            ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11717                            if (si != null) {
11718                                si.deliveryCount = 0;
11719                                si.doneExecutingCount++;
11720                                // Don't stop if killed.
11721                                r.stopIfKilled = true;
11722                            }
11723                            break;
11724                        }
11725                        case Service.START_TASK_REMOVED_COMPLETE: {
11726                            // Special processing for onTaskRemoved().  Don't
11727                            // impact normal onStartCommand() processing.
11728                            r.findDeliveredStart(startId, true);
11729                            break;
11730                        }
11731                        default:
11732                            throw new IllegalArgumentException(
11733                                    "Unknown service start result: " + res);
11734                    }
11735                    if (res == Service.START_STICKY_COMPATIBILITY) {
11736                        r.callStart = false;
11737                    }
11738                }
11739
11740                final long origId = Binder.clearCallingIdentity();
11741                serviceDoneExecutingLocked(r, inStopping);
11742                Binder.restoreCallingIdentity(origId);
11743            } else {
11744                Slog.w(TAG, "Done executing unknown service from pid "
11745                        + Binder.getCallingPid());
11746            }
11747        }
11748    }
11749
11750    public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
11751        if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
11752                + ": nesting=" + r.executeNesting
11753                + ", inStopping=" + inStopping + ", app=" + r.app);
11754        else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
11755        r.executeNesting--;
11756        if (r.executeNesting <= 0 && r.app != null) {
11757            if (DEBUG_SERVICE) Slog.v(TAG,
11758                    "Nesting at 0 of " + r.shortName);
11759            r.app.executingServices.remove(r);
11760            if (r.app.executingServices.size() == 0) {
11761                if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
11762                        "No more executingServices of " + r.shortName);
11763                mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11764            }
11765            if (inStopping) {
11766                if (DEBUG_SERVICE) Slog.v(TAG,
11767                        "doneExecuting remove stopping " + r);
11768                mStoppingServices.remove(r);
11769                r.bindings.clear();
11770            }
11771            updateOomAdjLocked(r.app);
11772        }
11773    }
11774
11775    void serviceTimeout(ProcessRecord proc) {
11776        String anrMessage = null;
11777
11778        synchronized(this) {
11779            if (proc.executingServices.size() == 0 || proc.thread == null) {
11780                return;
11781            }
11782            long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11783            Iterator<ServiceRecord> it = proc.executingServices.iterator();
11784            ServiceRecord timeout = null;
11785            long nextTime = 0;
11786            while (it.hasNext()) {
11787                ServiceRecord sr = it.next();
11788                if (sr.executingStart < maxTime) {
11789                    timeout = sr;
11790                    break;
11791                }
11792                if (sr.executingStart > nextTime) {
11793                    nextTime = sr.executingStart;
11794                }
11795            }
11796            if (timeout != null && mLruProcesses.contains(proc)) {
11797                Slog.w(TAG, "Timeout executing service: " + timeout);
11798                anrMessage = "Executing service " + timeout.shortName;
11799            } else {
11800                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11801                msg.obj = proc;
11802                mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11803            }
11804        }
11805
11806        if (anrMessage != null) {
11807            appNotResponding(proc, null, null, anrMessage);
11808        }
11809    }
11810
11811    // =========================================================
11812    // BACKUP AND RESTORE
11813    // =========================================================
11814
11815    // Cause the target app to be launched if necessary and its backup agent
11816    // instantiated.  The backup agent will invoke backupAgentCreated() on the
11817    // activity manager to announce its creation.
11818    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11819        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
11820        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11821
11822        synchronized(this) {
11823            // !!! TODO: currently no check here that we're already bound
11824            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11825            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11826            synchronized (stats) {
11827                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11828            }
11829
11830            // Backup agent is now in use, its package can't be stopped.
11831            try {
11832                AppGlobals.getPackageManager().setPackageStoppedState(
11833                        app.packageName, false);
11834            } catch (RemoteException e) {
11835            } catch (IllegalArgumentException e) {
11836                Slog.w(TAG, "Failed trying to unstop package "
11837                        + app.packageName + ": " + e);
11838            }
11839
11840            BackupRecord r = new BackupRecord(ss, app, backupMode);
11841            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11842                    ? new ComponentName(app.packageName, app.backupAgentName)
11843                    : new ComponentName("android", "FullBackupAgent");
11844            // startProcessLocked() returns existing proc's record if it's already running
11845            ProcessRecord proc = startProcessLocked(app.processName, app,
11846                    false, 0, "backup", hostingName, false);
11847            if (proc == null) {
11848                Slog.e(TAG, "Unable to start backup agent process " + r);
11849                return false;
11850            }
11851
11852            r.app = proc;
11853            mBackupTarget = r;
11854            mBackupAppName = app.packageName;
11855
11856            // Try not to kill the process during backup
11857            updateOomAdjLocked(proc);
11858
11859            // If the process is already attached, schedule the creation of the backup agent now.
11860            // If it is not yet live, this will be done when it attaches to the framework.
11861            if (proc.thread != null) {
11862                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11863                try {
11864                    proc.thread.scheduleCreateBackupAgent(app,
11865                            compatibilityInfoForPackageLocked(app), backupMode);
11866                } catch (RemoteException e) {
11867                    // Will time out on the backup manager side
11868                }
11869            } else {
11870                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11871            }
11872            // Invariants: at this point, the target app process exists and the application
11873            // is either already running or in the process of coming up.  mBackupTarget and
11874            // mBackupAppName describe the app, so that when it binds back to the AM we
11875            // know that it's scheduled for a backup-agent operation.
11876        }
11877
11878        return true;
11879    }
11880
11881    // A backup agent has just come up
11882    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11883        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11884                + " = " + agent);
11885
11886        synchronized(this) {
11887            if (!agentPackageName.equals(mBackupAppName)) {
11888                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11889                return;
11890            }
11891        }
11892
11893        long oldIdent = Binder.clearCallingIdentity();
11894        try {
11895            IBackupManager bm = IBackupManager.Stub.asInterface(
11896                    ServiceManager.getService(Context.BACKUP_SERVICE));
11897            bm.agentConnected(agentPackageName, agent);
11898        } catch (RemoteException e) {
11899            // can't happen; the backup manager service is local
11900        } catch (Exception e) {
11901            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11902            e.printStackTrace();
11903        } finally {
11904            Binder.restoreCallingIdentity(oldIdent);
11905        }
11906    }
11907
11908    // done with this agent
11909    public void unbindBackupAgent(ApplicationInfo appInfo) {
11910        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11911        if (appInfo == null) {
11912            Slog.w(TAG, "unbind backup agent for null app");
11913            return;
11914        }
11915
11916        synchronized(this) {
11917            if (mBackupAppName == null) {
11918                Slog.w(TAG, "Unbinding backup agent with no active backup");
11919                return;
11920            }
11921
11922            if (!mBackupAppName.equals(appInfo.packageName)) {
11923                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11924                return;
11925            }
11926
11927            ProcessRecord proc = mBackupTarget.app;
11928            mBackupTarget = null;
11929            mBackupAppName = null;
11930
11931            // Not backing this app up any more; reset its OOM adjustment
11932            updateOomAdjLocked(proc);
11933
11934            // If the app crashed during backup, 'thread' will be null here
11935            if (proc.thread != null) {
11936                try {
11937                    proc.thread.scheduleDestroyBackupAgent(appInfo,
11938                            compatibilityInfoForPackageLocked(appInfo));
11939                } catch (Exception e) {
11940                    Slog.e(TAG, "Exception when unbinding backup agent:");
11941                    e.printStackTrace();
11942                }
11943            }
11944        }
11945    }
11946    // =========================================================
11947    // BROADCASTS
11948    // =========================================================
11949
11950    private final List getStickiesLocked(String action, IntentFilter filter,
11951            List cur) {
11952        final ContentResolver resolver = mContext.getContentResolver();
11953        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11954        if (list == null) {
11955            return cur;
11956        }
11957        int N = list.size();
11958        for (int i=0; i<N; i++) {
11959            Intent intent = list.get(i);
11960            if (filter.match(resolver, intent, true, TAG) >= 0) {
11961                if (cur == null) {
11962                    cur = new ArrayList<Intent>();
11963                }
11964                cur.add(intent);
11965            }
11966        }
11967        return cur;
11968    }
11969
11970    private final void scheduleBroadcastsLocked() {
11971        if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
11972                + mBroadcastsScheduled);
11973
11974        if (mBroadcastsScheduled) {
11975            return;
11976        }
11977        mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11978        mBroadcastsScheduled = true;
11979    }
11980
11981    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11982            IIntentReceiver receiver, IntentFilter filter, String permission) {
11983        synchronized(this) {
11984            ProcessRecord callerApp = null;
11985            if (caller != null) {
11986                callerApp = getRecordForAppLocked(caller);
11987                if (callerApp == null) {
11988                    throw new SecurityException(
11989                            "Unable to find app for caller " + caller
11990                            + " (pid=" + Binder.getCallingPid()
11991                            + ") when registering receiver " + receiver);
11992                }
11993                if (callerApp.info.uid != Process.SYSTEM_UID &&
11994                        !callerApp.pkgList.contains(callerPackage)) {
11995                    throw new SecurityException("Given caller package " + callerPackage
11996                            + " is not running in process " + callerApp);
11997                }
11998            } else {
11999                callerPackage = null;
12000            }
12001
12002            List allSticky = null;
12003
12004            // Look for any matching sticky broadcasts...
12005            Iterator actions = filter.actionsIterator();
12006            if (actions != null) {
12007                while (actions.hasNext()) {
12008                    String action = (String)actions.next();
12009                    allSticky = getStickiesLocked(action, filter, allSticky);
12010                }
12011            } else {
12012                allSticky = getStickiesLocked(null, filter, allSticky);
12013            }
12014
12015            // The first sticky in the list is returned directly back to
12016            // the client.
12017            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12018
12019            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
12020                    + ": " + sticky);
12021
12022            if (receiver == null) {
12023                return sticky;
12024            }
12025
12026            ReceiverList rl
12027                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12028            if (rl == null) {
12029                rl = new ReceiverList(this, callerApp,
12030                        Binder.getCallingPid(),
12031                        Binder.getCallingUid(), receiver);
12032                if (rl.app != null) {
12033                    rl.app.receivers.add(rl);
12034                } else {
12035                    try {
12036                        receiver.asBinder().linkToDeath(rl, 0);
12037                    } catch (RemoteException e) {
12038                        return sticky;
12039                    }
12040                    rl.linkedToDeath = true;
12041                }
12042                mRegisteredReceivers.put(receiver.asBinder(), rl);
12043            }
12044            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
12045            rl.add(bf);
12046            if (!bf.debugCheck()) {
12047                Slog.w(TAG, "==> For Dynamic broadast");
12048            }
12049            mReceiverResolver.addFilter(bf);
12050
12051            // Enqueue broadcasts for all existing stickies that match
12052            // this filter.
12053            if (allSticky != null) {
12054                ArrayList receivers = new ArrayList();
12055                receivers.add(bf);
12056
12057                int N = allSticky.size();
12058                for (int i=0; i<N; i++) {
12059                    Intent intent = (Intent)allSticky.get(i);
12060                    BroadcastRecord r = new BroadcastRecord(intent, null,
12061                            null, -1, -1, null, receivers, null, 0, null, null,
12062                            false, true, true);
12063                    if (mParallelBroadcasts.size() == 0) {
12064                        scheduleBroadcastsLocked();
12065                    }
12066                    mParallelBroadcasts.add(r);
12067                }
12068            }
12069
12070            return sticky;
12071        }
12072    }
12073
12074    public void unregisterReceiver(IIntentReceiver receiver) {
12075        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
12076
12077        boolean doNext = false;
12078
12079        synchronized(this) {
12080            ReceiverList rl
12081                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12082            if (rl != null) {
12083                if (rl.curBroadcast != null) {
12084                    BroadcastRecord r = rl.curBroadcast;
12085                    doNext = finishReceiverLocked(
12086                        receiver.asBinder(), r.resultCode, r.resultData,
12087                        r.resultExtras, r.resultAbort, true);
12088                }
12089
12090                if (rl.app != null) {
12091                    rl.app.receivers.remove(rl);
12092                }
12093                removeReceiverLocked(rl);
12094                if (rl.linkedToDeath) {
12095                    rl.linkedToDeath = false;
12096                    rl.receiver.asBinder().unlinkToDeath(rl, 0);
12097                }
12098            }
12099        }
12100
12101        if (!doNext) {
12102            return;
12103        }
12104
12105        final long origId = Binder.clearCallingIdentity();
12106        processNextBroadcast(false);
12107        trimApplications();
12108        Binder.restoreCallingIdentity(origId);
12109    }
12110
12111    void removeReceiverLocked(ReceiverList rl) {
12112        mRegisteredReceivers.remove(rl.receiver.asBinder());
12113        int N = rl.size();
12114        for (int i=0; i<N; i++) {
12115            mReceiverResolver.removeFilter(rl.get(i));
12116        }
12117    }
12118
12119    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
12120        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12121            ProcessRecord r = mLruProcesses.get(i);
12122            if (r.thread != null) {
12123                try {
12124                    r.thread.dispatchPackageBroadcast(cmd, packages);
12125                } catch (RemoteException ex) {
12126                }
12127            }
12128        }
12129    }
12130
12131    private final int broadcastIntentLocked(ProcessRecord callerApp,
12132            String callerPackage, Intent intent, String resolvedType,
12133            IIntentReceiver resultTo, int resultCode, String resultData,
12134            Bundle map, String requiredPermission,
12135            boolean ordered, boolean sticky, int callingPid, int callingUid) {
12136        intent = new Intent(intent);
12137
12138        // By default broadcasts do not go to stopped apps.
12139        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
12140
12141        if (DEBUG_BROADCAST_LIGHT) Slog.v(
12142            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
12143            + " ordered=" + ordered);
12144        if ((resultTo != null) && !ordered) {
12145            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
12146        }
12147
12148        // Handle special intents: if this broadcast is from the package
12149        // manager about a package being removed, we need to remove all of
12150        // its activities from the history stack.
12151        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
12152                intent.getAction());
12153        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
12154                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
12155                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
12156                || uidRemoved) {
12157            if (checkComponentPermission(
12158                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
12159                    callingPid, callingUid, -1, true)
12160                    == PackageManager.PERMISSION_GRANTED) {
12161                if (uidRemoved) {
12162                    final Bundle intentExtras = intent.getExtras();
12163                    final int uid = intentExtras != null
12164                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
12165                    if (uid >= 0) {
12166                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
12167                        synchronized (bs) {
12168                            bs.removeUidStatsLocked(uid);
12169                        }
12170                    }
12171                } else {
12172                    // If resources are unvailble just force stop all
12173                    // those packages and flush the attribute cache as well.
12174                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
12175                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
12176                        if (list != null && (list.length > 0)) {
12177                            for (String pkg : list) {
12178                                forceStopPackageLocked(pkg, -1, false, true, true, false);
12179                            }
12180                            sendPackageBroadcastLocked(
12181                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
12182                        }
12183                    } else {
12184                        Uri data = intent.getData();
12185                        String ssp;
12186                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12187                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
12188                                forceStopPackageLocked(ssp,
12189                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
12190                            }
12191                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
12192                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
12193                                        new String[] {ssp});
12194                            }
12195                        }
12196                    }
12197                }
12198            } else {
12199                String msg = "Permission Denial: " + intent.getAction()
12200                        + " broadcast from " + callerPackage + " (pid=" + callingPid
12201                        + ", uid=" + callingUid + ")"
12202                        + " requires "
12203                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
12204                Slog.w(TAG, msg);
12205                throw new SecurityException(msg);
12206            }
12207
12208        // Special case for adding a package: by default turn on compatibility
12209        // mode.
12210        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
12211            Uri data = intent.getData();
12212            String ssp;
12213            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12214                mCompatModePackages.handlePackageAddedLocked(ssp,
12215                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
12216            }
12217        }
12218
12219        /*
12220         * If this is the time zone changed action, queue up a message that will reset the timezone
12221         * of all currently running processes. This message will get queued up before the broadcast
12222         * happens.
12223         */
12224        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
12225            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
12226        }
12227
12228        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
12229            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
12230        }
12231
12232        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
12233            ProxyProperties proxy = intent.getParcelableExtra("proxy");
12234            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
12235        }
12236
12237        /*
12238         * Prevent non-system code (defined here to be non-persistent
12239         * processes) from sending protected broadcasts.
12240         */
12241        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
12242                || callingUid == Process.SHELL_UID || callingUid == 0) {
12243            // Always okay.
12244        } else if (callerApp == null || !callerApp.persistent) {
12245            try {
12246                if (AppGlobals.getPackageManager().isProtectedBroadcast(
12247                        intent.getAction())) {
12248                    String msg = "Permission Denial: not allowed to send broadcast "
12249                            + intent.getAction() + " from pid="
12250                            + callingPid + ", uid=" + callingUid;
12251                    Slog.w(TAG, msg);
12252                    throw new SecurityException(msg);
12253                }
12254            } catch (RemoteException e) {
12255                Slog.w(TAG, "Remote exception", e);
12256                return BROADCAST_SUCCESS;
12257            }
12258        }
12259
12260        // Add to the sticky list if requested.
12261        if (sticky) {
12262            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
12263                    callingPid, callingUid)
12264                    != PackageManager.PERMISSION_GRANTED) {
12265                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
12266                        + callingPid + ", uid=" + callingUid
12267                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12268                Slog.w(TAG, msg);
12269                throw new SecurityException(msg);
12270            }
12271            if (requiredPermission != null) {
12272                Slog.w(TAG, "Can't broadcast sticky intent " + intent
12273                        + " and enforce permission " + requiredPermission);
12274                return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
12275            }
12276            if (intent.getComponent() != null) {
12277                throw new SecurityException(
12278                        "Sticky broadcasts can't target a specific component");
12279            }
12280            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12281            if (list == null) {
12282                list = new ArrayList<Intent>();
12283                mStickyBroadcasts.put(intent.getAction(), list);
12284            }
12285            int N = list.size();
12286            int i;
12287            for (i=0; i<N; i++) {
12288                if (intent.filterEquals(list.get(i))) {
12289                    // This sticky already exists, replace it.
12290                    list.set(i, new Intent(intent));
12291                    break;
12292                }
12293            }
12294            if (i >= N) {
12295                list.add(new Intent(intent));
12296            }
12297        }
12298
12299        // Figure out who all will receive this broadcast.
12300        List receivers = null;
12301        List<BroadcastFilter> registeredReceivers = null;
12302        try {
12303            if (intent.getComponent() != null) {
12304                // Broadcast is going to one specific receiver class...
12305                ActivityInfo ai = AppGlobals.getPackageManager().
12306                    getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
12307                if (ai != null) {
12308                    receivers = new ArrayList();
12309                    ResolveInfo ri = new ResolveInfo();
12310                    ri.activityInfo = ai;
12311                    receivers.add(ri);
12312                }
12313            } else {
12314                // Need to resolve the intent to interested receivers...
12315                if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
12316                         == 0) {
12317                    receivers =
12318                        AppGlobals.getPackageManager().queryIntentReceivers(
12319                                intent, resolvedType, STOCK_PM_FLAGS);
12320                }
12321                registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
12322            }
12323        } catch (RemoteException ex) {
12324            // pm is in same process, this will never happen.
12325        }
12326
12327        final boolean replacePending =
12328                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
12329
12330        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
12331                + " replacePending=" + replacePending);
12332
12333        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
12334        if (!ordered && NR > 0) {
12335            // If we are not serializing this broadcast, then send the
12336            // registered receivers separately so they don't wait for the
12337            // components to be launched.
12338            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12339                    callerPackage, callingPid, callingUid, requiredPermission,
12340                    registeredReceivers, resultTo, resultCode, resultData, map,
12341                    ordered, sticky, false);
12342            if (DEBUG_BROADCAST) Slog.v(
12343                    TAG, "Enqueueing parallel broadcast " + r
12344                    + ": prev had " + mParallelBroadcasts.size());
12345            boolean replaced = false;
12346            if (replacePending) {
12347                for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
12348                    if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
12349                        if (DEBUG_BROADCAST) Slog.v(TAG,
12350                                "***** DROPPING PARALLEL: " + intent);
12351                        mParallelBroadcasts.set(i, r);
12352                        replaced = true;
12353                        break;
12354                    }
12355                }
12356            }
12357            if (!replaced) {
12358                mParallelBroadcasts.add(r);
12359                scheduleBroadcastsLocked();
12360            }
12361            registeredReceivers = null;
12362            NR = 0;
12363        }
12364
12365        // Merge into one list.
12366        int ir = 0;
12367        if (receivers != null) {
12368            // A special case for PACKAGE_ADDED: do not allow the package
12369            // being added to see this broadcast.  This prevents them from
12370            // using this as a back door to get run as soon as they are
12371            // installed.  Maybe in the future we want to have a special install
12372            // broadcast or such for apps, but we'd like to deliberately make
12373            // this decision.
12374            String skipPackages[] = null;
12375            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
12376                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
12377                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
12378                Uri data = intent.getData();
12379                if (data != null) {
12380                    String pkgName = data.getSchemeSpecificPart();
12381                    if (pkgName != null) {
12382                        skipPackages = new String[] { pkgName };
12383                    }
12384                }
12385            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
12386                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
12387            }
12388            if (skipPackages != null && (skipPackages.length > 0)) {
12389                for (String skipPackage : skipPackages) {
12390                    if (skipPackage != null) {
12391                        int NT = receivers.size();
12392                        for (int it=0; it<NT; it++) {
12393                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
12394                            if (curt.activityInfo.packageName.equals(skipPackage)) {
12395                                receivers.remove(it);
12396                                it--;
12397                                NT--;
12398                            }
12399                        }
12400                    }
12401                }
12402            }
12403
12404            int NT = receivers != null ? receivers.size() : 0;
12405            int it = 0;
12406            ResolveInfo curt = null;
12407            BroadcastFilter curr = null;
12408            while (it < NT && ir < NR) {
12409                if (curt == null) {
12410                    curt = (ResolveInfo)receivers.get(it);
12411                }
12412                if (curr == null) {
12413                    curr = registeredReceivers.get(ir);
12414                }
12415                if (curr.getPriority() >= curt.priority) {
12416                    // Insert this broadcast record into the final list.
12417                    receivers.add(it, curr);
12418                    ir++;
12419                    curr = null;
12420                    it++;
12421                    NT++;
12422                } else {
12423                    // Skip to the next ResolveInfo in the final list.
12424                    it++;
12425                    curt = null;
12426                }
12427            }
12428        }
12429        while (ir < NR) {
12430            if (receivers == null) {
12431                receivers = new ArrayList();
12432            }
12433            receivers.add(registeredReceivers.get(ir));
12434            ir++;
12435        }
12436
12437        if ((receivers != null && receivers.size() > 0)
12438                || resultTo != null) {
12439            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12440                    callerPackage, callingPid, callingUid, requiredPermission,
12441                    receivers, resultTo, resultCode, resultData, map, ordered,
12442                    sticky, false);
12443            if (DEBUG_BROADCAST) Slog.v(
12444                    TAG, "Enqueueing ordered broadcast " + r
12445                    + ": prev had " + mOrderedBroadcasts.size());
12446            if (DEBUG_BROADCAST) {
12447                int seq = r.intent.getIntExtra("seq", -1);
12448                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
12449            }
12450            boolean replaced = false;
12451            if (replacePending) {
12452                for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
12453                    if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
12454                        if (DEBUG_BROADCAST) Slog.v(TAG,
12455                                "***** DROPPING ORDERED: " + intent);
12456                        mOrderedBroadcasts.set(i, r);
12457                        replaced = true;
12458                        break;
12459                    }
12460                }
12461            }
12462            if (!replaced) {
12463                mOrderedBroadcasts.add(r);
12464                scheduleBroadcastsLocked();
12465            }
12466        }
12467
12468        return BROADCAST_SUCCESS;
12469    }
12470
12471    final Intent verifyBroadcastLocked(Intent intent) {
12472        // Refuse possible leaked file descriptors
12473        if (intent != null && intent.hasFileDescriptors() == true) {
12474            throw new IllegalArgumentException("File descriptors passed in Intent");
12475        }
12476
12477        int flags = intent.getFlags();
12478
12479        if (!mProcessesReady) {
12480            // if the caller really truly claims to know what they're doing, go
12481            // ahead and allow the broadcast without launching any receivers
12482            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
12483                intent = new Intent(intent);
12484                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12485            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
12486                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
12487                        + " before boot completion");
12488                throw new IllegalStateException("Cannot broadcast before boot completed");
12489            }
12490        }
12491
12492        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
12493            throw new IllegalArgumentException(
12494                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
12495        }
12496
12497        return intent;
12498    }
12499
12500    public final int broadcastIntent(IApplicationThread caller,
12501            Intent intent, String resolvedType, IIntentReceiver resultTo,
12502            int resultCode, String resultData, Bundle map,
12503            String requiredPermission, boolean serialized, boolean sticky) {
12504        synchronized(this) {
12505            intent = verifyBroadcastLocked(intent);
12506
12507            final ProcessRecord callerApp = getRecordForAppLocked(caller);
12508            final int callingPid = Binder.getCallingPid();
12509            final int callingUid = Binder.getCallingUid();
12510            final long origId = Binder.clearCallingIdentity();
12511            int res = broadcastIntentLocked(callerApp,
12512                    callerApp != null ? callerApp.info.packageName : null,
12513                    intent, resolvedType, resultTo,
12514                    resultCode, resultData, map, requiredPermission, serialized,
12515                    sticky, callingPid, callingUid);
12516            Binder.restoreCallingIdentity(origId);
12517            return res;
12518        }
12519    }
12520
12521    int broadcastIntentInPackage(String packageName, int uid,
12522            Intent intent, String resolvedType, IIntentReceiver resultTo,
12523            int resultCode, String resultData, Bundle map,
12524            String requiredPermission, boolean serialized, boolean sticky) {
12525        synchronized(this) {
12526            intent = verifyBroadcastLocked(intent);
12527
12528            final long origId = Binder.clearCallingIdentity();
12529            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
12530                    resultTo, resultCode, resultData, map, requiredPermission,
12531                    serialized, sticky, -1, uid);
12532            Binder.restoreCallingIdentity(origId);
12533            return res;
12534        }
12535    }
12536
12537    public final void unbroadcastIntent(IApplicationThread caller,
12538            Intent intent) {
12539        // Refuse possible leaked file descriptors
12540        if (intent != null && intent.hasFileDescriptors() == true) {
12541            throw new IllegalArgumentException("File descriptors passed in Intent");
12542        }
12543
12544        synchronized(this) {
12545            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12546                    != PackageManager.PERMISSION_GRANTED) {
12547                String msg = "Permission Denial: unbroadcastIntent() from pid="
12548                        + Binder.getCallingPid()
12549                        + ", uid=" + Binder.getCallingUid()
12550                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12551                Slog.w(TAG, msg);
12552                throw new SecurityException(msg);
12553            }
12554            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12555            if (list != null) {
12556                int N = list.size();
12557                int i;
12558                for (i=0; i<N; i++) {
12559                    if (intent.filterEquals(list.get(i))) {
12560                        list.remove(i);
12561                        break;
12562                    }
12563                }
12564            }
12565        }
12566    }
12567
12568    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12569            String resultData, Bundle resultExtras, boolean resultAbort,
12570            boolean explicit) {
12571        if (mOrderedBroadcasts.size() == 0) {
12572            if (explicit) {
12573                Slog.w(TAG, "finishReceiver called but no pending broadcasts");
12574            }
12575            return false;
12576        }
12577        BroadcastRecord r = mOrderedBroadcasts.get(0);
12578        if (r.receiver == null) {
12579            if (explicit) {
12580                Slog.w(TAG, "finishReceiver called but none active");
12581            }
12582            return false;
12583        }
12584        if (r.receiver != receiver) {
12585            Slog.w(TAG, "finishReceiver called but active receiver is different");
12586            return false;
12587        }
12588        int state = r.state;
12589        r.state = BroadcastRecord.IDLE;
12590        if (state == BroadcastRecord.IDLE) {
12591            if (explicit) {
12592                Slog.w(TAG, "finishReceiver called but state is IDLE");
12593            }
12594        }
12595        r.receiver = null;
12596        r.intent.setComponent(null);
12597        if (r.curApp != null) {
12598            r.curApp.curReceiver = null;
12599        }
12600        if (r.curFilter != null) {
12601            r.curFilter.receiverList.curBroadcast = null;
12602        }
12603        r.curFilter = null;
12604        r.curApp = null;
12605        r.curComponent = null;
12606        r.curReceiver = null;
12607        mPendingBroadcast = null;
12608
12609        r.resultCode = resultCode;
12610        r.resultData = resultData;
12611        r.resultExtras = resultExtras;
12612        r.resultAbort = resultAbort;
12613
12614        // We will process the next receiver right now if this is finishing
12615        // an app receiver (which is always asynchronous) or after we have
12616        // come back from calling a receiver.
12617        return state == BroadcastRecord.APP_RECEIVE
12618                || state == BroadcastRecord.CALL_DONE_RECEIVE;
12619    }
12620
12621    public void finishReceiver(IBinder who, int resultCode, String resultData,
12622            Bundle resultExtras, boolean resultAbort) {
12623        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
12624
12625        // Refuse possible leaked file descriptors
12626        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12627            throw new IllegalArgumentException("File descriptors passed in Bundle");
12628        }
12629
12630        boolean doNext;
12631
12632        final long origId = Binder.clearCallingIdentity();
12633
12634        synchronized(this) {
12635            doNext = finishReceiverLocked(
12636                who, resultCode, resultData, resultExtras, resultAbort, true);
12637        }
12638
12639        if (doNext) {
12640            processNextBroadcast(false);
12641        }
12642        trimApplications();
12643
12644        Binder.restoreCallingIdentity(origId);
12645    }
12646
12647    private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
12648        if (r.nextReceiver > 0) {
12649            Object curReceiver = r.receivers.get(r.nextReceiver-1);
12650            if (curReceiver instanceof BroadcastFilter) {
12651                BroadcastFilter bf = (BroadcastFilter) curReceiver;
12652                EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
12653                        System.identityHashCode(r),
12654                        r.intent.getAction(),
12655                        r.nextReceiver - 1,
12656                        System.identityHashCode(bf));
12657            } else {
12658                EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
12659                        System.identityHashCode(r),
12660                        r.intent.getAction(),
12661                        r.nextReceiver - 1,
12662                        ((ResolveInfo)curReceiver).toString());
12663            }
12664        } else {
12665            Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
12666                    + r);
12667            EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
12668                    System.identityHashCode(r),
12669                    r.intent.getAction(),
12670                    r.nextReceiver,
12671                    "NONE");
12672        }
12673    }
12674
12675    private final void setBroadcastTimeoutLocked(long timeoutTime) {
12676        if (! mPendingBroadcastTimeoutMessage) {
12677            Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12678            mHandler.sendMessageAtTime(msg, timeoutTime);
12679            mPendingBroadcastTimeoutMessage = true;
12680        }
12681    }
12682
12683    private final void cancelBroadcastTimeoutLocked() {
12684        if (mPendingBroadcastTimeoutMessage) {
12685            mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12686            mPendingBroadcastTimeoutMessage = false;
12687        }
12688    }
12689
12690    private final void broadcastTimeoutLocked(boolean fromMsg) {
12691        if (fromMsg) {
12692            mPendingBroadcastTimeoutMessage = false;
12693        }
12694
12695        if (mOrderedBroadcasts.size() == 0) {
12696            return;
12697        }
12698
12699        long now = SystemClock.uptimeMillis();
12700        BroadcastRecord r = mOrderedBroadcasts.get(0);
12701        if (fromMsg) {
12702            if (mDidDexOpt) {
12703                // Delay timeouts until dexopt finishes.
12704                mDidDexOpt = false;
12705                long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
12706                setBroadcastTimeoutLocked(timeoutTime);
12707                return;
12708            }
12709            if (! mProcessesReady) {
12710                // Only process broadcast timeouts if the system is ready. That way
12711                // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
12712                // to do heavy lifting for system up.
12713                return;
12714            }
12715
12716            long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12717            if (timeoutTime > now) {
12718                // We can observe premature timeouts because we do not cancel and reset the
12719                // broadcast timeout message after each receiver finishes.  Instead, we set up
12720                // an initial timeout then kick it down the road a little further as needed
12721                // when it expires.
12722                if (DEBUG_BROADCAST) Slog.v(TAG,
12723                        "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12724                        + timeoutTime);
12725                setBroadcastTimeoutLocked(timeoutTime);
12726                return;
12727            }
12728        }
12729
12730        Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
12731                + ", started " + (now - r.receiverTime) + "ms ago");
12732        r.receiverTime = now;
12733        r.anrCount++;
12734
12735        // Current receiver has passed its expiration date.
12736        if (r.nextReceiver <= 0) {
12737            Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12738            return;
12739        }
12740
12741        ProcessRecord app = null;
12742        String anrMessage = null;
12743
12744        Object curReceiver = r.receivers.get(r.nextReceiver-1);
12745        Slog.w(TAG, "Receiver during timeout: " + curReceiver);
12746        logBroadcastReceiverDiscardLocked(r);
12747        if (curReceiver instanceof BroadcastFilter) {
12748            BroadcastFilter bf = (BroadcastFilter)curReceiver;
12749            if (bf.receiverList.pid != 0
12750                    && bf.receiverList.pid != MY_PID) {
12751                synchronized (this.mPidsSelfLocked) {
12752                    app = this.mPidsSelfLocked.get(
12753                            bf.receiverList.pid);
12754                }
12755            }
12756        } else {
12757            app = r.curApp;
12758        }
12759
12760        if (app != null) {
12761            anrMessage = "Broadcast of " + r.intent.toString();
12762        }
12763
12764        if (mPendingBroadcast == r) {
12765            mPendingBroadcast = null;
12766        }
12767
12768        // Move on to the next receiver.
12769        finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12770                r.resultExtras, r.resultAbort, true);
12771        scheduleBroadcastsLocked();
12772
12773        if (anrMessage != null) {
12774            // Post the ANR to the handler since we do not want to process ANRs while
12775            // potentially holding our lock.
12776            mHandler.post(new AppNotResponding(app, anrMessage));
12777        }
12778    }
12779
12780    private final void processCurBroadcastLocked(BroadcastRecord r,
12781            ProcessRecord app) throws RemoteException {
12782        if (DEBUG_BROADCAST)  Slog.v(TAG,
12783                "Process cur broadcast " + r + " for app " + app);
12784        if (app.thread == null) {
12785            throw new RemoteException();
12786        }
12787        r.receiver = app.thread.asBinder();
12788        r.curApp = app;
12789        app.curReceiver = r;
12790        updateLruProcessLocked(app, true, true);
12791
12792        // Tell the application to launch this receiver.
12793        r.intent.setComponent(r.curComponent);
12794
12795        boolean started = false;
12796        try {
12797            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
12798                    "Delivering to component " + r.curComponent
12799                    + ": " + r);
12800            ensurePackageDexOpt(r.intent.getComponent().getPackageName());
12801            app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
12802                    compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
12803                    r.resultCode, r.resultData, r.resultExtras, r.ordered);
12804            if (DEBUG_BROADCAST)  Slog.v(TAG,
12805                    "Process cur broadcast " + r + " DELIVERED for app " + app);
12806            started = true;
12807        } finally {
12808            if (!started) {
12809                if (DEBUG_BROADCAST)  Slog.v(TAG,
12810                        "Process cur broadcast " + r + ": NOT STARTED!");
12811                r.receiver = null;
12812                r.curApp = null;
12813                app.curReceiver = null;
12814            }
12815        }
12816
12817    }
12818
12819    static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
12820            Intent intent, int resultCode, String data, Bundle extras,
12821            boolean ordered, boolean sticky) throws RemoteException {
12822        // Send the intent to the receiver asynchronously using one-way binder calls.
12823        if (app != null && app.thread != null) {
12824            // If we have an app thread, do the call through that so it is
12825            // correctly ordered with other one-way calls.
12826            app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
12827                    data, extras, ordered, sticky);
12828        } else {
12829            receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
12830        }
12831    }
12832
12833    private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
12834            BroadcastFilter filter, boolean ordered) {
12835        boolean skip = false;
12836        if (filter.requiredPermission != null) {
12837            int perm = checkComponentPermission(filter.requiredPermission,
12838                    r.callingPid, r.callingUid, -1, true);
12839            if (perm != PackageManager.PERMISSION_GRANTED) {
12840                Slog.w(TAG, "Permission Denial: broadcasting "
12841                        + r.intent.toString()
12842                        + " from " + r.callerPackage + " (pid="
12843                        + r.callingPid + ", uid=" + r.callingUid + ")"
12844                        + " requires " + filter.requiredPermission
12845                        + " due to registered receiver " + filter);
12846                skip = true;
12847            }
12848        }
12849        if (r.requiredPermission != null) {
12850            int perm = checkComponentPermission(r.requiredPermission,
12851                    filter.receiverList.pid, filter.receiverList.uid, -1, true);
12852            if (perm != PackageManager.PERMISSION_GRANTED) {
12853                Slog.w(TAG, "Permission Denial: receiving "
12854                        + r.intent.toString()
12855                        + " to " + filter.receiverList.app
12856                        + " (pid=" + filter.receiverList.pid
12857                        + ", uid=" + filter.receiverList.uid + ")"
12858                        + " requires " + r.requiredPermission
12859                        + " due to sender " + r.callerPackage
12860                        + " (uid " + r.callingUid + ")");
12861                skip = true;
12862            }
12863        }
12864
12865        if (!skip) {
12866            // If this is not being sent as an ordered broadcast, then we
12867            // don't want to touch the fields that keep track of the current
12868            // state of ordered broadcasts.
12869            if (ordered) {
12870                r.receiver = filter.receiverList.receiver.asBinder();
12871                r.curFilter = filter;
12872                filter.receiverList.curBroadcast = r;
12873                r.state = BroadcastRecord.CALL_IN_RECEIVE;
12874                if (filter.receiverList.app != null) {
12875                    // Bump hosting application to no longer be in background
12876                    // scheduling class.  Note that we can't do that if there
12877                    // isn't an app...  but we can only be in that case for
12878                    // things that directly call the IActivityManager API, which
12879                    // are already core system stuff so don't matter for this.
12880                    r.curApp = filter.receiverList.app;
12881                    filter.receiverList.app.curReceiver = r;
12882                    updateOomAdjLocked();
12883                }
12884            }
12885            try {
12886                if (DEBUG_BROADCAST_LIGHT) {
12887                    int seq = r.intent.getIntExtra("seq", -1);
12888                    Slog.i(TAG, "Delivering to " + filter
12889                            + " (seq=" + seq + "): " + r);
12890                }
12891                performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
12892                    new Intent(r.intent), r.resultCode,
12893                    r.resultData, r.resultExtras, r.ordered, r.initialSticky);
12894                if (ordered) {
12895                    r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12896                }
12897            } catch (RemoteException e) {
12898                Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
12899                if (ordered) {
12900                    r.receiver = null;
12901                    r.curFilter = null;
12902                    filter.receiverList.curBroadcast = null;
12903                    if (filter.receiverList.app != null) {
12904                        filter.receiverList.app.curReceiver = null;
12905                    }
12906                }
12907            }
12908        }
12909    }
12910
12911    private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12912        if (r.callingUid < 0) {
12913            // This was from a registerReceiver() call; ignore it.
12914            return;
12915        }
12916        System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12917                MAX_BROADCAST_HISTORY-1);
12918        r.finishTime = SystemClock.uptimeMillis();
12919        mBroadcastHistory[0] = r;
12920    }
12921
12922    private final void processNextBroadcast(boolean fromMsg) {
12923        synchronized(this) {
12924            BroadcastRecord r;
12925
12926            if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
12927                    + mParallelBroadcasts.size() + " broadcasts, "
12928                    + mOrderedBroadcasts.size() + " ordered broadcasts");
12929
12930            updateCpuStats();
12931
12932            if (fromMsg) {
12933                mBroadcastsScheduled = false;
12934            }
12935
12936            // First, deliver any non-serialized broadcasts right away.
12937            while (mParallelBroadcasts.size() > 0) {
12938                r = mParallelBroadcasts.remove(0);
12939                r.dispatchTime = SystemClock.uptimeMillis();
12940                r.dispatchClockTime = System.currentTimeMillis();
12941                final int N = r.receivers.size();
12942                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
12943                        + r);
12944                for (int i=0; i<N; i++) {
12945                    Object target = r.receivers.get(i);
12946                    if (DEBUG_BROADCAST)  Slog.v(TAG,
12947                            "Delivering non-ordered to registered "
12948                            + target + ": " + r);
12949                    deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
12950                }
12951                addBroadcastToHistoryLocked(r);
12952                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
12953                        + r);
12954            }
12955
12956            // Now take care of the next serialized one...
12957
12958            // If we are waiting for a process to come up to handle the next
12959            // broadcast, then do nothing at this point.  Just in case, we
12960            // check that the process we're waiting for still exists.
12961            if (mPendingBroadcast != null) {
12962                if (DEBUG_BROADCAST_LIGHT) {
12963                    Slog.v(TAG, "processNextBroadcast: waiting for "
12964                            + mPendingBroadcast.curApp);
12965                }
12966
12967                boolean isDead;
12968                synchronized (mPidsSelfLocked) {
12969                    isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12970                }
12971                if (!isDead) {
12972                    // It's still alive, so keep waiting
12973                    return;
12974                } else {
12975                    Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
12976                            + " died before responding to broadcast");
12977                    mPendingBroadcast.state = BroadcastRecord.IDLE;
12978                    mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
12979                    mPendingBroadcast = null;
12980                }
12981            }
12982
12983            boolean looped = false;
12984
12985            do {
12986                if (mOrderedBroadcasts.size() == 0) {
12987                    // No more broadcasts pending, so all done!
12988                    scheduleAppGcsLocked();
12989                    if (looped) {
12990                        // If we had finished the last ordered broadcast, then
12991                        // make sure all processes have correct oom and sched
12992                        // adjustments.
12993                        updateOomAdjLocked();
12994                    }
12995                    return;
12996                }
12997                r = mOrderedBroadcasts.get(0);
12998                boolean forceReceive = false;
12999
13000                // Ensure that even if something goes awry with the timeout
13001                // detection, we catch "hung" broadcasts here, discard them,
13002                // and continue to make progress.
13003                //
13004                // This is only done if the system is ready so that PRE_BOOT_COMPLETED
13005                // receivers don't get executed with timeouts. They're intended for
13006                // one time heavy lifting after system upgrades and can take
13007                // significant amounts of time.
13008                int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
13009                if (mProcessesReady && r.dispatchTime > 0) {
13010                    long now = SystemClock.uptimeMillis();
13011                    if ((numReceivers > 0) &&
13012                            (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
13013                        Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
13014                                + " now=" + now
13015                                + " dispatchTime=" + r.dispatchTime
13016                                + " startTime=" + r.receiverTime
13017                                + " intent=" + r.intent
13018                                + " numReceivers=" + numReceivers
13019                                + " nextReceiver=" + r.nextReceiver
13020                                + " state=" + r.state);
13021                        broadcastTimeoutLocked(false); // forcibly finish this broadcast
13022                        forceReceive = true;
13023                        r.state = BroadcastRecord.IDLE;
13024                    }
13025                }
13026
13027                if (r.state != BroadcastRecord.IDLE) {
13028                    if (DEBUG_BROADCAST) Slog.d(TAG,
13029                            "processNextBroadcast() called when not idle (state="
13030                            + r.state + ")");
13031                    return;
13032                }
13033
13034                if (r.receivers == null || r.nextReceiver >= numReceivers
13035                        || r.resultAbort || forceReceive) {
13036                    // No more receivers for this broadcast!  Send the final
13037                    // result if requested...
13038                    if (r.resultTo != null) {
13039                        try {
13040                            if (DEBUG_BROADCAST) {
13041                                int seq = r.intent.getIntExtra("seq", -1);
13042                                Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
13043                                        + " seq=" + seq + " app=" + r.callerApp);
13044                            }
13045                            performReceiveLocked(r.callerApp, r.resultTo,
13046                                new Intent(r.intent), r.resultCode,
13047                                r.resultData, r.resultExtras, false, false);
13048                            // Set this to null so that the reference
13049                            // (local and remote) isnt kept in the mBroadcastHistory.
13050                            r.resultTo = null;
13051                        } catch (RemoteException e) {
13052                            Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
13053                        }
13054                    }
13055
13056                    if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
13057                    cancelBroadcastTimeoutLocked();
13058
13059                    if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
13060                            + r);
13061
13062                    // ... and on to the next...
13063                    addBroadcastToHistoryLocked(r);
13064                    mOrderedBroadcasts.remove(0);
13065                    r = null;
13066                    looped = true;
13067                    continue;
13068                }
13069            } while (r == null);
13070
13071            // Get the next receiver...
13072            int recIdx = r.nextReceiver++;
13073
13074            // Keep track of when this receiver started, and make sure there
13075            // is a timeout message pending to kill it if need be.
13076            r.receiverTime = SystemClock.uptimeMillis();
13077            if (recIdx == 0) {
13078                r.dispatchTime = r.receiverTime;
13079                r.dispatchClockTime = System.currentTimeMillis();
13080                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
13081                        + r);
13082            }
13083            if (! mPendingBroadcastTimeoutMessage) {
13084                long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
13085                if (DEBUG_BROADCAST) Slog.v(TAG,
13086                        "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
13087                setBroadcastTimeoutLocked(timeoutTime);
13088            }
13089
13090            Object nextReceiver = r.receivers.get(recIdx);
13091            if (nextReceiver instanceof BroadcastFilter) {
13092                // Simple case: this is a registered receiver who gets
13093                // a direct call.
13094                BroadcastFilter filter = (BroadcastFilter)nextReceiver;
13095                if (DEBUG_BROADCAST)  Slog.v(TAG,
13096                        "Delivering ordered to registered "
13097                        + filter + ": " + r);
13098                deliverToRegisteredReceiverLocked(r, filter, r.ordered);
13099                if (r.receiver == null || !r.ordered) {
13100                    // The receiver has already finished, so schedule to
13101                    // process the next one.
13102                    if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
13103                            + r.ordered + " receiver=" + r.receiver);
13104                    r.state = BroadcastRecord.IDLE;
13105                    scheduleBroadcastsLocked();
13106                }
13107                return;
13108            }
13109
13110            // Hard case: need to instantiate the receiver, possibly
13111            // starting its application process to host it.
13112
13113            ResolveInfo info =
13114                (ResolveInfo)nextReceiver;
13115
13116            boolean skip = false;
13117            int perm = checkComponentPermission(info.activityInfo.permission,
13118                    r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
13119                    info.activityInfo.exported);
13120            if (perm != PackageManager.PERMISSION_GRANTED) {
13121                if (!info.activityInfo.exported) {
13122                    Slog.w(TAG, "Permission Denial: broadcasting "
13123                            + r.intent.toString()
13124                            + " from " + r.callerPackage + " (pid=" + r.callingPid
13125                            + ", uid=" + r.callingUid + ")"
13126                            + " is not exported from uid " + info.activityInfo.applicationInfo.uid
13127                            + " due to receiver " + info.activityInfo.packageName
13128                            + "/" + info.activityInfo.name);
13129                } else {
13130                    Slog.w(TAG, "Permission Denial: broadcasting "
13131                            + r.intent.toString()
13132                            + " from " + r.callerPackage + " (pid=" + r.callingPid
13133                            + ", uid=" + r.callingUid + ")"
13134                            + " requires " + info.activityInfo.permission
13135                            + " due to receiver " + info.activityInfo.packageName
13136                            + "/" + info.activityInfo.name);
13137                }
13138                skip = true;
13139            }
13140            if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
13141                r.requiredPermission != null) {
13142                try {
13143                    perm = AppGlobals.getPackageManager().
13144                            checkPermission(r.requiredPermission,
13145                                    info.activityInfo.applicationInfo.packageName);
13146                } catch (RemoteException e) {
13147                    perm = PackageManager.PERMISSION_DENIED;
13148                }
13149                if (perm != PackageManager.PERMISSION_GRANTED) {
13150                    Slog.w(TAG, "Permission Denial: receiving "
13151                            + r.intent + " to "
13152                            + info.activityInfo.applicationInfo.packageName
13153                            + " requires " + r.requiredPermission
13154                            + " due to sender " + r.callerPackage
13155                            + " (uid " + r.callingUid + ")");
13156                    skip = true;
13157                }
13158            }
13159            if (r.curApp != null && r.curApp.crashing) {
13160                // If the target process is crashing, just skip it.
13161                if (DEBUG_BROADCAST)  Slog.v(TAG,
13162                        "Skipping deliver ordered " + r + " to " + r.curApp
13163                        + ": process crashing");
13164                skip = true;
13165            }
13166
13167            if (skip) {
13168                if (DEBUG_BROADCAST)  Slog.v(TAG,
13169                        "Skipping delivery of ordered " + r + " for whatever reason");
13170                r.receiver = null;
13171                r.curFilter = null;
13172                r.state = BroadcastRecord.IDLE;
13173                scheduleBroadcastsLocked();
13174                return;
13175            }
13176
13177            r.state = BroadcastRecord.APP_RECEIVE;
13178            String targetProcess = info.activityInfo.processName;
13179            r.curComponent = new ComponentName(
13180                    info.activityInfo.applicationInfo.packageName,
13181                    info.activityInfo.name);
13182            r.curReceiver = info.activityInfo;
13183
13184            // Broadcast is being executed, its package can't be stopped.
13185            try {
13186                AppGlobals.getPackageManager().setPackageStoppedState(
13187                        r.curComponent.getPackageName(), false);
13188            } catch (RemoteException e) {
13189            } catch (IllegalArgumentException e) {
13190                Slog.w(TAG, "Failed trying to unstop package "
13191                        + r.curComponent.getPackageName() + ": " + e);
13192            }
13193
13194            // Is this receiver's application already running?
13195            ProcessRecord app = getProcessRecordLocked(targetProcess,
13196                    info.activityInfo.applicationInfo.uid);
13197            if (app != null && app.thread != null) {
13198                try {
13199                    app.addPackage(info.activityInfo.packageName);
13200                    processCurBroadcastLocked(r, app);
13201                    return;
13202                } catch (RemoteException e) {
13203                    Slog.w(TAG, "Exception when sending broadcast to "
13204                          + r.curComponent, e);
13205                }
13206
13207                // If a dead object exception was thrown -- fall through to
13208                // restart the application.
13209            }
13210
13211            // Not running -- get it started, to be executed when the app comes up.
13212            if (DEBUG_BROADCAST)  Slog.v(TAG,
13213                    "Need to start app " + targetProcess + " for broadcast " + r);
13214            if ((r.curApp=startProcessLocked(targetProcess,
13215                    info.activityInfo.applicationInfo, true,
13216                    r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
13217                    "broadcast", r.curComponent,
13218                    (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
13219                            == null) {
13220                // Ah, this recipient is unavailable.  Finish it if necessary,
13221                // and mark the broadcast record as ready for the next.
13222                Slog.w(TAG, "Unable to launch app "
13223                        + info.activityInfo.applicationInfo.packageName + "/"
13224                        + info.activityInfo.applicationInfo.uid + " for broadcast "
13225                        + r.intent + ": process is bad");
13226                logBroadcastReceiverDiscardLocked(r);
13227                finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
13228                        r.resultExtras, r.resultAbort, true);
13229                scheduleBroadcastsLocked();
13230                r.state = BroadcastRecord.IDLE;
13231                return;
13232            }
13233
13234            mPendingBroadcast = r;
13235            mPendingBroadcastRecvIndex = recIdx;
13236        }
13237    }
13238
13239    // =========================================================
13240    // INSTRUMENTATION
13241    // =========================================================
13242
13243    public boolean startInstrumentation(ComponentName className,
13244            String profileFile, int flags, Bundle arguments,
13245            IInstrumentationWatcher watcher) {
13246        // Refuse possible leaked file descriptors
13247        if (arguments != null && arguments.hasFileDescriptors()) {
13248            throw new IllegalArgumentException("File descriptors passed in Bundle");
13249        }
13250
13251        synchronized(this) {
13252            InstrumentationInfo ii = null;
13253            ApplicationInfo ai = null;
13254            try {
13255                ii = mContext.getPackageManager().getInstrumentationInfo(
13256                    className, STOCK_PM_FLAGS);
13257                ai = mContext.getPackageManager().getApplicationInfo(
13258                    ii.targetPackage, STOCK_PM_FLAGS);
13259            } catch (PackageManager.NameNotFoundException e) {
13260            }
13261            if (ii == null) {
13262                reportStartInstrumentationFailure(watcher, className,
13263                        "Unable to find instrumentation info for: " + className);
13264                return false;
13265            }
13266            if (ai == null) {
13267                reportStartInstrumentationFailure(watcher, className,
13268                        "Unable to find instrumentation target package: " + ii.targetPackage);
13269                return false;
13270            }
13271
13272            int match = mContext.getPackageManager().checkSignatures(
13273                    ii.targetPackage, ii.packageName);
13274            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13275                String msg = "Permission Denial: starting instrumentation "
13276                        + className + " from pid="
13277                        + Binder.getCallingPid()
13278                        + ", uid=" + Binder.getCallingPid()
13279                        + " not allowed because package " + ii.packageName
13280                        + " does not have a signature matching the target "
13281                        + ii.targetPackage;
13282                reportStartInstrumentationFailure(watcher, className, msg);
13283                throw new SecurityException(msg);
13284            }
13285
13286            final long origId = Binder.clearCallingIdentity();
13287            // Instrumentation can kill and relaunch even persistent processes
13288            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
13289            ProcessRecord app = addAppLocked(ai);
13290            app.instrumentationClass = className;
13291            app.instrumentationInfo = ai;
13292            app.instrumentationProfileFile = profileFile;
13293            app.instrumentationArguments = arguments;
13294            app.instrumentationWatcher = watcher;
13295            app.instrumentationResultClass = className;
13296            Binder.restoreCallingIdentity(origId);
13297        }
13298
13299        return true;
13300    }
13301
13302    /**
13303     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13304     * error to the logs, but if somebody is watching, send the report there too.  This enables
13305     * the "am" command to report errors with more information.
13306     *
13307     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13308     * @param cn The component name of the instrumentation.
13309     * @param report The error report.
13310     */
13311    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13312            ComponentName cn, String report) {
13313        Slog.w(TAG, report);
13314        try {
13315            if (watcher != null) {
13316                Bundle results = new Bundle();
13317                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13318                results.putString("Error", report);
13319                watcher.instrumentationStatus(cn, -1, results);
13320            }
13321        } catch (RemoteException e) {
13322            Slog.w(TAG, e);
13323        }
13324    }
13325
13326    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13327        if (app.instrumentationWatcher != null) {
13328            try {
13329                // NOTE:  IInstrumentationWatcher *must* be oneway here
13330                app.instrumentationWatcher.instrumentationFinished(
13331                    app.instrumentationClass,
13332                    resultCode,
13333                    results);
13334            } catch (RemoteException e) {
13335            }
13336        }
13337        app.instrumentationWatcher = null;
13338        app.instrumentationClass = null;
13339        app.instrumentationInfo = null;
13340        app.instrumentationProfileFile = null;
13341        app.instrumentationArguments = null;
13342
13343        forceStopPackageLocked(app.processName, -1, false, false, true, true);
13344    }
13345
13346    public void finishInstrumentation(IApplicationThread target,
13347            int resultCode, Bundle results) {
13348        // Refuse possible leaked file descriptors
13349        if (results != null && results.hasFileDescriptors()) {
13350            throw new IllegalArgumentException("File descriptors passed in Intent");
13351        }
13352
13353        synchronized(this) {
13354            ProcessRecord app = getRecordForAppLocked(target);
13355            if (app == null) {
13356                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13357                return;
13358            }
13359            final long origId = Binder.clearCallingIdentity();
13360            finishInstrumentationLocked(app, resultCode, results);
13361            Binder.restoreCallingIdentity(origId);
13362        }
13363    }
13364
13365    // =========================================================
13366    // CONFIGURATION
13367    // =========================================================
13368
13369    public ConfigurationInfo getDeviceConfigurationInfo() {
13370        ConfigurationInfo config = new ConfigurationInfo();
13371        synchronized (this) {
13372            config.reqTouchScreen = mConfiguration.touchscreen;
13373            config.reqKeyboardType = mConfiguration.keyboard;
13374            config.reqNavigation = mConfiguration.navigation;
13375            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13376                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13377                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13378            }
13379            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13380                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13381                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13382            }
13383            config.reqGlEsVersion = GL_ES_VERSION;
13384        }
13385        return config;
13386    }
13387
13388    public Configuration getConfiguration() {
13389        Configuration ci;
13390        synchronized(this) {
13391            ci = new Configuration(mConfiguration);
13392        }
13393        return ci;
13394    }
13395
13396    public void updatePersistentConfiguration(Configuration values) {
13397        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13398                "updateConfiguration()");
13399        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13400                "updateConfiguration()");
13401        if (values == null) {
13402            throw new NullPointerException("Configuration must not be null");
13403        }
13404
13405        synchronized(this) {
13406            final long origId = Binder.clearCallingIdentity();
13407            updateConfigurationLocked(values, null, true, false);
13408            Binder.restoreCallingIdentity(origId);
13409        }
13410    }
13411
13412    public void updateConfiguration(Configuration values) {
13413        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13414                "updateConfiguration()");
13415
13416        synchronized(this) {
13417            if (values == null && mWindowManager != null) {
13418                // sentinel: fetch the current configuration from the window manager
13419                values = mWindowManager.computeNewConfiguration();
13420            }
13421
13422            if (mWindowManager != null) {
13423                mProcessList.applyDisplaySize(mWindowManager);
13424            }
13425
13426            final long origId = Binder.clearCallingIdentity();
13427            if (values != null) {
13428                Settings.System.clearConfiguration(values);
13429            }
13430            updateConfigurationLocked(values, null, false, false);
13431            Binder.restoreCallingIdentity(origId);
13432        }
13433    }
13434
13435    /**
13436     * Do either or both things: (1) change the current configuration, and (2)
13437     * make sure the given activity is running with the (now) current
13438     * configuration.  Returns true if the activity has been left running, or
13439     * false if <var>starting</var> is being destroyed to match the new
13440     * configuration.
13441     * @param persistent TODO
13442     */
13443    public boolean updateConfigurationLocked(Configuration values,
13444            ActivityRecord starting, boolean persistent, boolean initLocale) {
13445        int changes = 0;
13446
13447        boolean kept = true;
13448
13449        if (values != null) {
13450            Configuration newConfig = new Configuration(mConfiguration);
13451            changes = newConfig.updateFrom(values);
13452            if (changes != 0) {
13453                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13454                    Slog.i(TAG, "Updating configuration to: " + values);
13455                }
13456
13457                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13458
13459                if (values.locale != null && !initLocale) {
13460                    saveLocaleLocked(values.locale,
13461                                     !values.locale.equals(mConfiguration.locale),
13462                                     values.userSetLocale);
13463                }
13464
13465                mConfigurationSeq++;
13466                if (mConfigurationSeq <= 0) {
13467                    mConfigurationSeq = 1;
13468                }
13469                newConfig.seq = mConfigurationSeq;
13470                mConfiguration = newConfig;
13471                Slog.i(TAG, "Config changed: " + newConfig);
13472
13473                final Configuration configCopy = new Configuration(mConfiguration);
13474
13475                AttributeCache ac = AttributeCache.instance();
13476                if (ac != null) {
13477                    ac.updateConfiguration(configCopy);
13478                }
13479
13480                // Make sure all resources in our process are updated
13481                // right now, so that anyone who is going to retrieve
13482                // resource values after we return will be sure to get
13483                // the new ones.  This is especially important during
13484                // boot, where the first config change needs to guarantee
13485                // all resources have that config before following boot
13486                // code is executed.
13487                mSystemThread.applyConfigurationToResources(configCopy);
13488
13489                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
13490                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
13491                    msg.obj = new Configuration(configCopy);
13492                    mHandler.sendMessage(msg);
13493                }
13494
13495                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13496                    ProcessRecord app = mLruProcesses.get(i);
13497                    try {
13498                        if (app.thread != null) {
13499                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
13500                                    + app.processName + " new config " + mConfiguration);
13501                            app.thread.scheduleConfigurationChanged(configCopy);
13502                        }
13503                    } catch (Exception e) {
13504                    }
13505                }
13506                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
13507                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13508                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
13509                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
13510                        null, false, false, MY_PID, Process.SYSTEM_UID);
13511                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13512                    broadcastIntentLocked(null, null,
13513                            new Intent(Intent.ACTION_LOCALE_CHANGED),
13514                            null, null, 0, null, null,
13515                            null, false, false, MY_PID, Process.SYSTEM_UID);
13516                }
13517            }
13518        }
13519
13520        if (changes != 0 && starting == null) {
13521            // If the configuration changed, and the caller is not already
13522            // in the process of starting an activity, then find the top
13523            // activity to check if its configuration needs to change.
13524            starting = mMainStack.topRunningActivityLocked(null);
13525        }
13526
13527        if (starting != null) {
13528            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
13529            // And we need to make sure at this point that all other activities
13530            // are made visible with the correct configuration.
13531            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
13532        }
13533
13534        if (values != null && mWindowManager != null) {
13535            mWindowManager.setNewConfiguration(mConfiguration);
13536        }
13537
13538        return kept;
13539    }
13540
13541    /**
13542     * Save the locale.  You must be inside a synchronized (this) block.
13543     */
13544    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13545        if(isDiff) {
13546            SystemProperties.set("user.language", l.getLanguage());
13547            SystemProperties.set("user.region", l.getCountry());
13548        }
13549
13550        if(isPersist) {
13551            SystemProperties.set("persist.sys.language", l.getLanguage());
13552            SystemProperties.set("persist.sys.country", l.getCountry());
13553            SystemProperties.set("persist.sys.localevar", l.getVariant());
13554        }
13555    }
13556
13557    // =========================================================
13558    // LIFETIME MANAGEMENT
13559    // =========================================================
13560
13561    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
13562            ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
13563        if (mAdjSeq == app.adjSeq) {
13564            // This adjustment has already been computed.  If we are calling
13565            // from the top, we may have already computed our adjustment with
13566            // an earlier hidden adjustment that isn't really for us... if
13567            // so, use the new hidden adjustment.
13568            if (!recursed && app.hidden) {
13569                app.curAdj = app.curRawAdj = hiddenAdj;
13570            }
13571            return app.curRawAdj;
13572        }
13573
13574        if (app.thread == null) {
13575            app.adjSeq = mAdjSeq;
13576            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13577            return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
13578        }
13579
13580        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13581        app.adjSource = null;
13582        app.adjTarget = null;
13583        app.empty = false;
13584        app.hidden = false;
13585
13586        final int activitiesSize = app.activities.size();
13587
13588        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
13589            // The max adjustment doesn't allow this app to be anything
13590            // below foreground, so it is not worth doing work for it.
13591            app.adjType = "fixed";
13592            app.adjSeq = mAdjSeq;
13593            app.curRawAdj = app.maxAdj;
13594            app.foregroundActivities = false;
13595            app.keeping = true;
13596            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
13597            // System process can do UI, and when they do we want to have
13598            // them trim their memory after the user leaves the UI.  To
13599            // facilitate this, here we need to determine whether or not it
13600            // is currently showing UI.
13601            app.systemNoUi = true;
13602            if (app == TOP_APP) {
13603                app.systemNoUi = false;
13604            } else if (activitiesSize > 0) {
13605                for (int j = 0; j < activitiesSize; j++) {
13606                    final ActivityRecord r = app.activities.get(j);
13607                    if (r.visible) {
13608                        app.systemNoUi = false;
13609                        break;
13610                    }
13611                }
13612            }
13613            return (app.curAdj=app.maxAdj);
13614        }
13615
13616        final boolean hadForegroundActivities = app.foregroundActivities;
13617
13618        app.foregroundActivities = false;
13619        app.keeping = false;
13620        app.systemNoUi = false;
13621
13622        // Determine the importance of the process, starting with most
13623        // important to least, and assign an appropriate OOM adjustment.
13624        int adj;
13625        int schedGroup;
13626        if (app == TOP_APP) {
13627            // The last app on the list is the foreground app.
13628            adj = ProcessList.FOREGROUND_APP_ADJ;
13629            schedGroup = Process.THREAD_GROUP_DEFAULT;
13630            app.adjType = "top-activity";
13631            app.foregroundActivities = true;
13632        } else if (app.instrumentationClass != null) {
13633            // Don't want to kill running instrumentation.
13634            adj = ProcessList.FOREGROUND_APP_ADJ;
13635            schedGroup = Process.THREAD_GROUP_DEFAULT;
13636            app.adjType = "instrumentation";
13637        } else if (app.curReceiver != null ||
13638                (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
13639            // An app that is currently receiving a broadcast also
13640            // counts as being in the foreground.
13641            adj = ProcessList.FOREGROUND_APP_ADJ;
13642            schedGroup = Process.THREAD_GROUP_DEFAULT;
13643            app.adjType = "broadcast";
13644        } else if (app.executingServices.size() > 0) {
13645            // An app that is currently executing a service callback also
13646            // counts as being in the foreground.
13647            adj = ProcessList.FOREGROUND_APP_ADJ;
13648            schedGroup = Process.THREAD_GROUP_DEFAULT;
13649            app.adjType = "exec-service";
13650        } else if (activitiesSize > 0) {
13651            // This app is in the background with paused activities.
13652            // We inspect activities to potentially upgrade adjustment further below.
13653            adj = hiddenAdj;
13654            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13655            app.hidden = true;
13656            app.adjType = "bg-activities";
13657        } else {
13658            // A very not-needed process.  If this is lower in the lru list,
13659            // we will push it in to the empty bucket.
13660            adj = hiddenAdj;
13661            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13662            app.hidden = true;
13663            app.empty = true;
13664            app.adjType = "bg-empty";
13665        }
13666
13667        // Examine all activities if not already foreground.
13668        if (!app.foregroundActivities && activitiesSize > 0) {
13669            for (int j = 0; j < activitiesSize; j++) {
13670                final ActivityRecord r = app.activities.get(j);
13671                if (r.visible) {
13672                    // App has a visible activity; only upgrade adjustment.
13673                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
13674                        adj = ProcessList.VISIBLE_APP_ADJ;
13675                        app.adjType = "visible";
13676                    }
13677                    schedGroup = Process.THREAD_GROUP_DEFAULT;
13678                    app.hidden = false;
13679                    app.foregroundActivities = true;
13680                    break;
13681                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
13682                        || r.state == ActivityState.STOPPING) {
13683                    // Only upgrade adjustment.
13684                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13685                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13686                        app.adjType = "stopping";
13687                    }
13688                    app.hidden = false;
13689                    app.foregroundActivities = true;
13690                }
13691            }
13692        }
13693
13694        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13695            if (app.foregroundServices) {
13696                // The user is aware of this app, so make it visible.
13697                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13698                app.hidden = false;
13699                app.adjType = "foreground-service";
13700                schedGroup = Process.THREAD_GROUP_DEFAULT;
13701            } else if (app.forcingToForeground != null) {
13702                // The user is aware of this app, so make it visible.
13703                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13704                app.hidden = false;
13705                app.adjType = "force-foreground";
13706                app.adjSource = app.forcingToForeground;
13707                schedGroup = Process.THREAD_GROUP_DEFAULT;
13708            }
13709        }
13710
13711        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
13712            // We don't want to kill the current heavy-weight process.
13713            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
13714            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13715            app.hidden = false;
13716            app.adjType = "heavy";
13717        }
13718
13719        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
13720            // This process is hosting what we currently consider to be the
13721            // home app, so we don't want to let it go into the background.
13722            adj = ProcessList.HOME_APP_ADJ;
13723            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13724            app.hidden = false;
13725            app.adjType = "home";
13726        }
13727
13728        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
13729                && app.activities.size() > 0) {
13730            // This was the previous process that showed UI to the user.
13731            // We want to try to keep it around more aggressively, to give
13732            // a good experience around switching between two apps.
13733            adj = ProcessList.PREVIOUS_APP_ADJ;
13734            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13735            app.hidden = false;
13736            app.adjType = "previous";
13737        }
13738
13739        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13740                + " reason=" + app.adjType);
13741
13742        // By default, we use the computed adjustment.  It may be changed if
13743        // there are applications dependent on our services or providers, but
13744        // this gives us a baseline and makes sure we don't get into an
13745        // infinite recursion.
13746        app.adjSeq = mAdjSeq;
13747        app.curRawAdj = adj;
13748
13749        if (mBackupTarget != null && app == mBackupTarget.app) {
13750            // If possible we want to avoid killing apps while they're being backed up
13751            if (adj > ProcessList.BACKUP_APP_ADJ) {
13752                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
13753                adj = ProcessList.BACKUP_APP_ADJ;
13754                app.adjType = "backup";
13755                app.hidden = false;
13756            }
13757        }
13758
13759        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13760                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13761            final long now = SystemClock.uptimeMillis();
13762            // This process is more important if the top activity is
13763            // bound to the service.
13764            Iterator<ServiceRecord> jt = app.services.iterator();
13765            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
13766                ServiceRecord s = jt.next();
13767                if (s.startRequested) {
13768                    if (app.hasShownUi && app != mHomeProcess) {
13769                        // If this process has shown some UI, let it immediately
13770                        // go to the LRU list because it may be pretty heavy with
13771                        // UI stuff.  We'll tag it with a label just to help
13772                        // debug and understand what is going on.
13773                        if (adj > ProcessList.SERVICE_ADJ) {
13774                            app.adjType = "started-bg-ui-services";
13775                        }
13776                    } else {
13777                        if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13778                            // This service has seen some activity within
13779                            // recent memory, so we will keep its process ahead
13780                            // of the background processes.
13781                            if (adj > ProcessList.SERVICE_ADJ) {
13782                                adj = ProcessList.SERVICE_ADJ;
13783                                app.adjType = "started-services";
13784                                app.hidden = false;
13785                            }
13786                        }
13787                        // If we have let the service slide into the background
13788                        // state, still have some text describing what it is doing
13789                        // even though the service no longer has an impact.
13790                        if (adj > ProcessList.SERVICE_ADJ) {
13791                            app.adjType = "started-bg-services";
13792                        }
13793                    }
13794                    // Don't kill this process because it is doing work; it
13795                    // has said it is doing work.
13796                    app.keeping = true;
13797                }
13798                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13799                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13800                    Iterator<ArrayList<ConnectionRecord>> kt
13801                            = s.connections.values().iterator();
13802                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
13803                        ArrayList<ConnectionRecord> clist = kt.next();
13804                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
13805                            // XXX should compute this based on the max of
13806                            // all connected clients.
13807                            ConnectionRecord cr = clist.get(i);
13808                            if (cr.binding.client == app) {
13809                                // Binding to ourself is not interesting.
13810                                continue;
13811                            }
13812                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
13813                                ProcessRecord client = cr.binding.client;
13814                                int clientAdj = adj;
13815                                int myHiddenAdj = hiddenAdj;
13816                                if (myHiddenAdj > client.hiddenAdj) {
13817                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
13818                                        myHiddenAdj = client.hiddenAdj;
13819                                    } else {
13820                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
13821                                    }
13822                                }
13823                                clientAdj = computeOomAdjLocked(
13824                                    client, myHiddenAdj, TOP_APP, true, doingAll);
13825                                String adjType = null;
13826                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13827                                    // Not doing bind OOM management, so treat
13828                                    // this guy more like a started service.
13829                                    if (app.hasShownUi && app != mHomeProcess) {
13830                                        // If this process has shown some UI, let it immediately
13831                                        // go to the LRU list because it may be pretty heavy with
13832                                        // UI stuff.  We'll tag it with a label just to help
13833                                        // debug and understand what is going on.
13834                                        if (adj > clientAdj) {
13835                                            adjType = "bound-bg-ui-services";
13836                                        }
13837                                        app.hidden = false;
13838                                        clientAdj = adj;
13839                                    } else {
13840                                        if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13841                                            // This service has not seen activity within
13842                                            // recent memory, so allow it to drop to the
13843                                            // LRU list if there is no other reason to keep
13844                                            // it around.  We'll also tag it with a label just
13845                                            // to help debug and undertand what is going on.
13846                                            if (adj > clientAdj) {
13847                                                adjType = "bound-bg-services";
13848                                            }
13849                                            clientAdj = adj;
13850                                        }
13851                                    }
13852                                }
13853                                if (adj > clientAdj) {
13854                                    // If this process has recently shown UI, and
13855                                    // the process that is binding to it is less
13856                                    // important than being visible, then we don't
13857                                    // care about the binding as much as we care
13858                                    // about letting this process get into the LRU
13859                                    // list to be killed and restarted if needed for
13860                                    // memory.
13861                                    if (app.hasShownUi && app != mHomeProcess
13862                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13863                                        adjType = "bound-bg-ui-services";
13864                                    } else {
13865                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13866                                                |Context.BIND_IMPORTANT)) != 0) {
13867                                            adj = clientAdj;
13868                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
13869                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
13870                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13871                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13872                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
13873                                            adj = clientAdj;
13874                                        } else {
13875                                            app.pendingUiClean = true;
13876                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
13877                                                adj = ProcessList.VISIBLE_APP_ADJ;
13878                                            }
13879                                        }
13880                                        if (!client.hidden) {
13881                                            app.hidden = false;
13882                                        }
13883                                        if (client.keeping) {
13884                                            app.keeping = true;
13885                                        }
13886                                        adjType = "service";
13887                                    }
13888                                }
13889                                if (adjType != null) {
13890                                    app.adjType = adjType;
13891                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13892                                            .REASON_SERVICE_IN_USE;
13893                                    app.adjSource = cr.binding.client;
13894                                    app.adjSourceOom = clientAdj;
13895                                    app.adjTarget = s.name;
13896                                }
13897                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13898                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13899                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13900                                    }
13901                                }
13902                            }
13903                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13904                                ActivityRecord a = cr.activity;
13905                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
13906                                        (a.visible || a.state == ActivityState.RESUMED
13907                                         || a.state == ActivityState.PAUSING)) {
13908                                    adj = ProcessList.FOREGROUND_APP_ADJ;
13909                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13910                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13911                                    }
13912                                    app.hidden = false;
13913                                    app.adjType = "service";
13914                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13915                                            .REASON_SERVICE_IN_USE;
13916                                    app.adjSource = a;
13917                                    app.adjSourceOom = adj;
13918                                    app.adjTarget = s.name;
13919                                }
13920                            }
13921                        }
13922                    }
13923                }
13924            }
13925
13926            // Finally, if this process has active services running in it, we
13927            // would like to avoid killing it unless it would prevent the current
13928            // application from running.  By default we put the process in
13929            // with the rest of the background processes; as we scan through
13930            // its services we may bump it up from there.
13931            if (adj > hiddenAdj) {
13932                adj = hiddenAdj;
13933                app.hidden = false;
13934                app.adjType = "bg-services";
13935            }
13936        }
13937
13938        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13939                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13940            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
13941            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
13942                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13943                ContentProviderRecord cpr = jt.next();
13944                if (cpr.clients.size() != 0) {
13945                    Iterator<ProcessRecord> kt = cpr.clients.iterator();
13946                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
13947                        ProcessRecord client = kt.next();
13948                        if (client == app) {
13949                            // Being our own client is not interesting.
13950                            continue;
13951                        }
13952                        int myHiddenAdj = hiddenAdj;
13953                        if (myHiddenAdj > client.hiddenAdj) {
13954                            if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
13955                                myHiddenAdj = client.hiddenAdj;
13956                            } else {
13957                                myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
13958                            }
13959                        }
13960                        int clientAdj = computeOomAdjLocked(
13961                            client, myHiddenAdj, TOP_APP, true, doingAll);
13962                        if (adj > clientAdj) {
13963                            if (app.hasShownUi && app != mHomeProcess
13964                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13965                                app.adjType = "bg-ui-provider";
13966                            } else {
13967                                adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13968                                        ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
13969                                app.adjType = "provider";
13970                            }
13971                            if (!client.hidden) {
13972                                app.hidden = false;
13973                            }
13974                            if (client.keeping) {
13975                                app.keeping = true;
13976                            }
13977                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13978                                    .REASON_PROVIDER_IN_USE;
13979                            app.adjSource = client;
13980                            app.adjSourceOom = clientAdj;
13981                            app.adjTarget = cpr.name;
13982                        }
13983                        if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13984                            schedGroup = Process.THREAD_GROUP_DEFAULT;
13985                        }
13986                    }
13987                }
13988                // If the provider has external (non-framework) process
13989                // dependencies, ensure that its adjustment is at least
13990                // FOREGROUND_APP_ADJ.
13991                if (cpr.externals != 0) {
13992                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13993                        adj = ProcessList.FOREGROUND_APP_ADJ;
13994                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13995                        app.hidden = false;
13996                        app.keeping = true;
13997                        app.adjType = "provider";
13998                        app.adjTarget = cpr.name;
13999                    }
14000                }
14001            }
14002        }
14003
14004        app.curRawAdj = adj;
14005
14006        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14007        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14008        if (adj > app.maxAdj) {
14009            adj = app.maxAdj;
14010            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14011                schedGroup = Process.THREAD_GROUP_DEFAULT;
14012            }
14013        }
14014        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14015            app.keeping = true;
14016        }
14017
14018        if (app.hasAboveClient) {
14019            // If this process has bound to any services with BIND_ABOVE_CLIENT,
14020            // then we need to drop its adjustment to be lower than the service's
14021            // in order to honor the request.  We want to drop it by one adjustment
14022            // level...  but there is special meaning applied to various levels so
14023            // we will skip some of them.
14024            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
14025                // System process will not get dropped, ever
14026            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
14027                adj = ProcessList.VISIBLE_APP_ADJ;
14028            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
14029                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14030            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14031                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
14032            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
14033                adj++;
14034            }
14035        }
14036
14037        if (adj == ProcessList.SERVICE_ADJ) {
14038            if (doingAll) {
14039                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
14040                mNewNumServiceProcs++;
14041            }
14042            if (app.serviceb) {
14043                adj = ProcessList.SERVICE_B_ADJ;
14044            }
14045        } else {
14046            app.serviceb = false;
14047        }
14048
14049        app.curAdj = adj;
14050        app.curSchedGroup = schedGroup;
14051
14052        if (hadForegroundActivities != app.foregroundActivities) {
14053            mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
14054                    app.foregroundActivities).sendToTarget();
14055        }
14056
14057        return app.curRawAdj;
14058    }
14059
14060    /**
14061     * Ask a given process to GC right now.
14062     */
14063    final void performAppGcLocked(ProcessRecord app) {
14064        try {
14065            app.lastRequestedGc = SystemClock.uptimeMillis();
14066            if (app.thread != null) {
14067                if (app.reportLowMemory) {
14068                    app.reportLowMemory = false;
14069                    app.thread.scheduleLowMemory();
14070                } else {
14071                    app.thread.processInBackground();
14072                }
14073            }
14074        } catch (Exception e) {
14075            // whatever.
14076        }
14077    }
14078
14079    /**
14080     * Returns true if things are idle enough to perform GCs.
14081     */
14082    private final boolean canGcNowLocked() {
14083        return mParallelBroadcasts.size() == 0
14084                && mOrderedBroadcasts.size() == 0
14085                && (mSleeping || (mMainStack.mResumedActivity != null &&
14086                        mMainStack.mResumedActivity.idle));
14087    }
14088
14089    /**
14090     * Perform GCs on all processes that are waiting for it, but only
14091     * if things are idle.
14092     */
14093    final void performAppGcsLocked() {
14094        final int N = mProcessesToGc.size();
14095        if (N <= 0) {
14096            return;
14097        }
14098        if (canGcNowLocked()) {
14099            while (mProcessesToGc.size() > 0) {
14100                ProcessRecord proc = mProcessesToGc.remove(0);
14101                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
14102                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14103                            <= SystemClock.uptimeMillis()) {
14104                        // To avoid spamming the system, we will GC processes one
14105                        // at a time, waiting a few seconds between each.
14106                        performAppGcLocked(proc);
14107                        scheduleAppGcsLocked();
14108                        return;
14109                    } else {
14110                        // It hasn't been long enough since we last GCed this
14111                        // process...  put it in the list to wait for its time.
14112                        addProcessToGcListLocked(proc);
14113                        break;
14114                    }
14115                }
14116            }
14117
14118            scheduleAppGcsLocked();
14119        }
14120    }
14121
14122    /**
14123     * If all looks good, perform GCs on all processes waiting for them.
14124     */
14125    final void performAppGcsIfAppropriateLocked() {
14126        if (canGcNowLocked()) {
14127            performAppGcsLocked();
14128            return;
14129        }
14130        // Still not idle, wait some more.
14131        scheduleAppGcsLocked();
14132    }
14133
14134    /**
14135     * Schedule the execution of all pending app GCs.
14136     */
14137    final void scheduleAppGcsLocked() {
14138        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
14139
14140        if (mProcessesToGc.size() > 0) {
14141            // Schedule a GC for the time to the next process.
14142            ProcessRecord proc = mProcessesToGc.get(0);
14143            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14144
14145            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
14146            long now = SystemClock.uptimeMillis();
14147            if (when < (now+GC_TIMEOUT)) {
14148                when = now + GC_TIMEOUT;
14149            }
14150            mHandler.sendMessageAtTime(msg, when);
14151        }
14152    }
14153
14154    /**
14155     * Add a process to the array of processes waiting to be GCed.  Keeps the
14156     * list in sorted order by the last GC time.  The process can't already be
14157     * on the list.
14158     */
14159    final void addProcessToGcListLocked(ProcessRecord proc) {
14160        boolean added = false;
14161        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14162            if (mProcessesToGc.get(i).lastRequestedGc <
14163                    proc.lastRequestedGc) {
14164                added = true;
14165                mProcessesToGc.add(i+1, proc);
14166                break;
14167            }
14168        }
14169        if (!added) {
14170            mProcessesToGc.add(0, proc);
14171        }
14172    }
14173
14174    /**
14175     * Set up to ask a process to GC itself.  This will either do it
14176     * immediately, or put it on the list of processes to gc the next
14177     * time things are idle.
14178     */
14179    final void scheduleAppGcLocked(ProcessRecord app) {
14180        long now = SystemClock.uptimeMillis();
14181        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
14182            return;
14183        }
14184        if (!mProcessesToGc.contains(app)) {
14185            addProcessToGcListLocked(app);
14186            scheduleAppGcsLocked();
14187        }
14188    }
14189
14190    final void checkExcessivePowerUsageLocked(boolean doKills) {
14191        updateCpuStatsNow();
14192
14193        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14194        boolean doWakeKills = doKills;
14195        boolean doCpuKills = doKills;
14196        if (mLastPowerCheckRealtime == 0) {
14197            doWakeKills = false;
14198        }
14199        if (mLastPowerCheckUptime == 0) {
14200            doCpuKills = false;
14201        }
14202        if (stats.isScreenOn()) {
14203            doWakeKills = false;
14204        }
14205        final long curRealtime = SystemClock.elapsedRealtime();
14206        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
14207        final long curUptime = SystemClock.uptimeMillis();
14208        final long uptimeSince = curUptime - mLastPowerCheckUptime;
14209        mLastPowerCheckRealtime = curRealtime;
14210        mLastPowerCheckUptime = curUptime;
14211        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
14212            doWakeKills = false;
14213        }
14214        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
14215            doCpuKills = false;
14216        }
14217        int i = mLruProcesses.size();
14218        while (i > 0) {
14219            i--;
14220            ProcessRecord app = mLruProcesses.get(i);
14221            if (!app.keeping) {
14222                long wtime;
14223                synchronized (stats) {
14224                    wtime = stats.getProcessWakeTime(app.info.uid,
14225                            app.pid, curRealtime);
14226                }
14227                long wtimeUsed = wtime - app.lastWakeTime;
14228                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
14229                if (DEBUG_POWER) {
14230                    StringBuilder sb = new StringBuilder(128);
14231                    sb.append("Wake for ");
14232                    app.toShortString(sb);
14233                    sb.append(": over ");
14234                    TimeUtils.formatDuration(realtimeSince, sb);
14235                    sb.append(" used ");
14236                    TimeUtils.formatDuration(wtimeUsed, sb);
14237                    sb.append(" (");
14238                    sb.append((wtimeUsed*100)/realtimeSince);
14239                    sb.append("%)");
14240                    Slog.i(TAG, sb.toString());
14241                    sb.setLength(0);
14242                    sb.append("CPU for ");
14243                    app.toShortString(sb);
14244                    sb.append(": over ");
14245                    TimeUtils.formatDuration(uptimeSince, sb);
14246                    sb.append(" used ");
14247                    TimeUtils.formatDuration(cputimeUsed, sb);
14248                    sb.append(" (");
14249                    sb.append((cputimeUsed*100)/uptimeSince);
14250                    sb.append("%)");
14251                    Slog.i(TAG, sb.toString());
14252                }
14253                // If a process has held a wake lock for more
14254                // than 50% of the time during this period,
14255                // that sounds pad.  Kill!
14256                if (doWakeKills && realtimeSince > 0
14257                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
14258                    synchronized (stats) {
14259                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
14260                                realtimeSince, wtimeUsed);
14261                    }
14262                    Slog.w(TAG, "Excessive wake lock in " + app.processName
14263                            + " (pid " + app.pid + "): held " + wtimeUsed
14264                            + " during " + realtimeSince);
14265                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14266                            app.processName, app.setAdj, "excessive wake lock");
14267                    Process.killProcessQuiet(app.pid);
14268                } else if (doCpuKills && uptimeSince > 0
14269                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
14270                    synchronized (stats) {
14271                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
14272                                uptimeSince, cputimeUsed);
14273                    }
14274                    Slog.w(TAG, "Excessive CPU in " + app.processName
14275                            + " (pid " + app.pid + "): used " + cputimeUsed
14276                            + " during " + uptimeSince);
14277                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14278                            app.processName, app.setAdj, "excessive cpu");
14279                    Process.killProcessQuiet(app.pid);
14280                } else {
14281                    app.lastWakeTime = wtime;
14282                    app.lastCpuTime = app.curCpuTime;
14283                }
14284            }
14285        }
14286    }
14287
14288    private final boolean updateOomAdjLocked(
14289            ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
14290        app.hiddenAdj = hiddenAdj;
14291
14292        if (app.thread == null) {
14293            return false;
14294        }
14295
14296        final boolean wasKeeping = app.keeping;
14297
14298        boolean success = true;
14299
14300        computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
14301
14302        if (app.curRawAdj != app.setRawAdj) {
14303            if (false) {
14304                // Removing for now.  Forcing GCs is not so useful anymore
14305                // with Dalvik, and the new memory level hint facility is
14306                // better for what we need to do these days.
14307                if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
14308                        && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14309                    // If this app is transitioning from foreground to
14310                    // non-foreground, have it do a gc.
14311                    scheduleAppGcLocked(app);
14312                } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14313                        && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14314                    // Likewise do a gc when an app is moving in to the
14315                    // background (such as a service stopping).
14316                    scheduleAppGcLocked(app);
14317                }
14318            }
14319
14320            if (wasKeeping && !app.keeping) {
14321                // This app is no longer something we want to keep.  Note
14322                // its current wake lock time to later know to kill it if
14323                // it is not behaving well.
14324                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14325                synchronized (stats) {
14326                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
14327                            app.pid, SystemClock.elapsedRealtime());
14328                }
14329                app.lastCpuTime = app.curCpuTime;
14330            }
14331
14332            app.setRawAdj = app.curRawAdj;
14333        }
14334
14335        if (app.curAdj != app.setAdj) {
14336            if (Process.setOomAdj(app.pid, app.curAdj)) {
14337                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
14338                    TAG, "Set " + app.pid + " " + app.processName +
14339                    " adj " + app.curAdj + ": " + app.adjType);
14340                app.setAdj = app.curAdj;
14341            } else {
14342                success = false;
14343                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
14344            }
14345        }
14346        if (app.setSchedGroup != app.curSchedGroup) {
14347            app.setSchedGroup = app.curSchedGroup;
14348            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
14349                    "Setting process group of " + app.processName
14350                    + " to " + app.curSchedGroup);
14351            if (app.waitingToKill != null &&
14352                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
14353                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
14354                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14355                        app.processName, app.setAdj, app.waitingToKill);
14356                Process.killProcessQuiet(app.pid);
14357                success = false;
14358            } else {
14359                if (true) {
14360                    long oldId = Binder.clearCallingIdentity();
14361                    try {
14362                        Process.setProcessGroup(app.pid, app.curSchedGroup);
14363                    } catch (Exception e) {
14364                        Slog.w(TAG, "Failed setting process group of " + app.pid
14365                                + " to " + app.curSchedGroup);
14366                        e.printStackTrace();
14367                    } finally {
14368                        Binder.restoreCallingIdentity(oldId);
14369                    }
14370                } else {
14371                    if (app.thread != null) {
14372                        try {
14373                            app.thread.setSchedulingGroup(app.curSchedGroup);
14374                        } catch (RemoteException e) {
14375                        }
14376                    }
14377                }
14378            }
14379        }
14380        return success;
14381    }
14382
14383    private final ActivityRecord resumedAppLocked() {
14384        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
14385        if (resumedActivity == null || resumedActivity.app == null) {
14386            resumedActivity = mMainStack.mPausingActivity;
14387            if (resumedActivity == null || resumedActivity.app == null) {
14388                resumedActivity = mMainStack.topRunningActivityLocked(null);
14389            }
14390        }
14391        return resumedActivity;
14392    }
14393
14394    private final boolean updateOomAdjLocked(ProcessRecord app) {
14395        final ActivityRecord TOP_ACT = resumedAppLocked();
14396        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14397        int curAdj = app.curAdj;
14398        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14399            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
14400
14401        mAdjSeq++;
14402
14403        boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
14404        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14405            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
14406        if (nowHidden != wasHidden) {
14407            // Changed to/from hidden state, so apps after it in the LRU
14408            // list may also be changed.
14409            updateOomAdjLocked();
14410        }
14411        return success;
14412    }
14413
14414    final void updateOomAdjLocked() {
14415        final ActivityRecord TOP_ACT = resumedAppLocked();
14416        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14417
14418        if (false) {
14419            RuntimeException e = new RuntimeException();
14420            e.fillInStackTrace();
14421            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
14422        }
14423
14424        mAdjSeq++;
14425        mNewNumServiceProcs = 0;
14426
14427        // Let's determine how many processes we have running vs.
14428        // how many slots we have for background processes; we may want
14429        // to put multiple processes in a slot of there are enough of
14430        // them.
14431        int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
14432        int factor = (mLruProcesses.size()-4)/numSlots;
14433        if (factor < 1) factor = 1;
14434        int step = 0;
14435        int numHidden = 0;
14436
14437        // First update the OOM adjustment for each of the
14438        // application processes based on their current state.
14439        int i = mLruProcesses.size();
14440        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
14441        while (i > 0) {
14442            i--;
14443            ProcessRecord app = mLruProcesses.get(i);
14444            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
14445            updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
14446            if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
14447                && app.curAdj == curHiddenAdj) {
14448                step++;
14449                if (step >= factor) {
14450                    step = 0;
14451                    curHiddenAdj++;
14452                }
14453            }
14454            if (!app.killedBackground) {
14455                if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
14456                    numHidden++;
14457                    if (numHidden > mProcessLimit) {
14458                        Slog.i(TAG, "No longer want " + app.processName
14459                                + " (pid " + app.pid + "): hidden #" + numHidden);
14460                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14461                                app.processName, app.setAdj, "too many background");
14462                        app.killedBackground = true;
14463                        Process.killProcessQuiet(app.pid);
14464                    }
14465                }
14466            }
14467        }
14468
14469        mNumServiceProcs = mNewNumServiceProcs;
14470
14471        // Now determine the memory trimming level of background processes.
14472        // Unfortunately we need to start at the back of the list to do this
14473        // properly.  We only do this if the number of background apps we
14474        // are managing to keep around is less than half the maximum we desire;
14475        // if we are keeping a good number around, we'll let them use whatever
14476        // memory they want.
14477        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
14478            final int N = mLruProcesses.size();
14479            factor = numHidden/3;
14480            int minFactor = 2;
14481            if (mHomeProcess != null) minFactor++;
14482            if (mPreviousProcess != null) minFactor++;
14483            if (factor < minFactor) factor = minFactor;
14484            step = 0;
14485            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
14486            for (i=0; i<N; i++) {
14487                ProcessRecord app = mLruProcesses.get(i);
14488                if (app.curAdj >= ProcessList.HOME_APP_ADJ
14489                        && app.curAdj != ProcessList.SERVICE_B_ADJ
14490                        && !app.killedBackground) {
14491                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
14492                        try {
14493                            app.thread.scheduleTrimMemory(curLevel);
14494                        } catch (RemoteException e) {
14495                        }
14496                        if (false) {
14497                            // For now we won't do this; our memory trimming seems
14498                            // to be good enough at this point that destroying
14499                            // activities causes more harm than good.
14500                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
14501                                    && app != mHomeProcess && app != mPreviousProcess) {
14502                                // For these apps we will also finish their activities
14503                                // to help them free memory.
14504                                mMainStack.destroyActivitiesLocked(app, false, "trim");
14505                            }
14506                        }
14507                    }
14508                    app.trimMemoryLevel = curLevel;
14509                    step++;
14510                    if (step >= factor) {
14511                        switch (curLevel) {
14512                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
14513                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
14514                                break;
14515                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
14516                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
14517                                break;
14518                        }
14519                    }
14520                } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14521                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
14522                            && app.thread != null) {
14523                        try {
14524                            app.thread.scheduleTrimMemory(
14525                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
14526                        } catch (RemoteException e) {
14527                        }
14528                    }
14529                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
14530                } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
14531                        && app.pendingUiClean) {
14532                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14533                            && app.thread != null) {
14534                        try {
14535                            app.thread.scheduleTrimMemory(
14536                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14537                        } catch (RemoteException e) {
14538                        }
14539                    }
14540                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14541                    app.pendingUiClean = false;
14542                } else {
14543                    app.trimMemoryLevel = 0;
14544                }
14545            }
14546        } else {
14547            final int N = mLruProcesses.size();
14548            for (i=0; i<N; i++) {
14549                ProcessRecord app = mLruProcesses.get(i);
14550                if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
14551                        && app.pendingUiClean) {
14552                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14553                            && app.thread != null) {
14554                        try {
14555                            app.thread.scheduleTrimMemory(
14556                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14557                        } catch (RemoteException e) {
14558                        }
14559                    }
14560                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14561                    app.pendingUiClean = false;
14562                } else {
14563                    app.trimMemoryLevel = 0;
14564                }
14565            }
14566        }
14567
14568        if (mAlwaysFinishActivities) {
14569            mMainStack.destroyActivitiesLocked(null, false, "always-finish");
14570        }
14571    }
14572
14573    final void trimApplications() {
14574        synchronized (this) {
14575            int i;
14576
14577            // First remove any unused application processes whose package
14578            // has been removed.
14579            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
14580                final ProcessRecord app = mRemovedProcesses.get(i);
14581                if (app.activities.size() == 0
14582                        && app.curReceiver == null && app.services.size() == 0) {
14583                    Slog.i(
14584                        TAG, "Exiting empty application process "
14585                        + app.processName + " ("
14586                        + (app.thread != null ? app.thread.asBinder() : null)
14587                        + ")\n");
14588                    if (app.pid > 0 && app.pid != MY_PID) {
14589                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14590                                app.processName, app.setAdj, "empty");
14591                        Process.killProcessQuiet(app.pid);
14592                    } else {
14593                        try {
14594                            app.thread.scheduleExit();
14595                        } catch (Exception e) {
14596                            // Ignore exceptions.
14597                        }
14598                    }
14599                    cleanUpApplicationRecordLocked(app, false, true, -1);
14600                    mRemovedProcesses.remove(i);
14601
14602                    if (app.persistent) {
14603                        if (app.persistent) {
14604                            addAppLocked(app.info);
14605                        }
14606                    }
14607                }
14608            }
14609
14610            // Now update the oom adj for all processes.
14611            updateOomAdjLocked();
14612        }
14613    }
14614
14615    /** This method sends the specified signal to each of the persistent apps */
14616    public void signalPersistentProcesses(int sig) throws RemoteException {
14617        if (sig != Process.SIGNAL_USR1) {
14618            throw new SecurityException("Only SIGNAL_USR1 is allowed");
14619        }
14620
14621        synchronized (this) {
14622            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14623                    != PackageManager.PERMISSION_GRANTED) {
14624                throw new SecurityException("Requires permission "
14625                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14626            }
14627
14628            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14629                ProcessRecord r = mLruProcesses.get(i);
14630                if (r.thread != null && r.persistent) {
14631                    Process.sendSignal(r.pid, sig);
14632                }
14633            }
14634        }
14635    }
14636
14637    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
14638        if (proc == null || proc == mProfileProc) {
14639            proc = mProfileProc;
14640            path = mProfileFile;
14641            profileType = mProfileType;
14642            clearProfilerLocked();
14643        }
14644        if (proc == null) {
14645            return;
14646        }
14647        try {
14648            proc.thread.profilerControl(false, path, null, profileType);
14649        } catch (RemoteException e) {
14650            throw new IllegalStateException("Process disappeared");
14651        }
14652    }
14653
14654    private void clearProfilerLocked() {
14655        if (mProfileFd != null) {
14656            try {
14657                mProfileFd.close();
14658            } catch (IOException e) {
14659            }
14660        }
14661        mProfileApp = null;
14662        mProfileProc = null;
14663        mProfileFile = null;
14664        mProfileType = 0;
14665        mAutoStopProfiler = false;
14666    }
14667
14668    public boolean profileControl(String process, boolean start,
14669            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
14670
14671        try {
14672            synchronized (this) {
14673                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14674                // its own permission.
14675                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14676                        != PackageManager.PERMISSION_GRANTED) {
14677                    throw new SecurityException("Requires permission "
14678                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14679                }
14680
14681                if (start && fd == null) {
14682                    throw new IllegalArgumentException("null fd");
14683                }
14684
14685                ProcessRecord proc = null;
14686                if (process != null) {
14687                    try {
14688                        int pid = Integer.parseInt(process);
14689                        synchronized (mPidsSelfLocked) {
14690                            proc = mPidsSelfLocked.get(pid);
14691                        }
14692                    } catch (NumberFormatException e) {
14693                    }
14694
14695                    if (proc == null) {
14696                        HashMap<String, SparseArray<ProcessRecord>> all
14697                                = mProcessNames.getMap();
14698                        SparseArray<ProcessRecord> procs = all.get(process);
14699                        if (procs != null && procs.size() > 0) {
14700                            proc = procs.valueAt(0);
14701                        }
14702                    }
14703                }
14704
14705                if (start && (proc == null || proc.thread == null)) {
14706                    throw new IllegalArgumentException("Unknown process: " + process);
14707                }
14708
14709                if (start) {
14710                    stopProfilerLocked(null, null, 0);
14711                    setProfileApp(proc.info, proc.processName, path, fd, false);
14712                    mProfileProc = proc;
14713                    mProfileType = profileType;
14714                    try {
14715                        fd = fd.dup();
14716                    } catch (IOException e) {
14717                        fd = null;
14718                    }
14719                    proc.thread.profilerControl(start, path, fd, profileType);
14720                    fd = null;
14721                    mProfileFd = null;
14722                } else {
14723                    stopProfilerLocked(proc, path, profileType);
14724                    if (fd != null) {
14725                        try {
14726                            fd.close();
14727                        } catch (IOException e) {
14728                        }
14729                    }
14730                }
14731
14732                return true;
14733            }
14734        } catch (RemoteException e) {
14735            throw new IllegalStateException("Process disappeared");
14736        } finally {
14737            if (fd != null) {
14738                try {
14739                    fd.close();
14740                } catch (IOException e) {
14741                }
14742            }
14743        }
14744    }
14745
14746    public boolean dumpHeap(String process, boolean managed,
14747            String path, ParcelFileDescriptor fd) throws RemoteException {
14748
14749        try {
14750            synchronized (this) {
14751                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14752                // its own permission (same as profileControl).
14753                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14754                        != PackageManager.PERMISSION_GRANTED) {
14755                    throw new SecurityException("Requires permission "
14756                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14757                }
14758
14759                if (fd == null) {
14760                    throw new IllegalArgumentException("null fd");
14761                }
14762
14763                ProcessRecord proc = null;
14764                try {
14765                    int pid = Integer.parseInt(process);
14766                    synchronized (mPidsSelfLocked) {
14767                        proc = mPidsSelfLocked.get(pid);
14768                    }
14769                } catch (NumberFormatException e) {
14770                }
14771
14772                if (proc == null) {
14773                    HashMap<String, SparseArray<ProcessRecord>> all
14774                            = mProcessNames.getMap();
14775                    SparseArray<ProcessRecord> procs = all.get(process);
14776                    if (procs != null && procs.size() > 0) {
14777                        proc = procs.valueAt(0);
14778                    }
14779                }
14780
14781                if (proc == null || proc.thread == null) {
14782                    throw new IllegalArgumentException("Unknown process: " + process);
14783                }
14784
14785                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14786                if (!isDebuggable) {
14787                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14788                        throw new SecurityException("Process not debuggable: " + proc);
14789                    }
14790                }
14791
14792                proc.thread.dumpHeap(managed, path, fd);
14793                fd = null;
14794                return true;
14795            }
14796        } catch (RemoteException e) {
14797            throw new IllegalStateException("Process disappeared");
14798        } finally {
14799            if (fd != null) {
14800                try {
14801                    fd.close();
14802                } catch (IOException e) {
14803                }
14804            }
14805        }
14806    }
14807
14808    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14809    public void monitor() {
14810        synchronized (this) { }
14811    }
14812
14813    public void onCoreSettingsChange(Bundle settings) {
14814        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14815            ProcessRecord processRecord = mLruProcesses.get(i);
14816            try {
14817                if (processRecord.thread != null) {
14818                    processRecord.thread.setCoreSettings(settings);
14819                }
14820            } catch (RemoteException re) {
14821                /* ignore */
14822            }
14823        }
14824    }
14825
14826    // Multi-user methods
14827
14828    public boolean switchUser(int userid) {
14829        // TODO
14830        return true;
14831    }
14832}
14833