ActivityManagerService.java revision 0c3804950236fe170ebf6cc7a5f1e3e305b8f315
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 static android.content.pm.PackageManager.PERMISSION_GRANTED;
20
21import com.android.internal.R;
22import com.android.internal.os.BatteryStatsImpl;
23import com.android.internal.os.ProcessStats;
24import com.android.server.AttributeCache;
25import com.android.server.IntentResolver;
26import com.android.server.ProcessMap;
27import com.android.server.SystemServer;
28import com.android.server.Watchdog;
29import com.android.server.am.ActivityStack.ActivityState;
30import com.android.server.wm.WindowManagerService;
31
32import dalvik.system.Zygote;
33
34import android.app.Activity;
35import android.app.ActivityManager;
36import android.app.ActivityManagerNative;
37import android.app.ActivityOptions;
38import android.app.ActivityThread;
39import android.app.AlertDialog;
40import android.app.AppGlobals;
41import android.app.ApplicationErrorReport;
42import android.app.Dialog;
43import android.app.IActivityController;
44import android.app.IApplicationThread;
45import android.app.IInstrumentationWatcher;
46import android.app.INotificationManager;
47import android.app.IProcessObserver;
48import android.app.IServiceConnection;
49import android.app.IThumbnailReceiver;
50import android.app.Instrumentation;
51import android.app.Notification;
52import android.app.NotificationManager;
53import android.app.PendingIntent;
54import android.app.backup.IBackupManager;
55import android.content.ActivityNotFoundException;
56import android.content.BroadcastReceiver;
57import android.content.ClipData;
58import android.content.ComponentCallbacks2;
59import android.content.ComponentName;
60import android.content.ContentProvider;
61import android.content.ContentResolver;
62import android.content.Context;
63import android.content.DialogInterface;
64import android.content.IContentProvider;
65import android.content.IIntentReceiver;
66import android.content.IIntentSender;
67import android.content.Intent;
68import android.content.IntentFilter;
69import android.content.IntentSender;
70import android.content.pm.ActivityInfo;
71import android.content.pm.ApplicationInfo;
72import android.content.pm.ConfigurationInfo;
73import android.content.pm.IPackageDataObserver;
74import android.content.pm.IPackageManager;
75import android.content.pm.InstrumentationInfo;
76import android.content.pm.PackageInfo;
77import android.content.pm.PackageManager;
78import android.content.pm.UserInfo;
79import android.content.pm.PackageManager.NameNotFoundException;
80import android.content.pm.PathPermission;
81import android.content.pm.ProviderInfo;
82import android.content.pm.ResolveInfo;
83import android.content.pm.ServiceInfo;
84import android.content.res.CompatibilityInfo;
85import android.content.res.Configuration;
86import android.graphics.Bitmap;
87import android.net.Proxy;
88import android.net.ProxyProperties;
89import android.net.Uri;
90import android.os.Binder;
91import android.os.Build;
92import android.os.Bundle;
93import android.os.Debug;
94import android.os.DropBoxManager;
95import android.os.Environment;
96import android.os.FileObserver;
97import android.os.FileUtils;
98import android.os.Handler;
99import android.os.IBinder;
100import android.os.IPermissionController;
101import android.os.Looper;
102import android.os.Message;
103import android.os.Parcel;
104import android.os.ParcelFileDescriptor;
105import android.os.Process;
106import android.os.RemoteCallbackList;
107import android.os.RemoteException;
108import android.os.ServiceManager;
109import android.os.StrictMode;
110import android.os.SystemClock;
111import android.os.SystemProperties;
112import android.os.UserHandle;
113import android.os.UserManager;
114import android.provider.Settings;
115import android.text.format.Time;
116import android.util.EventLog;
117import android.util.Log;
118import android.util.Pair;
119import android.util.PrintWriterPrinter;
120import android.util.Slog;
121import android.util.SparseArray;
122import android.util.SparseIntArray;
123import android.util.TimeUtils;
124import android.view.Gravity;
125import android.view.LayoutInflater;
126import android.view.View;
127import android.view.WindowManager;
128import android.view.WindowManagerPolicy;
129
130import java.io.BufferedInputStream;
131import java.io.BufferedOutputStream;
132import java.io.BufferedReader;
133import java.io.DataInputStream;
134import java.io.DataOutputStream;
135import java.io.File;
136import java.io.FileDescriptor;
137import java.io.FileInputStream;
138import java.io.FileNotFoundException;
139import java.io.FileOutputStream;
140import java.io.IOException;
141import java.io.InputStreamReader;
142import java.io.PrintWriter;
143import java.io.StringWriter;
144import java.lang.ref.WeakReference;
145import java.util.ArrayList;
146import java.util.Collections;
147import java.util.Comparator;
148import java.util.HashMap;
149import java.util.HashSet;
150import java.util.Iterator;
151import java.util.List;
152import java.util.Locale;
153import java.util.Map;
154import java.util.Map.Entry;
155import java.util.Set;
156import java.util.concurrent.atomic.AtomicBoolean;
157import java.util.concurrent.atomic.AtomicLong;
158
159public final class ActivityManagerService extends ActivityManagerNative
160        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
161    private static final String USER_DATA_DIR = "/data/user/";
162    static final String TAG = "ActivityManager";
163    static final String TAG_MU = "ActivityManagerServiceMU";
164    static final boolean DEBUG = false;
165    static final boolean localLOGV = DEBUG;
166    static final boolean DEBUG_SWITCH = localLOGV || false;
167    static final boolean DEBUG_TASKS = localLOGV || false;
168    static final boolean DEBUG_PAUSE = localLOGV || false;
169    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
170    static final boolean DEBUG_TRANSITION = localLOGV || false;
171    static final boolean DEBUG_BROADCAST = localLOGV || false;
172    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
173    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
174    static final boolean DEBUG_SERVICE = localLOGV || false;
175    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
176    static final boolean DEBUG_VISBILITY = localLOGV || false;
177    static final boolean DEBUG_PROCESSES = localLOGV || false;
178    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
179    static final boolean DEBUG_PROVIDER = localLOGV || false;
180    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
181    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
182    static final boolean DEBUG_RESULTS = localLOGV || false;
183    static final boolean DEBUG_BACKUP = localLOGV || false;
184    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
185    static final boolean DEBUG_POWER = localLOGV || false;
186    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
187    static final boolean DEBUG_MU = localLOGV || false;
188    static final boolean VALIDATE_TOKENS = false;
189    static final boolean SHOW_ACTIVITY_START_TIME = true;
190
191    // Control over CPU and battery monitoring.
192    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
193    static final boolean MONITOR_CPU_USAGE = true;
194    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
195    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
196    static final boolean MONITOR_THREAD_CPU_USAGE = false;
197
198    // The flags that are set for all calls we make to the package manager.
199    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
200
201    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
202
203    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
204
205    // Maximum number of recent tasks that we can remember.
206    static final int MAX_RECENT_TASKS = 20;
207
208    // Amount of time after a call to stopAppSwitches() during which we will
209    // prevent further untrusted switches from happening.
210    static final long APP_SWITCH_DELAY_TIME = 5*1000;
211
212    // How long we wait for a launched process to attach to the activity manager
213    // before we decide it's never going to come up for real.
214    static final int PROC_START_TIMEOUT = 10*1000;
215
216    // How long we wait for a launched process to attach to the activity manager
217    // before we decide it's never going to come up for real, when the process was
218    // started with a wrapper for instrumentation (such as Valgrind) because it
219    // could take much longer than usual.
220    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
221
222    // How long to wait after going idle before forcing apps to GC.
223    static final int GC_TIMEOUT = 5*1000;
224
225    // The minimum amount of time between successive GC requests for a process.
226    static final int GC_MIN_INTERVAL = 60*1000;
227
228    // The rate at which we check for apps using excessive power -- 15 mins.
229    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
230
231    // The minimum sample duration we will allow before deciding we have
232    // enough data on wake locks to start killing things.
233    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
234
235    // The minimum sample duration we will allow before deciding we have
236    // enough data on CPU usage to start killing things.
237    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
238
239    // How long we allow a receiver to run before giving up on it.
240    static final int BROADCAST_FG_TIMEOUT = 10*1000;
241    static final int BROADCAST_BG_TIMEOUT = 60*1000;
242
243    // How long we wait until we timeout on key dispatching.
244    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
245
246    // How long we wait until we timeout on key dispatching during instrumentation.
247    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
248
249    static final int MY_PID = Process.myPid();
250
251    static final String[] EMPTY_STRING_ARRAY = new String[0];
252
253    public ActivityStack mMainStack;
254
255    private final boolean mHeadless;
256
257    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
258    // default actuion automatically.  Important for devices without direct input
259    // devices.
260    private boolean mShowDialogs = true;
261
262    /**
263     * Description of a request to start a new activity, which has been held
264     * due to app switches being disabled.
265     */
266    static class PendingActivityLaunch {
267        ActivityRecord r;
268        ActivityRecord sourceRecord;
269        int startFlags;
270    }
271
272    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
273            = new ArrayList<PendingActivityLaunch>();
274
275
276    BroadcastQueue mFgBroadcastQueue;
277    BroadcastQueue mBgBroadcastQueue;
278    // Convenient for easy iteration over the queues. Foreground is first
279    // so that dispatch of foreground broadcasts gets precedence.
280    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
281
282    BroadcastQueue broadcastQueueForIntent(Intent intent) {
283        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
284        if (DEBUG_BACKGROUND_BROADCAST) {
285            Slog.i(TAG, "Broadcast intent " + intent + " on "
286                    + (isFg ? "foreground" : "background")
287                    + " queue");
288        }
289        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
290    }
291
292    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
293        for (BroadcastQueue queue : mBroadcastQueues) {
294            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
295            if (r != null) {
296                return r;
297            }
298        }
299        return null;
300    }
301
302    /**
303     * Activity we have told the window manager to have key focus.
304     */
305    ActivityRecord mFocusedActivity = null;
306    /**
307     * List of intents that were used to start the most recent tasks.
308     */
309    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
310
311    /**
312     * Process management.
313     */
314    final ProcessList mProcessList = new ProcessList();
315
316    /**
317     * All of the applications we currently have running organized by name.
318     * The keys are strings of the application package name (as
319     * returned by the package manager), and the keys are ApplicationRecord
320     * objects.
321     */
322    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
323
324    /**
325     * The currently running isolated processes.
326     */
327    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
328
329    /**
330     * Counter for assigning isolated process uids, to avoid frequently reusing the
331     * same ones.
332     */
333    int mNextIsolatedProcessUid = 0;
334
335    /**
336     * The currently running heavy-weight process, if any.
337     */
338    ProcessRecord mHeavyWeightProcess = null;
339
340    /**
341     * The last time that various processes have crashed.
342     */
343    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
344
345    /**
346     * Set of applications that we consider to be bad, and will reject
347     * incoming broadcasts from (which the user has no control over).
348     * Processes are added to this set when they have crashed twice within
349     * a minimum amount of time; they are removed from it when they are
350     * later restarted (hopefully due to some user action).  The value is the
351     * time it was added to the list.
352     */
353    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
354
355    /**
356     * All of the processes we currently have running organized by pid.
357     * The keys are the pid running the application.
358     *
359     * <p>NOTE: This object is protected by its own lock, NOT the global
360     * activity manager lock!
361     */
362    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
363
364    /**
365     * All of the processes that have been forced to be foreground.  The key
366     * is the pid of the caller who requested it (we hold a death
367     * link on it).
368     */
369    abstract class ForegroundToken implements IBinder.DeathRecipient {
370        int pid;
371        IBinder token;
372    }
373    final SparseArray<ForegroundToken> mForegroundProcesses
374            = new SparseArray<ForegroundToken>();
375
376    /**
377     * List of records for processes that someone had tried to start before the
378     * system was ready.  We don't start them at that point, but ensure they
379     * are started by the time booting is complete.
380     */
381    final ArrayList<ProcessRecord> mProcessesOnHold
382            = new ArrayList<ProcessRecord>();
383
384    /**
385     * List of persistent applications that are in the process
386     * of being started.
387     */
388    final ArrayList<ProcessRecord> mPersistentStartingProcesses
389            = new ArrayList<ProcessRecord>();
390
391    /**
392     * Processes that are being forcibly torn down.
393     */
394    final ArrayList<ProcessRecord> mRemovedProcesses
395            = new ArrayList<ProcessRecord>();
396
397    /**
398     * List of running applications, sorted by recent usage.
399     * The first entry in the list is the least recently used.
400     * It contains ApplicationRecord objects.  This list does NOT include
401     * any persistent application records (since we never want to exit them).
402     */
403    final ArrayList<ProcessRecord> mLruProcesses
404            = new ArrayList<ProcessRecord>();
405
406    /**
407     * List of processes that should gc as soon as things are idle.
408     */
409    final ArrayList<ProcessRecord> mProcessesToGc
410            = new ArrayList<ProcessRecord>();
411
412    /**
413     * This is the process holding what we currently consider to be
414     * the "home" activity.
415     */
416    ProcessRecord mHomeProcess;
417
418    /**
419     * This is the process holding the activity the user last visited that
420     * is in a different process from the one they are currently in.
421     */
422    ProcessRecord mPreviousProcess;
423
424    /**
425     * The time at which the previous process was last visible.
426     */
427    long mPreviousProcessVisibleTime;
428
429    /**
430     * Packages that the user has asked to have run in screen size
431     * compatibility mode instead of filling the screen.
432     */
433    final CompatModePackages mCompatModePackages;
434
435    /**
436     * Set of PendingResultRecord objects that are currently active.
437     */
438    final HashSet mPendingResultRecords = new HashSet();
439
440    /**
441     * Set of IntentSenderRecord objects that are currently active.
442     */
443    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
444            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
445
446    /**
447     * Fingerprints (hashCode()) of stack traces that we've
448     * already logged DropBox entries for.  Guarded by itself.  If
449     * something (rogue user app) forces this over
450     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
451     */
452    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
453    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
454
455    /**
456     * Strict Mode background batched logging state.
457     *
458     * The string buffer is guarded by itself, and its lock is also
459     * used to determine if another batched write is already
460     * in-flight.
461     */
462    private final StringBuilder mStrictModeBuffer = new StringBuilder();
463
464    /**
465     * Keeps track of all IIntentReceivers that have been registered for
466     * broadcasts.  Hash keys are the receiver IBinder, hash value is
467     * a ReceiverList.
468     */
469    final HashMap mRegisteredReceivers = new HashMap();
470
471    /**
472     * Resolver for broadcast intents to registered receivers.
473     * Holds BroadcastFilter (subclass of IntentFilter).
474     */
475    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
476            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
477        @Override
478        protected boolean allowFilterResult(
479                BroadcastFilter filter, List<BroadcastFilter> dest) {
480            IBinder target = filter.receiverList.receiver.asBinder();
481            for (int i=dest.size()-1; i>=0; i--) {
482                if (dest.get(i).receiverList.receiver.asBinder() == target) {
483                    return false;
484                }
485            }
486            return true;
487        }
488
489        @Override
490        protected BroadcastFilter[] newArray(int size) {
491            return new BroadcastFilter[size];
492        }
493
494        @Override
495        protected String packageForFilter(BroadcastFilter filter) {
496            return filter.packageName;
497        }
498    };
499
500    /**
501     * State of all active sticky broadcasts.  Keys are the action of the
502     * sticky Intent, values are an ArrayList of all broadcasted intents with
503     * that action (which should usually be one).
504     */
505    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
506            new HashMap<String, ArrayList<Intent>>();
507
508    final ActiveServices mServices;
509
510    /**
511     * Backup/restore process management
512     */
513    String mBackupAppName = null;
514    BackupRecord mBackupTarget = null;
515
516    /**
517     * List of PendingThumbnailsRecord objects of clients who are still
518     * waiting to receive all of the thumbnails for a task.
519     */
520    final ArrayList mPendingThumbnails = new ArrayList();
521
522    /**
523     * List of HistoryRecord objects that have been finished and must
524     * still report back to a pending thumbnail receiver.
525     */
526    final ArrayList mCancelledThumbnails = new ArrayList();
527
528    final ProviderMap mProviderMap = new ProviderMap();
529
530    /**
531     * List of content providers who have clients waiting for them.  The
532     * application is currently being launched and the provider will be
533     * removed from this list once it is published.
534     */
535    final ArrayList<ContentProviderRecord> mLaunchingProviders
536            = new ArrayList<ContentProviderRecord>();
537
538    /**
539     * Global set of specific Uri permissions that have been granted.
540     */
541    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
542            = new SparseArray<HashMap<Uri, UriPermission>>();
543
544    CoreSettingsObserver mCoreSettingsObserver;
545
546    /**
547     * Thread-local storage used to carry caller permissions over through
548     * indirect content-provider access.
549     * @see #ActivityManagerService.openContentUri()
550     */
551    private class Identity {
552        public int pid;
553        public int uid;
554
555        Identity(int _pid, int _uid) {
556            pid = _pid;
557            uid = _uid;
558        }
559    }
560
561    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
562
563    /**
564     * All information we have collected about the runtime performance of
565     * any user id that can impact battery performance.
566     */
567    final BatteryStatsService mBatteryStatsService;
568
569    /**
570     * information about component usage
571     */
572    final UsageStatsService mUsageStatsService;
573
574    /**
575     * Current configuration information.  HistoryRecord objects are given
576     * a reference to this object to indicate which configuration they are
577     * currently running in, so this object must be kept immutable.
578     */
579    Configuration mConfiguration = new Configuration();
580
581    /**
582     * Current sequencing integer of the configuration, for skipping old
583     * configurations.
584     */
585    int mConfigurationSeq = 0;
586
587    /**
588     * Hardware-reported OpenGLES version.
589     */
590    final int GL_ES_VERSION;
591
592    /**
593     * List of initialization arguments to pass to all processes when binding applications to them.
594     * For example, references to the commonly used services.
595     */
596    HashMap<String, IBinder> mAppBindArgs;
597
598    /**
599     * Temporary to avoid allocations.  Protected by main lock.
600     */
601    final StringBuilder mStringBuilder = new StringBuilder(256);
602
603    /**
604     * Used to control how we initialize the service.
605     */
606    boolean mStartRunning = false;
607    ComponentName mTopComponent;
608    String mTopAction;
609    String mTopData;
610    boolean mProcessesReady = false;
611    boolean mSystemReady = false;
612    boolean mBooting = false;
613    boolean mWaitingUpdate = false;
614    boolean mDidUpdate = false;
615    boolean mOnBattery = false;
616    boolean mLaunchWarningShown = false;
617
618    Context mContext;
619
620    int mFactoryTest;
621
622    boolean mCheckedForSetup;
623
624    /**
625     * The time at which we will allow normal application switches again,
626     * after a call to {@link #stopAppSwitches()}.
627     */
628    long mAppSwitchesAllowedTime;
629
630    /**
631     * This is set to true after the first switch after mAppSwitchesAllowedTime
632     * is set; any switches after that will clear the time.
633     */
634    boolean mDidAppSwitch;
635
636    /**
637     * Last time (in realtime) at which we checked for power usage.
638     */
639    long mLastPowerCheckRealtime;
640
641    /**
642     * Last time (in uptime) at which we checked for power usage.
643     */
644    long mLastPowerCheckUptime;
645
646    /**
647     * Set while we are wanting to sleep, to prevent any
648     * activities from being started/resumed.
649     */
650    boolean mSleeping = false;
651
652    /**
653     * State of external calls telling us if the device is asleep.
654     */
655    boolean mWentToSleep = false;
656
657    /**
658     * State of external call telling us if the lock screen is shown.
659     */
660    boolean mLockScreenShown = false;
661
662    /**
663     * Set if we are shutting down the system, similar to sleeping.
664     */
665    boolean mShuttingDown = false;
666
667    /**
668     * Task identifier that activities are currently being started
669     * in.  Incremented each time a new task is created.
670     * todo: Replace this with a TokenSpace class that generates non-repeating
671     * integers that won't wrap.
672     */
673    int mCurTask = 1;
674
675    /**
676     * Current sequence id for oom_adj computation traversal.
677     */
678    int mAdjSeq = 0;
679
680    /**
681     * Current sequence id for process LRU updating.
682     */
683    int mLruSeq = 0;
684
685    /**
686     * Keep track of the non-hidden/empty process we last found, to help
687     * determine how to distribute hidden/empty processes next time.
688     */
689    int mNumNonHiddenProcs = 0;
690
691    /**
692     * Keep track of the number of hidden procs, to balance oom adj
693     * distribution between those and empty procs.
694     */
695    int mNumHiddenProcs = 0;
696
697    /**
698     * Keep track of the number of service processes we last found, to
699     * determine on the next iteration which should be B services.
700     */
701    int mNumServiceProcs = 0;
702    int mNewNumServiceProcs = 0;
703
704    /**
705     * System monitoring: number of processes that died since the last
706     * N procs were started.
707     */
708    int[] mProcDeaths = new int[20];
709
710    /**
711     * This is set if we had to do a delayed dexopt of an app before launching
712     * it, to increasing the ANR timeouts in that case.
713     */
714    boolean mDidDexOpt;
715
716    String mDebugApp = null;
717    boolean mWaitForDebugger = false;
718    boolean mDebugTransient = false;
719    String mOrigDebugApp = null;
720    boolean mOrigWaitForDebugger = false;
721    boolean mAlwaysFinishActivities = false;
722    IActivityController mController = null;
723    String mProfileApp = null;
724    ProcessRecord mProfileProc = null;
725    String mProfileFile;
726    ParcelFileDescriptor mProfileFd;
727    int mProfileType = 0;
728    boolean mAutoStopProfiler = false;
729    String mOpenGlTraceApp = null;
730
731    static class ProcessChangeItem {
732        static final int CHANGE_ACTIVITIES = 1<<0;
733        static final int CHANGE_IMPORTANCE= 1<<1;
734        int changes;
735        int uid;
736        int pid;
737        int importance;
738        boolean foregroundActivities;
739    }
740
741    final RemoteCallbackList<IProcessObserver> mProcessObservers
742            = new RemoteCallbackList<IProcessObserver>();
743    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
744
745    final ArrayList<ProcessChangeItem> mPendingProcessChanges
746            = new ArrayList<ProcessChangeItem>();
747    final ArrayList<ProcessChangeItem> mAvailProcessChanges
748            = new ArrayList<ProcessChangeItem>();
749
750    /**
751     * Callback of last caller to {@link #requestPss}.
752     */
753    Runnable mRequestPssCallback;
754
755    /**
756     * Remaining processes for which we are waiting results from the last
757     * call to {@link #requestPss}.
758     */
759    final ArrayList<ProcessRecord> mRequestPssList
760            = new ArrayList<ProcessRecord>();
761
762    /**
763     * Runtime statistics collection thread.  This object's lock is used to
764     * protect all related state.
765     */
766    final Thread mProcessStatsThread;
767
768    /**
769     * Used to collect process stats when showing not responding dialog.
770     * Protected by mProcessStatsThread.
771     */
772    final ProcessStats mProcessStats = new ProcessStats(
773            MONITOR_THREAD_CPU_USAGE);
774    final AtomicLong mLastCpuTime = new AtomicLong(0);
775    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
776
777    long mLastWriteTime = 0;
778
779    /**
780     * Set to true after the system has finished booting.
781     */
782    boolean mBooted = false;
783
784    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
785    int mProcessLimitOverride = -1;
786
787    WindowManagerService mWindowManager;
788
789    static ActivityManagerService mSelf;
790    static ActivityThread mSystemThread;
791
792    private int mCurrentUserId;
793    private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
794    private UserManager mUserManager;
795
796    private final class AppDeathRecipient implements IBinder.DeathRecipient {
797        final ProcessRecord mApp;
798        final int mPid;
799        final IApplicationThread mAppThread;
800
801        AppDeathRecipient(ProcessRecord app, int pid,
802                IApplicationThread thread) {
803            if (localLOGV) Slog.v(
804                TAG, "New death recipient " + this
805                + " for thread " + thread.asBinder());
806            mApp = app;
807            mPid = pid;
808            mAppThread = thread;
809        }
810
811        public void binderDied() {
812            if (localLOGV) Slog.v(
813                TAG, "Death received in " + this
814                + " for thread " + mAppThread.asBinder());
815            synchronized(ActivityManagerService.this) {
816                appDiedLocked(mApp, mPid, mAppThread);
817            }
818        }
819    }
820
821    static final int SHOW_ERROR_MSG = 1;
822    static final int SHOW_NOT_RESPONDING_MSG = 2;
823    static final int SHOW_FACTORY_ERROR_MSG = 3;
824    static final int UPDATE_CONFIGURATION_MSG = 4;
825    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
826    static final int WAIT_FOR_DEBUGGER_MSG = 6;
827    static final int SERVICE_TIMEOUT_MSG = 12;
828    static final int UPDATE_TIME_ZONE = 13;
829    static final int SHOW_UID_ERROR_MSG = 14;
830    static final int IM_FEELING_LUCKY_MSG = 15;
831    static final int PROC_START_TIMEOUT_MSG = 20;
832    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
833    static final int KILL_APPLICATION_MSG = 22;
834    static final int FINALIZE_PENDING_INTENT_MSG = 23;
835    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
836    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
837    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
838    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
839    static final int CLEAR_DNS_CACHE = 28;
840    static final int UPDATE_HTTP_PROXY = 29;
841    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
842    static final int DISPATCH_PROCESSES_CHANGED = 31;
843    static final int DISPATCH_PROCESS_DIED = 32;
844    static final int REPORT_MEM_USAGE = 33;
845
846    static final int FIRST_ACTIVITY_STACK_MSG = 100;
847    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
848    static final int FIRST_COMPAT_MODE_MSG = 300;
849
850    AlertDialog mUidAlert;
851    CompatModeDialog mCompatModeDialog;
852    long mLastMemUsageReportTime = 0;
853
854    final Handler mHandler = new Handler() {
855        //public Handler() {
856        //    if (localLOGV) Slog.v(TAG, "Handler started!");
857        //}
858
859        public void handleMessage(Message msg) {
860            switch (msg.what) {
861            case SHOW_ERROR_MSG: {
862                HashMap data = (HashMap) msg.obj;
863                synchronized (ActivityManagerService.this) {
864                    ProcessRecord proc = (ProcessRecord)data.get("app");
865                    if (proc != null && proc.crashDialog != null) {
866                        Slog.e(TAG, "App already has crash dialog: " + proc);
867                        return;
868                    }
869                    AppErrorResult res = (AppErrorResult) data.get("result");
870                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
871                        Dialog d = new AppErrorDialog(mContext, res, proc);
872                        d.show();
873                        proc.crashDialog = d;
874                    } else {
875                        // The device is asleep, so just pretend that the user
876                        // saw a crash dialog and hit "force quit".
877                        res.set(0);
878                    }
879                }
880
881                ensureBootCompleted();
882            } break;
883            case SHOW_NOT_RESPONDING_MSG: {
884                synchronized (ActivityManagerService.this) {
885                    HashMap data = (HashMap) msg.obj;
886                    ProcessRecord proc = (ProcessRecord)data.get("app");
887                    if (proc != null && proc.anrDialog != null) {
888                        Slog.e(TAG, "App already has anr dialog: " + proc);
889                        return;
890                    }
891
892                    Intent intent = new Intent("android.intent.action.ANR");
893                    if (!mProcessesReady) {
894                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
895                                | Intent.FLAG_RECEIVER_FOREGROUND);
896                    }
897                    broadcastIntentLocked(null, null, intent,
898                            null, null, 0, null, null, null,
899                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
900
901                    if (mShowDialogs) {
902                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
903                                mContext, proc, (ActivityRecord)data.get("activity"));
904                        d.show();
905                        proc.anrDialog = d;
906                    } else {
907                        // Just kill the app if there is no dialog to be shown.
908                        killAppAtUsersRequest(proc, null);
909                    }
910                }
911
912                ensureBootCompleted();
913            } break;
914            case SHOW_STRICT_MODE_VIOLATION_MSG: {
915                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
916                synchronized (ActivityManagerService.this) {
917                    ProcessRecord proc = (ProcessRecord) data.get("app");
918                    if (proc == null) {
919                        Slog.e(TAG, "App not found when showing strict mode dialog.");
920                        break;
921                    }
922                    if (proc.crashDialog != null) {
923                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
924                        return;
925                    }
926                    AppErrorResult res = (AppErrorResult) data.get("result");
927                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
928                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
929                        d.show();
930                        proc.crashDialog = d;
931                    } else {
932                        // The device is asleep, so just pretend that the user
933                        // saw a crash dialog and hit "force quit".
934                        res.set(0);
935                    }
936                }
937                ensureBootCompleted();
938            } break;
939            case SHOW_FACTORY_ERROR_MSG: {
940                Dialog d = new FactoryErrorDialog(
941                    mContext, msg.getData().getCharSequence("msg"));
942                d.show();
943                ensureBootCompleted();
944            } break;
945            case UPDATE_CONFIGURATION_MSG: {
946                final ContentResolver resolver = mContext.getContentResolver();
947                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
948            } break;
949            case GC_BACKGROUND_PROCESSES_MSG: {
950                synchronized (ActivityManagerService.this) {
951                    performAppGcsIfAppropriateLocked();
952                }
953            } break;
954            case WAIT_FOR_DEBUGGER_MSG: {
955                synchronized (ActivityManagerService.this) {
956                    ProcessRecord app = (ProcessRecord)msg.obj;
957                    if (msg.arg1 != 0) {
958                        if (!app.waitedForDebugger) {
959                            Dialog d = new AppWaitingForDebuggerDialog(
960                                    ActivityManagerService.this,
961                                    mContext, app);
962                            app.waitDialog = d;
963                            app.waitedForDebugger = true;
964                            d.show();
965                        }
966                    } else {
967                        if (app.waitDialog != null) {
968                            app.waitDialog.dismiss();
969                            app.waitDialog = null;
970                        }
971                    }
972                }
973            } break;
974            case SERVICE_TIMEOUT_MSG: {
975                if (mDidDexOpt) {
976                    mDidDexOpt = false;
977                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
978                    nmsg.obj = msg.obj;
979                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
980                    return;
981                }
982                mServices.serviceTimeout((ProcessRecord)msg.obj);
983            } break;
984            case UPDATE_TIME_ZONE: {
985                synchronized (ActivityManagerService.this) {
986                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
987                        ProcessRecord r = mLruProcesses.get(i);
988                        if (r.thread != null) {
989                            try {
990                                r.thread.updateTimeZone();
991                            } catch (RemoteException ex) {
992                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
993                            }
994                        }
995                    }
996                }
997            } break;
998            case CLEAR_DNS_CACHE: {
999                synchronized (ActivityManagerService.this) {
1000                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1001                        ProcessRecord r = mLruProcesses.get(i);
1002                        if (r.thread != null) {
1003                            try {
1004                                r.thread.clearDnsCache();
1005                            } catch (RemoteException ex) {
1006                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1007                            }
1008                        }
1009                    }
1010                }
1011            } break;
1012            case UPDATE_HTTP_PROXY: {
1013                ProxyProperties proxy = (ProxyProperties)msg.obj;
1014                String host = "";
1015                String port = "";
1016                String exclList = "";
1017                if (proxy != null) {
1018                    host = proxy.getHost();
1019                    port = Integer.toString(proxy.getPort());
1020                    exclList = proxy.getExclusionList();
1021                }
1022                synchronized (ActivityManagerService.this) {
1023                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1024                        ProcessRecord r = mLruProcesses.get(i);
1025                        if (r.thread != null) {
1026                            try {
1027                                r.thread.setHttpProxy(host, port, exclList);
1028                            } catch (RemoteException ex) {
1029                                Slog.w(TAG, "Failed to update http proxy for: " +
1030                                        r.info.processName);
1031                            }
1032                        }
1033                    }
1034                }
1035            } break;
1036            case SHOW_UID_ERROR_MSG: {
1037                String title = "System UIDs Inconsistent";
1038                String text = "UIDs on the system are inconsistent, you need to wipe your"
1039                        + " data partition or your device will be unstable.";
1040                Log.e(TAG, title + ": " + text);
1041                if (mShowDialogs) {
1042                    // XXX This is a temporary dialog, no need to localize.
1043                    AlertDialog d = new BaseErrorDialog(mContext);
1044                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1045                    d.setCancelable(false);
1046                    d.setTitle(title);
1047                    d.setMessage(text);
1048                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1049                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1050                    mUidAlert = d;
1051                    d.show();
1052                }
1053            } break;
1054            case IM_FEELING_LUCKY_MSG: {
1055                if (mUidAlert != null) {
1056                    mUidAlert.dismiss();
1057                    mUidAlert = null;
1058                }
1059            } break;
1060            case PROC_START_TIMEOUT_MSG: {
1061                if (mDidDexOpt) {
1062                    mDidDexOpt = false;
1063                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1064                    nmsg.obj = msg.obj;
1065                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1066                    return;
1067                }
1068                ProcessRecord app = (ProcessRecord)msg.obj;
1069                synchronized (ActivityManagerService.this) {
1070                    processStartTimedOutLocked(app);
1071                }
1072            } break;
1073            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1074                synchronized (ActivityManagerService.this) {
1075                    doPendingActivityLaunchesLocked(true);
1076                }
1077            } break;
1078            case KILL_APPLICATION_MSG: {
1079                synchronized (ActivityManagerService.this) {
1080                    int uid = msg.arg1;
1081                    boolean restart = (msg.arg2 == 1);
1082                    String pkg = (String) msg.obj;
1083                    forceStopPackageLocked(pkg, uid, restart, false, true, false,
1084                            UserHandle.getUserId(uid));
1085                }
1086            } break;
1087            case FINALIZE_PENDING_INTENT_MSG: {
1088                ((PendingIntentRecord)msg.obj).completeFinalize();
1089            } break;
1090            case POST_HEAVY_NOTIFICATION_MSG: {
1091                INotificationManager inm = NotificationManager.getService();
1092                if (inm == null) {
1093                    return;
1094                }
1095
1096                ActivityRecord root = (ActivityRecord)msg.obj;
1097                ProcessRecord process = root.app;
1098                if (process == null) {
1099                    return;
1100                }
1101
1102                try {
1103                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1104                    String text = mContext.getString(R.string.heavy_weight_notification,
1105                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1106                    Notification notification = new Notification();
1107                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1108                    notification.when = 0;
1109                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1110                    notification.tickerText = text;
1111                    notification.defaults = 0; // please be quiet
1112                    notification.sound = null;
1113                    notification.vibrate = null;
1114                    notification.setLatestEventInfo(context, text,
1115                            mContext.getText(R.string.heavy_weight_notification_detail),
1116                            PendingIntent.getActivity(mContext, 0, root.intent,
1117                                    PendingIntent.FLAG_CANCEL_CURRENT));
1118
1119                    try {
1120                        int[] outId = new int[1];
1121                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
1122                                notification, outId);
1123                    } catch (RuntimeException e) {
1124                        Slog.w(ActivityManagerService.TAG,
1125                                "Error showing notification for heavy-weight app", e);
1126                    } catch (RemoteException e) {
1127                    }
1128                } catch (NameNotFoundException e) {
1129                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1130                }
1131            } break;
1132            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1133                INotificationManager inm = NotificationManager.getService();
1134                if (inm == null) {
1135                    return;
1136                }
1137                try {
1138                    inm.cancelNotification("android",
1139                            R.string.heavy_weight_notification);
1140                } catch (RuntimeException e) {
1141                    Slog.w(ActivityManagerService.TAG,
1142                            "Error canceling notification for service", e);
1143                } catch (RemoteException e) {
1144                }
1145            } break;
1146            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1147                synchronized (ActivityManagerService.this) {
1148                    checkExcessivePowerUsageLocked(true);
1149                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1150                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1151                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1152                }
1153            } break;
1154            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1155                synchronized (ActivityManagerService.this) {
1156                    ActivityRecord ar = (ActivityRecord)msg.obj;
1157                    if (mCompatModeDialog != null) {
1158                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1159                                ar.info.applicationInfo.packageName)) {
1160                            return;
1161                        }
1162                        mCompatModeDialog.dismiss();
1163                        mCompatModeDialog = null;
1164                    }
1165                    if (ar != null && false) {
1166                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1167                                ar.packageName)) {
1168                            int mode = mCompatModePackages.computeCompatModeLocked(
1169                                    ar.info.applicationInfo);
1170                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1171                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1172                                mCompatModeDialog = new CompatModeDialog(
1173                                        ActivityManagerService.this, mContext,
1174                                        ar.info.applicationInfo);
1175                                mCompatModeDialog.show();
1176                            }
1177                        }
1178                    }
1179                }
1180                break;
1181            }
1182            case DISPATCH_PROCESSES_CHANGED: {
1183                dispatchProcessesChanged();
1184                break;
1185            }
1186            case DISPATCH_PROCESS_DIED: {
1187                final int pid = msg.arg1;
1188                final int uid = msg.arg2;
1189                dispatchProcessDied(pid, uid);
1190                break;
1191            }
1192            case REPORT_MEM_USAGE: {
1193                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1194                if (!isDebuggable) {
1195                    return;
1196                }
1197                synchronized (ActivityManagerService.this) {
1198                    long now = SystemClock.uptimeMillis();
1199                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1200                        // Don't report more than every 5 minutes to somewhat
1201                        // avoid spamming.
1202                        return;
1203                    }
1204                    mLastMemUsageReportTime = now;
1205                }
1206                Thread thread = new Thread() {
1207                    @Override public void run() {
1208                        StringBuilder dropBuilder = new StringBuilder(1024);
1209                        StringBuilder logBuilder = new StringBuilder(1024);
1210                        StringWriter oomSw = new StringWriter();
1211                        PrintWriter oomPw = new PrintWriter(oomSw);
1212                        StringWriter catSw = new StringWriter();
1213                        PrintWriter catPw = new PrintWriter(catSw);
1214                        String[] emptyArgs = new String[] { };
1215                        StringBuilder tag = new StringBuilder(128);
1216                        StringBuilder stack = new StringBuilder(128);
1217                        tag.append("Low on memory -- ");
1218                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1219                                tag, stack);
1220                        dropBuilder.append(stack);
1221                        dropBuilder.append('\n');
1222                        dropBuilder.append('\n');
1223                        String oomString = oomSw.toString();
1224                        dropBuilder.append(oomString);
1225                        dropBuilder.append('\n');
1226                        logBuilder.append(oomString);
1227                        try {
1228                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1229                                    "procrank", });
1230                            final InputStreamReader converter = new InputStreamReader(
1231                                    proc.getInputStream());
1232                            BufferedReader in = new BufferedReader(converter);
1233                            String line;
1234                            while (true) {
1235                                line = in.readLine();
1236                                if (line == null) {
1237                                    break;
1238                                }
1239                                if (line.length() > 0) {
1240                                    logBuilder.append(line);
1241                                    logBuilder.append('\n');
1242                                }
1243                                dropBuilder.append(line);
1244                                dropBuilder.append('\n');
1245                            }
1246                            converter.close();
1247                        } catch (IOException e) {
1248                        }
1249                        synchronized (ActivityManagerService.this) {
1250                            catPw.println();
1251                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1252                            catPw.println();
1253                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1254                                    false, false, null);
1255                            catPw.println();
1256                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1257                        }
1258                        dropBuilder.append(catSw.toString());
1259                        addErrorToDropBox("lowmem", null, "system_server", null,
1260                                null, tag.toString(), dropBuilder.toString(), null, null);
1261                        Slog.i(TAG, logBuilder.toString());
1262                        synchronized (ActivityManagerService.this) {
1263                            long now = SystemClock.uptimeMillis();
1264                            if (mLastMemUsageReportTime < now) {
1265                                mLastMemUsageReportTime = now;
1266                            }
1267                        }
1268                    }
1269                };
1270                thread.start();
1271                break;
1272            }
1273            }
1274        }
1275    };
1276
1277    public static void setSystemProcess() {
1278        try {
1279            ActivityManagerService m = mSelf;
1280
1281            ServiceManager.addService("activity", m, true);
1282            ServiceManager.addService("meminfo", new MemBinder(m));
1283            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1284            ServiceManager.addService("dbinfo", new DbBinder(m));
1285            if (MONITOR_CPU_USAGE) {
1286                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1287            }
1288            ServiceManager.addService("permission", new PermissionController(m));
1289
1290            ApplicationInfo info =
1291                mSelf.mContext.getPackageManager().getApplicationInfo(
1292                            "android", STOCK_PM_FLAGS);
1293            mSystemThread.installSystemApplicationInfo(info);
1294
1295            synchronized (mSelf) {
1296                ProcessRecord app = mSelf.newProcessRecordLocked(
1297                        mSystemThread.getApplicationThread(), info,
1298                        info.processName, false);
1299                app.persistent = true;
1300                app.pid = MY_PID;
1301                app.maxAdj = ProcessList.SYSTEM_ADJ;
1302                mSelf.mProcessNames.put(app.processName, app.uid, app);
1303                synchronized (mSelf.mPidsSelfLocked) {
1304                    mSelf.mPidsSelfLocked.put(app.pid, app);
1305                }
1306                mSelf.updateLruProcessLocked(app, true, true);
1307            }
1308        } catch (PackageManager.NameNotFoundException e) {
1309            throw new RuntimeException(
1310                    "Unable to find android system package", e);
1311        }
1312    }
1313
1314    public void setWindowManager(WindowManagerService wm) {
1315        mWindowManager = wm;
1316    }
1317
1318    public static final Context main(int factoryTest) {
1319        AThread thr = new AThread();
1320        thr.start();
1321
1322        synchronized (thr) {
1323            while (thr.mService == null) {
1324                try {
1325                    thr.wait();
1326                } catch (InterruptedException e) {
1327                }
1328            }
1329        }
1330
1331        ActivityManagerService m = thr.mService;
1332        mSelf = m;
1333        ActivityThread at = ActivityThread.systemMain();
1334        mSystemThread = at;
1335        Context context = at.getSystemContext();
1336        context.setTheme(android.R.style.Theme_Holo);
1337        m.mContext = context;
1338        m.mFactoryTest = factoryTest;
1339        m.mMainStack = new ActivityStack(m, context, true);
1340
1341        m.mBatteryStatsService.publish(context);
1342        m.mUsageStatsService.publish(context);
1343
1344        synchronized (thr) {
1345            thr.mReady = true;
1346            thr.notifyAll();
1347        }
1348
1349        m.startRunning(null, null, null, null);
1350
1351        return context;
1352    }
1353
1354    public static ActivityManagerService self() {
1355        return mSelf;
1356    }
1357
1358    static class AThread extends Thread {
1359        ActivityManagerService mService;
1360        boolean mReady = false;
1361
1362        public AThread() {
1363            super("ActivityManager");
1364        }
1365
1366        public void run() {
1367            Looper.prepare();
1368
1369            android.os.Process.setThreadPriority(
1370                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1371            android.os.Process.setCanSelfBackground(false);
1372
1373            ActivityManagerService m = new ActivityManagerService();
1374
1375            synchronized (this) {
1376                mService = m;
1377                notifyAll();
1378            }
1379
1380            synchronized (this) {
1381                while (!mReady) {
1382                    try {
1383                        wait();
1384                    } catch (InterruptedException e) {
1385                    }
1386                }
1387            }
1388
1389            // For debug builds, log event loop stalls to dropbox for analysis.
1390            if (StrictMode.conditionallyEnableDebugLogging()) {
1391                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1392            }
1393
1394            Looper.loop();
1395        }
1396    }
1397
1398    static class MemBinder extends Binder {
1399        ActivityManagerService mActivityManagerService;
1400        MemBinder(ActivityManagerService activityManagerService) {
1401            mActivityManagerService = activityManagerService;
1402        }
1403
1404        @Override
1405        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1406            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1407                    != PackageManager.PERMISSION_GRANTED) {
1408                pw.println("Permission Denial: can't dump meminfo from from pid="
1409                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1410                        + " without permission " + android.Manifest.permission.DUMP);
1411                return;
1412            }
1413
1414            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1415                    false, null, null, null);
1416        }
1417    }
1418
1419    static class GraphicsBinder extends Binder {
1420        ActivityManagerService mActivityManagerService;
1421        GraphicsBinder(ActivityManagerService activityManagerService) {
1422            mActivityManagerService = activityManagerService;
1423        }
1424
1425        @Override
1426        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1427            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1428                    != PackageManager.PERMISSION_GRANTED) {
1429                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1430                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1431                        + " without permission " + android.Manifest.permission.DUMP);
1432                return;
1433            }
1434
1435            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1436        }
1437    }
1438
1439    static class DbBinder extends Binder {
1440        ActivityManagerService mActivityManagerService;
1441        DbBinder(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 dbinfo from from pid="
1450                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1451                        + " without permission " + android.Manifest.permission.DUMP);
1452                return;
1453            }
1454
1455            mActivityManagerService.dumpDbInfo(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        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1487        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1488        mBroadcastQueues[0] = mFgBroadcastQueue;
1489        mBroadcastQueues[1] = mBgBroadcastQueue;
1490
1491        mServices = new ActiveServices(this);
1492
1493        File dataDir = Environment.getDataDirectory();
1494        File systemDir = new File(dataDir, "system");
1495        systemDir.mkdirs();
1496        mBatteryStatsService = new BatteryStatsService(new File(
1497                systemDir, "batterystats.bin").toString());
1498        mBatteryStatsService.getActiveStatistics().readLocked();
1499        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1500        mOnBattery = DEBUG_POWER ? true
1501                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1502        mBatteryStatsService.getActiveStatistics().setCallback(this);
1503
1504        mUsageStatsService = new UsageStatsService(new File(
1505                systemDir, "usagestats").toString());
1506        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1507
1508        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1509            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1510
1511        mConfiguration.setToDefaults();
1512        mConfiguration.locale = Locale.getDefault();
1513        mConfigurationSeq = mConfiguration.seq = 1;
1514        mProcessStats.init();
1515
1516        mCompatModePackages = new CompatModePackages(this, systemDir);
1517
1518        // Add ourself to the Watchdog monitors.
1519        Watchdog.getInstance().addMonitor(this);
1520
1521        mProcessStatsThread = new Thread("ProcessStats") {
1522            public void run() {
1523                while (true) {
1524                    try {
1525                        try {
1526                            synchronized(this) {
1527                                final long now = SystemClock.uptimeMillis();
1528                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1529                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1530                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1531                                //        + ", write delay=" + nextWriteDelay);
1532                                if (nextWriteDelay < nextCpuDelay) {
1533                                    nextCpuDelay = nextWriteDelay;
1534                                }
1535                                if (nextCpuDelay > 0) {
1536                                    mProcessStatsMutexFree.set(true);
1537                                    this.wait(nextCpuDelay);
1538                                }
1539                            }
1540                        } catch (InterruptedException e) {
1541                        }
1542                        updateCpuStatsNow();
1543                    } catch (Exception e) {
1544                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1545                    }
1546                }
1547            }
1548        };
1549        mProcessStatsThread.start();
1550    }
1551
1552    @Override
1553    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1554            throws RemoteException {
1555        if (code == SYSPROPS_TRANSACTION) {
1556            // We need to tell all apps about the system property change.
1557            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1558            synchronized(this) {
1559                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1560                    final int NA = apps.size();
1561                    for (int ia=0; ia<NA; ia++) {
1562                        ProcessRecord app = apps.valueAt(ia);
1563                        if (app.thread != null) {
1564                            procs.add(app.thread.asBinder());
1565                        }
1566                    }
1567                }
1568            }
1569
1570            int N = procs.size();
1571            for (int i=0; i<N; i++) {
1572                Parcel data2 = Parcel.obtain();
1573                try {
1574                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1575                } catch (RemoteException e) {
1576                }
1577                data2.recycle();
1578            }
1579        }
1580        try {
1581            return super.onTransact(code, data, reply, flags);
1582        } catch (RuntimeException e) {
1583            // The activity manager only throws security exceptions, so let's
1584            // log all others.
1585            if (!(e instanceof SecurityException)) {
1586                Slog.e(TAG, "Activity Manager Crash", e);
1587            }
1588            throw e;
1589        }
1590    }
1591
1592    void updateCpuStats() {
1593        final long now = SystemClock.uptimeMillis();
1594        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1595            return;
1596        }
1597        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1598            synchronized (mProcessStatsThread) {
1599                mProcessStatsThread.notify();
1600            }
1601        }
1602    }
1603
1604    void updateCpuStatsNow() {
1605        synchronized (mProcessStatsThread) {
1606            mProcessStatsMutexFree.set(false);
1607            final long now = SystemClock.uptimeMillis();
1608            boolean haveNewCpuStats = false;
1609
1610            if (MONITOR_CPU_USAGE &&
1611                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1612                mLastCpuTime.set(now);
1613                haveNewCpuStats = true;
1614                mProcessStats.update();
1615                //Slog.i(TAG, mProcessStats.printCurrentState());
1616                //Slog.i(TAG, "Total CPU usage: "
1617                //        + mProcessStats.getTotalCpuPercent() + "%");
1618
1619                // Slog the cpu usage if the property is set.
1620                if ("true".equals(SystemProperties.get("events.cpu"))) {
1621                    int user = mProcessStats.getLastUserTime();
1622                    int system = mProcessStats.getLastSystemTime();
1623                    int iowait = mProcessStats.getLastIoWaitTime();
1624                    int irq = mProcessStats.getLastIrqTime();
1625                    int softIrq = mProcessStats.getLastSoftIrqTime();
1626                    int idle = mProcessStats.getLastIdleTime();
1627
1628                    int total = user + system + iowait + irq + softIrq + idle;
1629                    if (total == 0) total = 1;
1630
1631                    EventLog.writeEvent(EventLogTags.CPU,
1632                            ((user+system+iowait+irq+softIrq) * 100) / total,
1633                            (user * 100) / total,
1634                            (system * 100) / total,
1635                            (iowait * 100) / total,
1636                            (irq * 100) / total,
1637                            (softIrq * 100) / total);
1638                }
1639            }
1640
1641            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1642            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1643            synchronized(bstats) {
1644                synchronized(mPidsSelfLocked) {
1645                    if (haveNewCpuStats) {
1646                        if (mOnBattery) {
1647                            int perc = bstats.startAddingCpuLocked();
1648                            int totalUTime = 0;
1649                            int totalSTime = 0;
1650                            final int N = mProcessStats.countStats();
1651                            for (int i=0; i<N; i++) {
1652                                ProcessStats.Stats st = mProcessStats.getStats(i);
1653                                if (!st.working) {
1654                                    continue;
1655                                }
1656                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1657                                int otherUTime = (st.rel_utime*perc)/100;
1658                                int otherSTime = (st.rel_stime*perc)/100;
1659                                totalUTime += otherUTime;
1660                                totalSTime += otherSTime;
1661                                if (pr != null) {
1662                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1663                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1664                                            st.rel_stime-otherSTime);
1665                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1666                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1667                                } else {
1668                                    BatteryStatsImpl.Uid.Proc ps =
1669                                            bstats.getProcessStatsLocked(st.name, st.pid);
1670                                    if (ps != null) {
1671                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1672                                                st.rel_stime-otherSTime);
1673                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1674                                    }
1675                                }
1676                            }
1677                            bstats.finishAddingCpuLocked(perc, totalUTime,
1678                                    totalSTime, cpuSpeedTimes);
1679                        }
1680                    }
1681                }
1682
1683                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1684                    mLastWriteTime = now;
1685                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1686                }
1687            }
1688        }
1689    }
1690
1691    @Override
1692    public void batteryNeedsCpuUpdate() {
1693        updateCpuStatsNow();
1694    }
1695
1696    @Override
1697    public void batteryPowerChanged(boolean onBattery) {
1698        // When plugging in, update the CPU stats first before changing
1699        // the plug state.
1700        updateCpuStatsNow();
1701        synchronized (this) {
1702            synchronized(mPidsSelfLocked) {
1703                mOnBattery = DEBUG_POWER ? true : onBattery;
1704            }
1705        }
1706    }
1707
1708    /**
1709     * Initialize the application bind args. These are passed to each
1710     * process when the bindApplication() IPC is sent to the process. They're
1711     * lazily setup to make sure the services are running when they're asked for.
1712     */
1713    private HashMap<String, IBinder> getCommonServicesLocked() {
1714        if (mAppBindArgs == null) {
1715            mAppBindArgs = new HashMap<String, IBinder>();
1716
1717            // Setup the application init args
1718            mAppBindArgs.put("package", ServiceManager.getService("package"));
1719            mAppBindArgs.put("window", ServiceManager.getService("window"));
1720            mAppBindArgs.put(Context.ALARM_SERVICE,
1721                    ServiceManager.getService(Context.ALARM_SERVICE));
1722        }
1723        return mAppBindArgs;
1724    }
1725
1726    final void setFocusedActivityLocked(ActivityRecord r) {
1727        if (mFocusedActivity != r) {
1728            mFocusedActivity = r;
1729            if (r != null) {
1730                mWindowManager.setFocusedApp(r.appToken, true);
1731            }
1732        }
1733    }
1734
1735    private final void updateLruProcessInternalLocked(ProcessRecord app,
1736            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1737        // put it on the LRU to keep track of when it should be exited.
1738        int lrui = mLruProcesses.indexOf(app);
1739        if (lrui >= 0) mLruProcesses.remove(lrui);
1740
1741        int i = mLruProcesses.size()-1;
1742        int skipTop = 0;
1743
1744        app.lruSeq = mLruSeq;
1745
1746        // compute the new weight for this process.
1747        if (updateActivityTime) {
1748            app.lastActivityTime = SystemClock.uptimeMillis();
1749        }
1750        if (app.activities.size() > 0) {
1751            // If this process has activities, we more strongly want to keep
1752            // it around.
1753            app.lruWeight = app.lastActivityTime;
1754        } else if (app.pubProviders.size() > 0) {
1755            // If this process contains content providers, we want to keep
1756            // it a little more strongly.
1757            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1758            // Also don't let it kick out the first few "real" hidden processes.
1759            skipTop = ProcessList.MIN_HIDDEN_APPS;
1760        } else {
1761            // If this process doesn't have activities, we less strongly
1762            // want to keep it around, and generally want to avoid getting
1763            // in front of any very recently used activities.
1764            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1765            // Also don't let it kick out the first few "real" hidden processes.
1766            skipTop = ProcessList.MIN_HIDDEN_APPS;
1767        }
1768
1769        while (i >= 0) {
1770            ProcessRecord p = mLruProcesses.get(i);
1771            // If this app shouldn't be in front of the first N background
1772            // apps, then skip over that many that are currently hidden.
1773            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1774                skipTop--;
1775            }
1776            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1777                mLruProcesses.add(i+1, app);
1778                break;
1779            }
1780            i--;
1781        }
1782        if (i < 0) {
1783            mLruProcesses.add(0, app);
1784        }
1785
1786        // If the app is currently using a content provider or service,
1787        // bump those processes as well.
1788        if (app.connections.size() > 0) {
1789            for (ConnectionRecord cr : app.connections) {
1790                if (cr.binding != null && cr.binding.service != null
1791                        && cr.binding.service.app != null
1792                        && cr.binding.service.app.lruSeq != mLruSeq) {
1793                    updateLruProcessInternalLocked(cr.binding.service.app, false,
1794                            updateActivityTime, i+1);
1795                }
1796            }
1797        }
1798        for (int j=app.conProviders.size()-1; j>=0; j--) {
1799            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1800            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1801                updateLruProcessInternalLocked(cpr.proc, false,
1802                        updateActivityTime, i+1);
1803            }
1804        }
1805
1806        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1807        if (oomAdj) {
1808            updateOomAdjLocked();
1809        }
1810    }
1811
1812    final void updateLruProcessLocked(ProcessRecord app,
1813            boolean oomAdj, boolean updateActivityTime) {
1814        mLruSeq++;
1815        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1816    }
1817
1818    final ProcessRecord getProcessRecordLocked(
1819            String processName, int uid) {
1820        if (uid == Process.SYSTEM_UID) {
1821            // The system gets to run in any process.  If there are multiple
1822            // processes with the same uid, just pick the first (this
1823            // should never happen).
1824            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1825                    processName);
1826            if (procs == null) return null;
1827            final int N = procs.size();
1828            for (int i = 0; i < N; i++) {
1829                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1830            }
1831        }
1832        ProcessRecord proc = mProcessNames.get(processName, uid);
1833        return proc;
1834    }
1835
1836    void ensurePackageDexOpt(String packageName) {
1837        IPackageManager pm = AppGlobals.getPackageManager();
1838        try {
1839            if (pm.performDexOpt(packageName)) {
1840                mDidDexOpt = true;
1841            }
1842        } catch (RemoteException e) {
1843        }
1844    }
1845
1846    boolean isNextTransitionForward() {
1847        int transit = mWindowManager.getPendingAppTransition();
1848        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1849                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1850                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1851    }
1852
1853    final ProcessRecord startProcessLocked(String processName,
1854            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1855            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1856            boolean isolated) {
1857        ProcessRecord app;
1858        if (!isolated) {
1859            app = getProcessRecordLocked(processName, info.uid);
1860        } else {
1861            // If this is an isolated process, it can't re-use an existing process.
1862            app = null;
1863        }
1864        // We don't have to do anything more if:
1865        // (1) There is an existing application record; and
1866        // (2) The caller doesn't think it is dead, OR there is no thread
1867        //     object attached to it so we know it couldn't have crashed; and
1868        // (3) There is a pid assigned to it, so it is either starting or
1869        //     already running.
1870        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1871                + " app=" + app + " knownToBeDead=" + knownToBeDead
1872                + " thread=" + (app != null ? app.thread : null)
1873                + " pid=" + (app != null ? app.pid : -1));
1874        if (app != null && app.pid > 0) {
1875            if (!knownToBeDead || app.thread == null) {
1876                // We already have the app running, or are waiting for it to
1877                // come up (we have a pid but not yet its thread), so keep it.
1878                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1879                // If this is a new package in the process, add the package to the list
1880                app.addPackage(info.packageName);
1881                return app;
1882            } else {
1883                // An application record is attached to a previous process,
1884                // clean it up now.
1885                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1886                handleAppDiedLocked(app, true, true);
1887            }
1888        }
1889
1890        String hostingNameStr = hostingName != null
1891                ? hostingName.flattenToShortString() : null;
1892
1893        if (!isolated) {
1894            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1895                // If we are in the background, then check to see if this process
1896                // is bad.  If so, we will just silently fail.
1897                if (mBadProcesses.get(info.processName, info.uid) != null) {
1898                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1899                            + "/" + info.processName);
1900                    return null;
1901                }
1902            } else {
1903                // When the user is explicitly starting a process, then clear its
1904                // crash count so that we won't make it bad until they see at
1905                // least one crash dialog again, and make the process good again
1906                // if it had been bad.
1907                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1908                        + "/" + info.processName);
1909                mProcessCrashTimes.remove(info.processName, info.uid);
1910                if (mBadProcesses.get(info.processName, info.uid) != null) {
1911                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1912                            info.processName);
1913                    mBadProcesses.remove(info.processName, info.uid);
1914                    if (app != null) {
1915                        app.bad = false;
1916                    }
1917                }
1918            }
1919        }
1920
1921        if (app == null) {
1922            app = newProcessRecordLocked(null, info, processName, isolated);
1923            if (app == null) {
1924                Slog.w(TAG, "Failed making new process record for "
1925                        + processName + "/" + info.uid + " isolated=" + isolated);
1926                return null;
1927            }
1928            mProcessNames.put(processName, app.uid, app);
1929            if (isolated) {
1930                mIsolatedProcesses.put(app.uid, app);
1931            }
1932        } else {
1933            // If this is a new package in the process, add the package to the list
1934            app.addPackage(info.packageName);
1935        }
1936
1937        // If the system is not ready yet, then hold off on starting this
1938        // process until it is.
1939        if (!mProcessesReady
1940                && !isAllowedWhileBooting(info)
1941                && !allowWhileBooting) {
1942            if (!mProcessesOnHold.contains(app)) {
1943                mProcessesOnHold.add(app);
1944            }
1945            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1946            return app;
1947        }
1948
1949        startProcessLocked(app, hostingType, hostingNameStr);
1950        return (app.pid != 0) ? app : null;
1951    }
1952
1953    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1954        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1955    }
1956
1957    private final void startProcessLocked(ProcessRecord app,
1958            String hostingType, String hostingNameStr) {
1959        if (app.pid > 0 && app.pid != MY_PID) {
1960            synchronized (mPidsSelfLocked) {
1961                mPidsSelfLocked.remove(app.pid);
1962                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1963            }
1964            app.setPid(0);
1965        }
1966
1967        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1968                "startProcessLocked removing on hold: " + app);
1969        mProcessesOnHold.remove(app);
1970
1971        updateCpuStats();
1972
1973        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1974        mProcDeaths[0] = 0;
1975
1976        try {
1977            int uid = app.uid;
1978
1979            int[] gids = null;
1980            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
1981            if (!app.isolated) {
1982                try {
1983                    final PackageManager pm = mContext.getPackageManager();
1984                    gids = pm.getPackageGids(app.info.packageName);
1985                    if (pm.checkPermission(
1986                            android.Manifest.permission.READ_EXTERNAL_STORAGE, app.info.packageName)
1987                            == PERMISSION_GRANTED) {
1988                        if (Environment.isExternalStorageEmulated()) {
1989                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
1990                        } else {
1991                            mountExternal = Zygote.MOUNT_EXTERNAL_SINGLEUSER;
1992                        }
1993                    }
1994                } catch (PackageManager.NameNotFoundException e) {
1995                    Slog.w(TAG, "Unable to retrieve gids", e);
1996                }
1997            }
1998            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1999                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2000                        && mTopComponent != null
2001                        && app.processName.equals(mTopComponent.getPackageName())) {
2002                    uid = 0;
2003                }
2004                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2005                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2006                    uid = 0;
2007                }
2008            }
2009            int debugFlags = 0;
2010            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2011                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2012                // Also turn on CheckJNI for debuggable apps. It's quite
2013                // awkward to turn on otherwise.
2014                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2015            }
2016            // Run the app in safe mode if its manifest requests so or the
2017            // system is booted in safe mode.
2018            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2019                Zygote.systemInSafeMode == true) {
2020                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2021            }
2022            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2023                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2024            }
2025            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2026                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2027            }
2028            if ("1".equals(SystemProperties.get("debug.assert"))) {
2029                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2030            }
2031
2032            // Start the process.  It will either succeed and return a result containing
2033            // the PID of the new process, or else throw a RuntimeException.
2034            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2035                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2036                    app.info.targetSdkVersion, null, null);
2037
2038            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2039            synchronized (bs) {
2040                if (bs.isOnBattery()) {
2041                    app.batteryStats.incStartsLocked();
2042                }
2043            }
2044
2045            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2046                    app.processName, hostingType,
2047                    hostingNameStr != null ? hostingNameStr : "");
2048
2049            if (app.persistent) {
2050                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2051            }
2052
2053            StringBuilder buf = mStringBuilder;
2054            buf.setLength(0);
2055            buf.append("Start proc ");
2056            buf.append(app.processName);
2057            buf.append(" for ");
2058            buf.append(hostingType);
2059            if (hostingNameStr != null) {
2060                buf.append(" ");
2061                buf.append(hostingNameStr);
2062            }
2063            buf.append(": pid=");
2064            buf.append(startResult.pid);
2065            buf.append(" uid=");
2066            buf.append(uid);
2067            buf.append(" gids={");
2068            if (gids != null) {
2069                for (int gi=0; gi<gids.length; gi++) {
2070                    if (gi != 0) buf.append(", ");
2071                    buf.append(gids[gi]);
2072
2073                }
2074            }
2075            buf.append("}");
2076            Slog.i(TAG, buf.toString());
2077            app.setPid(startResult.pid);
2078            app.usingWrapper = startResult.usingWrapper;
2079            app.removed = false;
2080            synchronized (mPidsSelfLocked) {
2081                this.mPidsSelfLocked.put(startResult.pid, app);
2082                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2083                msg.obj = app;
2084                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2085                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2086            }
2087        } catch (RuntimeException e) {
2088            // XXX do better error recovery.
2089            app.setPid(0);
2090            Slog.e(TAG, "Failure starting process " + app.processName, e);
2091        }
2092    }
2093
2094    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2095        if (resumed) {
2096            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2097        } else {
2098            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2099        }
2100    }
2101
2102    boolean startHomeActivityLocked(int userId) {
2103        if (mHeadless) {
2104            // Added because none of the other calls to ensureBootCompleted seem to fire
2105            // when running headless.
2106            ensureBootCompleted();
2107            return false;
2108        }
2109
2110        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2111                && mTopAction == null) {
2112            // We are running in factory test mode, but unable to find
2113            // the factory test app, so just sit around displaying the
2114            // error message and don't try to start anything.
2115            return false;
2116        }
2117        Intent intent = new Intent(
2118            mTopAction,
2119            mTopData != null ? Uri.parse(mTopData) : null);
2120        intent.setComponent(mTopComponent);
2121        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2122            intent.addCategory(Intent.CATEGORY_HOME);
2123        }
2124        ActivityInfo aInfo =
2125            intent.resolveActivityInfo(mContext.getPackageManager(),
2126                    STOCK_PM_FLAGS);
2127        if (aInfo != null) {
2128            intent.setComponent(new ComponentName(
2129                    aInfo.applicationInfo.packageName, aInfo.name));
2130            // Don't do this if the home app is currently being
2131            // instrumented.
2132            aInfo = new ActivityInfo(aInfo);
2133            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2134            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2135                    aInfo.applicationInfo.uid);
2136            if (app == null || app.instrumentationClass == null) {
2137                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2138                mMainStack.startActivityLocked(null, intent, null, aInfo,
2139                        null, null, 0, 0, 0, 0, null, false, null);
2140            }
2141        }
2142
2143        return true;
2144    }
2145
2146    /**
2147     * Starts the "new version setup screen" if appropriate.
2148     */
2149    void startSetupActivityLocked() {
2150        // Only do this once per boot.
2151        if (mCheckedForSetup) {
2152            return;
2153        }
2154
2155        // We will show this screen if the current one is a different
2156        // version than the last one shown, and we are not running in
2157        // low-level factory test mode.
2158        final ContentResolver resolver = mContext.getContentResolver();
2159        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2160                Settings.Secure.getInt(resolver,
2161                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2162            mCheckedForSetup = true;
2163
2164            // See if we should be showing the platform update setup UI.
2165            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2166            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2167                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2168
2169            // We don't allow third party apps to replace this.
2170            ResolveInfo ri = null;
2171            for (int i=0; ris != null && i<ris.size(); i++) {
2172                if ((ris.get(i).activityInfo.applicationInfo.flags
2173                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2174                    ri = ris.get(i);
2175                    break;
2176                }
2177            }
2178
2179            if (ri != null) {
2180                String vers = ri.activityInfo.metaData != null
2181                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2182                        : null;
2183                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2184                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2185                            Intent.METADATA_SETUP_VERSION);
2186                }
2187                String lastVers = Settings.Secure.getString(
2188                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2189                if (vers != null && !vers.equals(lastVers)) {
2190                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2191                    intent.setComponent(new ComponentName(
2192                            ri.activityInfo.packageName, ri.activityInfo.name));
2193                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2194                            null, null, 0, 0, 0, 0, null, false, null);
2195                }
2196            }
2197        }
2198    }
2199
2200    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2201        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2202    }
2203
2204    void enforceNotIsolatedCaller(String caller) {
2205        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2206            throw new SecurityException("Isolated process not allowed to call " + caller);
2207        }
2208    }
2209
2210    public int getFrontActivityScreenCompatMode() {
2211        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2212        synchronized (this) {
2213            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2214        }
2215    }
2216
2217    public void setFrontActivityScreenCompatMode(int mode) {
2218        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2219                "setFrontActivityScreenCompatMode");
2220        synchronized (this) {
2221            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2222        }
2223    }
2224
2225    public int getPackageScreenCompatMode(String packageName) {
2226        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2227        synchronized (this) {
2228            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2229        }
2230    }
2231
2232    public void setPackageScreenCompatMode(String packageName, int mode) {
2233        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2234                "setPackageScreenCompatMode");
2235        synchronized (this) {
2236            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2237        }
2238    }
2239
2240    public boolean getPackageAskScreenCompat(String packageName) {
2241        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2242        synchronized (this) {
2243            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2244        }
2245    }
2246
2247    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2248        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2249                "setPackageAskScreenCompat");
2250        synchronized (this) {
2251            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2252        }
2253    }
2254
2255    void reportResumedActivityLocked(ActivityRecord r) {
2256        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2257        updateUsageStats(r, true);
2258    }
2259
2260    private void dispatchProcessesChanged() {
2261        int N;
2262        synchronized (this) {
2263            N = mPendingProcessChanges.size();
2264            if (mActiveProcessChanges.length < N) {
2265                mActiveProcessChanges = new ProcessChangeItem[N];
2266            }
2267            mPendingProcessChanges.toArray(mActiveProcessChanges);
2268            mAvailProcessChanges.addAll(mPendingProcessChanges);
2269            mPendingProcessChanges.clear();
2270            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2271        }
2272        int i = mProcessObservers.beginBroadcast();
2273        while (i > 0) {
2274            i--;
2275            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2276            if (observer != null) {
2277                try {
2278                    for (int j=0; j<N; j++) {
2279                        ProcessChangeItem item = mActiveProcessChanges[j];
2280                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2281                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2282                                    + item.pid + " uid=" + item.uid + ": "
2283                                    + item.foregroundActivities);
2284                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2285                                    item.foregroundActivities);
2286                        }
2287                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2288                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2289                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2290                            observer.onImportanceChanged(item.pid, item.uid,
2291                                    item.importance);
2292                        }
2293                    }
2294                } catch (RemoteException e) {
2295                }
2296            }
2297        }
2298        mProcessObservers.finishBroadcast();
2299    }
2300
2301    private void dispatchProcessDied(int pid, int uid) {
2302        int i = mProcessObservers.beginBroadcast();
2303        while (i > 0) {
2304            i--;
2305            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2306            if (observer != null) {
2307                try {
2308                    observer.onProcessDied(pid, uid);
2309                } catch (RemoteException e) {
2310                }
2311            }
2312        }
2313        mProcessObservers.finishBroadcast();
2314    }
2315
2316    final void doPendingActivityLaunchesLocked(boolean doResume) {
2317        final int N = mPendingActivityLaunches.size();
2318        if (N <= 0) {
2319            return;
2320        }
2321        for (int i=0; i<N; i++) {
2322            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2323            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2324                    pal.startFlags, doResume && i == (N-1), null);
2325        }
2326        mPendingActivityLaunches.clear();
2327    }
2328
2329    public final int startActivity(IApplicationThread caller,
2330            Intent intent, String resolvedType, IBinder resultTo,
2331            String resultWho, int requestCode, int startFlags,
2332            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2333        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2334                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2335    }
2336
2337    public final int startActivityAsUser(IApplicationThread caller,
2338            Intent intent, String resolvedType, IBinder resultTo,
2339            String resultWho, int requestCode, int startFlags,
2340            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2341        enforceNotIsolatedCaller("startActivity");
2342        if (userId != UserHandle.getCallingUserId()) {
2343            // Requesting a different user, make sure that they have the permission
2344            if (checkComponentPermission(
2345                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2346                    Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
2347                    == PackageManager.PERMISSION_GRANTED) {
2348                // Translate to the current user id, if caller wasn't aware
2349                if (userId == UserHandle.USER_CURRENT) {
2350                    userId = mCurrentUserId;
2351                }
2352            } else {
2353                String msg = "Permission Denial: "
2354                        + "Request to startActivity as user " + userId
2355                        + " but is calling from user " + UserHandle.getCallingUserId()
2356                        + "; this requires "
2357                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
2358                Slog.w(TAG, msg);
2359                throw new SecurityException(msg);
2360            }
2361        } else {
2362            if (intent.getCategories() != null
2363                    && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2364                // Requesting home, set the identity to the current user
2365                // HACK!
2366                userId = mCurrentUserId;
2367            } else {
2368                // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
2369                // the current user's userId
2370                if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
2371                    userId = 0;
2372                } else {
2373                    userId = Binder.getOrigCallingUser();
2374                }
2375            }
2376        }
2377        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2378                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2379                null, null, options, userId);
2380    }
2381
2382    public final WaitResult startActivityAndWait(IApplicationThread caller,
2383            Intent intent, String resolvedType, IBinder resultTo,
2384            String resultWho, int requestCode, int startFlags, String profileFile,
2385            ParcelFileDescriptor profileFd, Bundle options) {
2386        enforceNotIsolatedCaller("startActivityAndWait");
2387        WaitResult res = new WaitResult();
2388        int userId = Binder.getOrigCallingUser();
2389        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2390                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2391                res, null, options, userId);
2392        return res;
2393    }
2394
2395    public final int startActivityWithConfig(IApplicationThread caller,
2396            Intent intent, String resolvedType, IBinder resultTo,
2397            String resultWho, int requestCode, int startFlags, Configuration config,
2398            Bundle options) {
2399        enforceNotIsolatedCaller("startActivityWithConfig");
2400        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2401                resultTo, resultWho, requestCode, startFlags,
2402                null, null, null, config, options, Binder.getOrigCallingUser());
2403        return ret;
2404    }
2405
2406    public int startActivityIntentSender(IApplicationThread caller,
2407            IntentSender intent, Intent fillInIntent, String resolvedType,
2408            IBinder resultTo, String resultWho, int requestCode,
2409            int flagsMask, int flagsValues, Bundle options) {
2410        enforceNotIsolatedCaller("startActivityIntentSender");
2411        // Refuse possible leaked file descriptors
2412        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2413            throw new IllegalArgumentException("File descriptors passed in Intent");
2414        }
2415
2416        IIntentSender sender = intent.getTarget();
2417        if (!(sender instanceof PendingIntentRecord)) {
2418            throw new IllegalArgumentException("Bad PendingIntent object");
2419        }
2420
2421        PendingIntentRecord pir = (PendingIntentRecord)sender;
2422
2423        synchronized (this) {
2424            // If this is coming from the currently resumed activity, it is
2425            // effectively saying that app switches are allowed at this point.
2426            if (mMainStack.mResumedActivity != null
2427                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2428                            Binder.getCallingUid()) {
2429                mAppSwitchesAllowedTime = 0;
2430            }
2431        }
2432        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2433                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2434        return ret;
2435    }
2436
2437    public boolean startNextMatchingActivity(IBinder callingActivity,
2438            Intent intent, Bundle options) {
2439        // Refuse possible leaked file descriptors
2440        if (intent != null && intent.hasFileDescriptors() == true) {
2441            throw new IllegalArgumentException("File descriptors passed in Intent");
2442        }
2443
2444        synchronized (this) {
2445            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2446            if (r == null) {
2447                ActivityOptions.abort(options);
2448                return false;
2449            }
2450            if (r.app == null || r.app.thread == null) {
2451                // The caller is not running...  d'oh!
2452                ActivityOptions.abort(options);
2453                return false;
2454            }
2455            intent = new Intent(intent);
2456            // The caller is not allowed to change the data.
2457            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2458            // And we are resetting to find the next component...
2459            intent.setComponent(null);
2460
2461            ActivityInfo aInfo = null;
2462            try {
2463                List<ResolveInfo> resolves =
2464                    AppGlobals.getPackageManager().queryIntentActivities(
2465                            intent, r.resolvedType,
2466                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2467                            UserHandle.getCallingUserId());
2468
2469                // Look for the original activity in the list...
2470                final int N = resolves != null ? resolves.size() : 0;
2471                for (int i=0; i<N; i++) {
2472                    ResolveInfo rInfo = resolves.get(i);
2473                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2474                            && rInfo.activityInfo.name.equals(r.info.name)) {
2475                        // We found the current one...  the next matching is
2476                        // after it.
2477                        i++;
2478                        if (i<N) {
2479                            aInfo = resolves.get(i).activityInfo;
2480                        }
2481                        break;
2482                    }
2483                }
2484            } catch (RemoteException e) {
2485            }
2486
2487            if (aInfo == null) {
2488                // Nobody who is next!
2489                ActivityOptions.abort(options);
2490                return false;
2491            }
2492
2493            intent.setComponent(new ComponentName(
2494                    aInfo.applicationInfo.packageName, aInfo.name));
2495            intent.setFlags(intent.getFlags()&~(
2496                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2497                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2498                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2499                    Intent.FLAG_ACTIVITY_NEW_TASK));
2500
2501            // Okay now we need to start the new activity, replacing the
2502            // currently running activity.  This is a little tricky because
2503            // we want to start the new one as if the current one is finished,
2504            // but not finish the current one first so that there is no flicker.
2505            // And thus...
2506            final boolean wasFinishing = r.finishing;
2507            r.finishing = true;
2508
2509            // Propagate reply information over to the new activity.
2510            final ActivityRecord resultTo = r.resultTo;
2511            final String resultWho = r.resultWho;
2512            final int requestCode = r.requestCode;
2513            r.resultTo = null;
2514            if (resultTo != null) {
2515                resultTo.removeResultsLocked(r, resultWho, requestCode);
2516            }
2517
2518            final long origId = Binder.clearCallingIdentity();
2519            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2520                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2521                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2522                    options, false, null);
2523            Binder.restoreCallingIdentity(origId);
2524
2525            r.finishing = wasFinishing;
2526            if (res != ActivityManager.START_SUCCESS) {
2527                return false;
2528            }
2529            return true;
2530        }
2531    }
2532
2533    public final int startActivityInPackage(int uid,
2534            Intent intent, String resolvedType, IBinder resultTo,
2535            String resultWho, int requestCode, int startFlags, Bundle options) {
2536
2537        // This is so super not safe, that only the system (or okay root)
2538        // can do it.
2539        final int callingUid = Binder.getCallingUid();
2540        if (callingUid != 0 && callingUid != Process.myUid()) {
2541            throw new SecurityException(
2542                    "startActivityInPackage only available to the system");
2543        }
2544
2545        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2546                resultTo, resultWho, requestCode, startFlags,
2547                null, null, null, null, options, UserHandle.getUserId(uid));
2548        return ret;
2549    }
2550
2551    public final int startActivities(IApplicationThread caller,
2552            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2553        enforceNotIsolatedCaller("startActivities");
2554        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2555                options, Binder.getOrigCallingUser());
2556        return ret;
2557    }
2558
2559    public final int startActivitiesInPackage(int uid,
2560            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2561            Bundle options) {
2562
2563        // This is so super not safe, that only the system (or okay root)
2564        // can do it.
2565        final int callingUid = Binder.getCallingUid();
2566        if (callingUid != 0 && callingUid != Process.myUid()) {
2567            throw new SecurityException(
2568                    "startActivityInPackage only available to the system");
2569        }
2570        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2571                options, UserHandle.getUserId(uid));
2572        return ret;
2573    }
2574
2575    final void addRecentTaskLocked(TaskRecord task) {
2576        int N = mRecentTasks.size();
2577        // Quick case: check if the top-most recent task is the same.
2578        if (N > 0 && mRecentTasks.get(0) == task) {
2579            return;
2580        }
2581        // Remove any existing entries that are the same kind of task.
2582        for (int i=0; i<N; i++) {
2583            TaskRecord tr = mRecentTasks.get(i);
2584            if (task.userId == tr.userId
2585                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2586                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2587                mRecentTasks.remove(i);
2588                i--;
2589                N--;
2590                if (task.intent == null) {
2591                    // If the new recent task we are adding is not fully
2592                    // specified, then replace it with the existing recent task.
2593                    task = tr;
2594                }
2595            }
2596        }
2597        if (N >= MAX_RECENT_TASKS) {
2598            mRecentTasks.remove(N-1);
2599        }
2600        mRecentTasks.add(0, task);
2601    }
2602
2603    public void setRequestedOrientation(IBinder token,
2604            int requestedOrientation) {
2605        synchronized (this) {
2606            ActivityRecord r = mMainStack.isInStackLocked(token);
2607            if (r == null) {
2608                return;
2609            }
2610            final long origId = Binder.clearCallingIdentity();
2611            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2612            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2613                    mConfiguration,
2614                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2615            if (config != null) {
2616                r.frozenBeforeDestroy = true;
2617                if (!updateConfigurationLocked(config, r, false, false)) {
2618                    mMainStack.resumeTopActivityLocked(null);
2619                }
2620            }
2621            Binder.restoreCallingIdentity(origId);
2622        }
2623    }
2624
2625    public int getRequestedOrientation(IBinder token) {
2626        synchronized (this) {
2627            ActivityRecord r = mMainStack.isInStackLocked(token);
2628            if (r == null) {
2629                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2630            }
2631            return mWindowManager.getAppOrientation(r.appToken);
2632        }
2633    }
2634
2635    /**
2636     * This is the internal entry point for handling Activity.finish().
2637     *
2638     * @param token The Binder token referencing the Activity we want to finish.
2639     * @param resultCode Result code, if any, from this Activity.
2640     * @param resultData Result data (Intent), if any, from this Activity.
2641     *
2642     * @return Returns true if the activity successfully finished, or false if it is still running.
2643     */
2644    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2645        // Refuse possible leaked file descriptors
2646        if (resultData != null && resultData.hasFileDescriptors() == true) {
2647            throw new IllegalArgumentException("File descriptors passed in Intent");
2648        }
2649
2650        synchronized(this) {
2651            if (mController != null) {
2652                // Find the first activity that is not finishing.
2653                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2654                if (next != null) {
2655                    // ask watcher if this is allowed
2656                    boolean resumeOK = true;
2657                    try {
2658                        resumeOK = mController.activityResuming(next.packageName);
2659                    } catch (RemoteException e) {
2660                        mController = null;
2661                    }
2662
2663                    if (!resumeOK) {
2664                        return false;
2665                    }
2666                }
2667            }
2668            final long origId = Binder.clearCallingIdentity();
2669            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2670                    resultData, "app-request");
2671            Binder.restoreCallingIdentity(origId);
2672            return res;
2673        }
2674    }
2675
2676    public final void finishHeavyWeightApp() {
2677        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2678                != PackageManager.PERMISSION_GRANTED) {
2679            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2680                    + Binder.getCallingPid()
2681                    + ", uid=" + Binder.getCallingUid()
2682                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2683            Slog.w(TAG, msg);
2684            throw new SecurityException(msg);
2685        }
2686
2687        synchronized(this) {
2688            if (mHeavyWeightProcess == null) {
2689                return;
2690            }
2691
2692            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2693                    mHeavyWeightProcess.activities);
2694            for (int i=0; i<activities.size(); i++) {
2695                ActivityRecord r = activities.get(i);
2696                if (!r.finishing) {
2697                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2698                    if (index >= 0) {
2699                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2700                                null, "finish-heavy");
2701                    }
2702                }
2703            }
2704
2705            mHeavyWeightProcess = null;
2706            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2707        }
2708    }
2709
2710    public void crashApplication(int uid, int initialPid, String packageName,
2711            String message) {
2712        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2713                != PackageManager.PERMISSION_GRANTED) {
2714            String msg = "Permission Denial: crashApplication() from pid="
2715                    + Binder.getCallingPid()
2716                    + ", uid=" + Binder.getCallingUid()
2717                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2718            Slog.w(TAG, msg);
2719            throw new SecurityException(msg);
2720        }
2721
2722        synchronized(this) {
2723            ProcessRecord proc = null;
2724
2725            // Figure out which process to kill.  We don't trust that initialPid
2726            // still has any relation to current pids, so must scan through the
2727            // list.
2728            synchronized (mPidsSelfLocked) {
2729                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2730                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2731                    if (p.uid != uid) {
2732                        continue;
2733                    }
2734                    if (p.pid == initialPid) {
2735                        proc = p;
2736                        break;
2737                    }
2738                    for (String str : p.pkgList) {
2739                        if (str.equals(packageName)) {
2740                            proc = p;
2741                        }
2742                    }
2743                }
2744            }
2745
2746            if (proc == null) {
2747                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2748                        + " initialPid=" + initialPid
2749                        + " packageName=" + packageName);
2750                return;
2751            }
2752
2753            if (proc.thread != null) {
2754                if (proc.pid == Process.myPid()) {
2755                    Log.w(TAG, "crashApplication: trying to crash self!");
2756                    return;
2757                }
2758                long ident = Binder.clearCallingIdentity();
2759                try {
2760                    proc.thread.scheduleCrash(message);
2761                } catch (RemoteException e) {
2762                }
2763                Binder.restoreCallingIdentity(ident);
2764            }
2765        }
2766    }
2767
2768    public final void finishSubActivity(IBinder token, String resultWho,
2769            int requestCode) {
2770        synchronized(this) {
2771            final long origId = Binder.clearCallingIdentity();
2772            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2773            Binder.restoreCallingIdentity(origId);
2774        }
2775    }
2776
2777    public boolean finishActivityAffinity(IBinder token) {
2778        synchronized(this) {
2779            final long origId = Binder.clearCallingIdentity();
2780            boolean res = mMainStack.finishActivityAffinityLocked(token);
2781            Binder.restoreCallingIdentity(origId);
2782            return res;
2783        }
2784    }
2785
2786    public boolean willActivityBeVisible(IBinder token) {
2787        synchronized(this) {
2788            int i;
2789            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2790                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2791                if (r.appToken == token) {
2792                    return true;
2793                }
2794                if (r.fullscreen && !r.finishing) {
2795                    return false;
2796                }
2797            }
2798            return true;
2799        }
2800    }
2801
2802    public void overridePendingTransition(IBinder token, String packageName,
2803            int enterAnim, int exitAnim) {
2804        synchronized(this) {
2805            ActivityRecord self = mMainStack.isInStackLocked(token);
2806            if (self == null) {
2807                return;
2808            }
2809
2810            final long origId = Binder.clearCallingIdentity();
2811
2812            if (self.state == ActivityState.RESUMED
2813                    || self.state == ActivityState.PAUSING) {
2814                mWindowManager.overridePendingAppTransition(packageName,
2815                        enterAnim, exitAnim, null);
2816            }
2817
2818            Binder.restoreCallingIdentity(origId);
2819        }
2820    }
2821
2822    /**
2823     * Main function for removing an existing process from the activity manager
2824     * as a result of that process going away.  Clears out all connections
2825     * to the process.
2826     */
2827    private final void handleAppDiedLocked(ProcessRecord app,
2828            boolean restarting, boolean allowRestart) {
2829        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2830        if (!restarting) {
2831            mLruProcesses.remove(app);
2832        }
2833
2834        if (mProfileProc == app) {
2835            clearProfilerLocked();
2836        }
2837
2838        // Just in case...
2839        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2840            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2841            mMainStack.mPausingActivity = null;
2842        }
2843        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2844            mMainStack.mLastPausedActivity = null;
2845        }
2846
2847        // Remove this application's activities from active lists.
2848        mMainStack.removeHistoryRecordsForAppLocked(app);
2849
2850        boolean atTop = true;
2851        boolean hasVisibleActivities = false;
2852
2853        // Clean out the history list.
2854        int i = mMainStack.mHistory.size();
2855        if (localLOGV) Slog.v(
2856            TAG, "Removing app " + app + " from history with " + i + " entries");
2857        while (i > 0) {
2858            i--;
2859            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2860            if (localLOGV) Slog.v(
2861                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2862            if (r.app == app) {
2863                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2864                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2865                        RuntimeException here = new RuntimeException("here");
2866                        here.fillInStackTrace();
2867                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2868                                + ": haveState=" + r.haveState
2869                                + " stateNotNeeded=" + r.stateNotNeeded
2870                                + " finishing=" + r.finishing
2871                                + " state=" + r.state, here);
2872                    }
2873                    if (!r.finishing) {
2874                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2875                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2876                                System.identityHashCode(r),
2877                                r.task.taskId, r.shortComponentName,
2878                                "proc died without state saved");
2879                    }
2880                    mMainStack.removeActivityFromHistoryLocked(r);
2881
2882                } else {
2883                    // We have the current state for this activity, so
2884                    // it can be restarted later when needed.
2885                    if (localLOGV) Slog.v(
2886                        TAG, "Keeping entry, setting app to null");
2887                    if (r.visible) {
2888                        hasVisibleActivities = true;
2889                    }
2890                    r.app = null;
2891                    r.nowVisible = false;
2892                    if (!r.haveState) {
2893                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2894                                "App died, clearing saved state of " + r);
2895                        r.icicle = null;
2896                    }
2897                }
2898
2899                r.stack.cleanUpActivityLocked(r, true, true);
2900            }
2901            atTop = false;
2902        }
2903
2904        app.activities.clear();
2905
2906        if (app.instrumentationClass != null) {
2907            Slog.w(TAG, "Crash of app " + app.processName
2908                  + " running instrumentation " + app.instrumentationClass);
2909            Bundle info = new Bundle();
2910            info.putString("shortMsg", "Process crashed.");
2911            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2912        }
2913
2914        if (!restarting) {
2915            if (!mMainStack.resumeTopActivityLocked(null)) {
2916                // If there was nothing to resume, and we are not already
2917                // restarting this process, but there is a visible activity that
2918                // is hosted by the process...  then make sure all visible
2919                // activities are running, taking care of restarting this
2920                // process.
2921                if (hasVisibleActivities) {
2922                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2923                }
2924            }
2925        }
2926    }
2927
2928    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2929        IBinder threadBinder = thread.asBinder();
2930        // Find the application record.
2931        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2932            ProcessRecord rec = mLruProcesses.get(i);
2933            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2934                return i;
2935            }
2936        }
2937        return -1;
2938    }
2939
2940    final ProcessRecord getRecordForAppLocked(
2941            IApplicationThread thread) {
2942        if (thread == null) {
2943            return null;
2944        }
2945
2946        int appIndex = getLRURecordIndexForAppLocked(thread);
2947        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2948    }
2949
2950    final void appDiedLocked(ProcessRecord app, int pid,
2951            IApplicationThread thread) {
2952
2953        mProcDeaths[0]++;
2954
2955        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2956        synchronized (stats) {
2957            stats.noteProcessDiedLocked(app.info.uid, pid);
2958        }
2959
2960        // Clean up already done if the process has been re-started.
2961        if (app.pid == pid && app.thread != null &&
2962                app.thread.asBinder() == thread.asBinder()) {
2963            if (!app.killedBackground) {
2964                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2965                        + ") has died.");
2966            }
2967            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2968            if (localLOGV) Slog.v(
2969                TAG, "Dying app: " + app + ", pid: " + pid
2970                + ", thread: " + thread.asBinder());
2971            boolean doLowMem = app.instrumentationClass == null;
2972            handleAppDiedLocked(app, false, true);
2973
2974            if (doLowMem) {
2975                // If there are no longer any background processes running,
2976                // and the app that died was not running instrumentation,
2977                // then tell everyone we are now low on memory.
2978                boolean haveBg = false;
2979                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2980                    ProcessRecord rec = mLruProcesses.get(i);
2981                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2982                        haveBg = true;
2983                        break;
2984                    }
2985                }
2986
2987                if (!haveBg) {
2988                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2989                    long now = SystemClock.uptimeMillis();
2990                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2991                        ProcessRecord rec = mLruProcesses.get(i);
2992                        if (rec != app && rec.thread != null &&
2993                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2994                            // The low memory report is overriding any current
2995                            // state for a GC request.  Make sure to do
2996                            // heavy/important/visible/foreground processes first.
2997                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
2998                                rec.lastRequestedGc = 0;
2999                            } else {
3000                                rec.lastRequestedGc = rec.lastLowMemory;
3001                            }
3002                            rec.reportLowMemory = true;
3003                            rec.lastLowMemory = now;
3004                            mProcessesToGc.remove(rec);
3005                            addProcessToGcListLocked(rec);
3006                        }
3007                    }
3008                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3009                    scheduleAppGcsLocked();
3010                }
3011            }
3012        } else if (app.pid != pid) {
3013            // A new process has already been started.
3014            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3015                    + ") has died and restarted (pid " + app.pid + ").");
3016            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3017        } else if (DEBUG_PROCESSES) {
3018            Slog.d(TAG, "Received spurious death notification for thread "
3019                    + thread.asBinder());
3020        }
3021    }
3022
3023    /**
3024     * If a stack trace dump file is configured, dump process stack traces.
3025     * @param clearTraces causes the dump file to be erased prior to the new
3026     *    traces being written, if true; when false, the new traces will be
3027     *    appended to any existing file content.
3028     * @param firstPids of dalvik VM processes to dump stack traces for first
3029     * @param lastPids of dalvik VM processes to dump stack traces for last
3030     * @param nativeProcs optional list of native process names to dump stack crawls
3031     * @return file containing stack traces, or null if no dump file is configured
3032     */
3033    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3034            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3035        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3036        if (tracesPath == null || tracesPath.length() == 0) {
3037            return null;
3038        }
3039
3040        File tracesFile = new File(tracesPath);
3041        try {
3042            File tracesDir = tracesFile.getParentFile();
3043            if (!tracesDir.exists()) tracesFile.mkdirs();
3044            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3045
3046            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3047            tracesFile.createNewFile();
3048            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3049        } catch (IOException e) {
3050            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3051            return null;
3052        }
3053
3054        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3055        return tracesFile;
3056    }
3057
3058    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3059            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3060        // Use a FileObserver to detect when traces finish writing.
3061        // The order of traces is considered important to maintain for legibility.
3062        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3063            public synchronized void onEvent(int event, String path) { notify(); }
3064        };
3065
3066        try {
3067            observer.startWatching();
3068
3069            // First collect all of the stacks of the most important pids.
3070            if (firstPids != null) {
3071                try {
3072                    int num = firstPids.size();
3073                    for (int i = 0; i < num; i++) {
3074                        synchronized (observer) {
3075                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3076                            observer.wait(200);  // Wait for write-close, give up after 200msec
3077                        }
3078                    }
3079                } catch (InterruptedException e) {
3080                    Log.wtf(TAG, e);
3081                }
3082            }
3083
3084            // Next measure CPU usage.
3085            if (processStats != null) {
3086                processStats.init();
3087                System.gc();
3088                processStats.update();
3089                try {
3090                    synchronized (processStats) {
3091                        processStats.wait(500); // measure over 1/2 second.
3092                    }
3093                } catch (InterruptedException e) {
3094                }
3095                processStats.update();
3096
3097                // We'll take the stack crawls of just the top apps using CPU.
3098                final int N = processStats.countWorkingStats();
3099                int numProcs = 0;
3100                for (int i=0; i<N && numProcs<5; i++) {
3101                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3102                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3103                        numProcs++;
3104                        try {
3105                            synchronized (observer) {
3106                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3107                                observer.wait(200);  // Wait for write-close, give up after 200msec
3108                            }
3109                        } catch (InterruptedException e) {
3110                            Log.wtf(TAG, e);
3111                        }
3112
3113                    }
3114                }
3115            }
3116
3117        } finally {
3118            observer.stopWatching();
3119        }
3120
3121        if (nativeProcs != null) {
3122            int[] pids = Process.getPidsForCommands(nativeProcs);
3123            if (pids != null) {
3124                for (int pid : pids) {
3125                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3126                }
3127            }
3128        }
3129    }
3130
3131    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3132        if (true || IS_USER_BUILD) {
3133            return;
3134        }
3135        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3136        if (tracesPath == null || tracesPath.length() == 0) {
3137            return;
3138        }
3139
3140        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3141        StrictMode.allowThreadDiskWrites();
3142        try {
3143            final File tracesFile = new File(tracesPath);
3144            final File tracesDir = tracesFile.getParentFile();
3145            final File tracesTmp = new File(tracesDir, "__tmp__");
3146            try {
3147                if (!tracesDir.exists()) tracesFile.mkdirs();
3148                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3149
3150                if (tracesFile.exists()) {
3151                    tracesTmp.delete();
3152                    tracesFile.renameTo(tracesTmp);
3153                }
3154                StringBuilder sb = new StringBuilder();
3155                Time tobj = new Time();
3156                tobj.set(System.currentTimeMillis());
3157                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3158                sb.append(": ");
3159                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3160                sb.append(" since ");
3161                sb.append(msg);
3162                FileOutputStream fos = new FileOutputStream(tracesFile);
3163                fos.write(sb.toString().getBytes());
3164                if (app == null) {
3165                    fos.write("\n*** No application process!".getBytes());
3166                }
3167                fos.close();
3168                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3169            } catch (IOException e) {
3170                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3171                return;
3172            }
3173
3174            if (app != null) {
3175                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3176                firstPids.add(app.pid);
3177                dumpStackTraces(tracesPath, firstPids, null, null, null);
3178            }
3179
3180            File lastTracesFile = null;
3181            File curTracesFile = null;
3182            for (int i=9; i>=0; i--) {
3183                String name = String.format("slow%02d.txt", i);
3184                curTracesFile = new File(tracesDir, name);
3185                if (curTracesFile.exists()) {
3186                    if (lastTracesFile != null) {
3187                        curTracesFile.renameTo(lastTracesFile);
3188                    } else {
3189                        curTracesFile.delete();
3190                    }
3191                }
3192                lastTracesFile = curTracesFile;
3193            }
3194            tracesFile.renameTo(curTracesFile);
3195            if (tracesTmp.exists()) {
3196                tracesTmp.renameTo(tracesFile);
3197            }
3198        } finally {
3199            StrictMode.setThreadPolicy(oldPolicy);
3200        }
3201    }
3202
3203    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3204            ActivityRecord parent, final String annotation) {
3205        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3206        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3207
3208        if (mController != null) {
3209            try {
3210                // 0 == continue, -1 = kill process immediately
3211                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3212                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3213            } catch (RemoteException e) {
3214                mController = null;
3215            }
3216        }
3217
3218        long anrTime = SystemClock.uptimeMillis();
3219        if (MONITOR_CPU_USAGE) {
3220            updateCpuStatsNow();
3221        }
3222
3223        synchronized (this) {
3224            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3225            if (mShuttingDown) {
3226                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3227                return;
3228            } else if (app.notResponding) {
3229                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3230                return;
3231            } else if (app.crashing) {
3232                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3233                return;
3234            }
3235
3236            // In case we come through here for the same app before completing
3237            // this one, mark as anring now so we will bail out.
3238            app.notResponding = true;
3239
3240            // Log the ANR to the event log.
3241            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3242                    annotation);
3243
3244            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3245            firstPids.add(app.pid);
3246
3247            int parentPid = app.pid;
3248            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3249            if (parentPid != app.pid) firstPids.add(parentPid);
3250
3251            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3252
3253            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3254                ProcessRecord r = mLruProcesses.get(i);
3255                if (r != null && r.thread != null) {
3256                    int pid = r.pid;
3257                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3258                        if (r.persistent) {
3259                            firstPids.add(pid);
3260                        } else {
3261                            lastPids.put(pid, Boolean.TRUE);
3262                        }
3263                    }
3264                }
3265            }
3266        }
3267
3268        // Log the ANR to the main log.
3269        StringBuilder info = new StringBuilder();
3270        info.setLength(0);
3271        info.append("ANR in ").append(app.processName);
3272        if (activity != null && activity.shortComponentName != null) {
3273            info.append(" (").append(activity.shortComponentName).append(")");
3274        }
3275        info.append("\n");
3276        if (annotation != null) {
3277            info.append("Reason: ").append(annotation).append("\n");
3278        }
3279        if (parent != null && parent != activity) {
3280            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3281        }
3282
3283        final ProcessStats processStats = new ProcessStats(true);
3284
3285        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3286
3287        String cpuInfo = null;
3288        if (MONITOR_CPU_USAGE) {
3289            updateCpuStatsNow();
3290            synchronized (mProcessStatsThread) {
3291                cpuInfo = mProcessStats.printCurrentState(anrTime);
3292            }
3293            info.append(processStats.printCurrentLoad());
3294            info.append(cpuInfo);
3295        }
3296
3297        info.append(processStats.printCurrentState(anrTime));
3298
3299        Slog.e(TAG, info.toString());
3300        if (tracesFile == null) {
3301            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3302            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3303        }
3304
3305        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3306                cpuInfo, tracesFile, null);
3307
3308        if (mController != null) {
3309            try {
3310                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3311                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3312                if (res != 0) {
3313                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3314                    return;
3315                }
3316            } catch (RemoteException e) {
3317                mController = null;
3318            }
3319        }
3320
3321        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3322        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3323                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3324
3325        synchronized (this) {
3326            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3327                Slog.w(TAG, "Killing " + app + ": background ANR");
3328                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3329                        app.processName, app.setAdj, "background ANR");
3330                Process.killProcessQuiet(app.pid);
3331                return;
3332            }
3333
3334            // Set the app's notResponding state, and look up the errorReportReceiver
3335            makeAppNotRespondingLocked(app,
3336                    activity != null ? activity.shortComponentName : null,
3337                    annotation != null ? "ANR " + annotation : "ANR",
3338                    info.toString());
3339
3340            // Bring up the infamous App Not Responding dialog
3341            Message msg = Message.obtain();
3342            HashMap map = new HashMap();
3343            msg.what = SHOW_NOT_RESPONDING_MSG;
3344            msg.obj = map;
3345            map.put("app", app);
3346            if (activity != null) {
3347                map.put("activity", activity);
3348            }
3349
3350            mHandler.sendMessage(msg);
3351        }
3352    }
3353
3354    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3355        if (!mLaunchWarningShown) {
3356            mLaunchWarningShown = true;
3357            mHandler.post(new Runnable() {
3358                @Override
3359                public void run() {
3360                    synchronized (ActivityManagerService.this) {
3361                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3362                        d.show();
3363                        mHandler.postDelayed(new Runnable() {
3364                            @Override
3365                            public void run() {
3366                                synchronized (ActivityManagerService.this) {
3367                                    d.dismiss();
3368                                    mLaunchWarningShown = false;
3369                                }
3370                            }
3371                        }, 4000);
3372                    }
3373                }
3374            });
3375        }
3376    }
3377
3378    public boolean clearApplicationUserData(final String packageName,
3379            final IPackageDataObserver observer, final int userId) {
3380        enforceNotIsolatedCaller("clearApplicationUserData");
3381        int uid = Binder.getCallingUid();
3382        int pid = Binder.getCallingPid();
3383        long callingId = Binder.clearCallingIdentity();
3384        try {
3385            IPackageManager pm = AppGlobals.getPackageManager();
3386            int pkgUid = -1;
3387            synchronized(this) {
3388                try {
3389                    pkgUid = pm.getPackageUid(packageName, userId);
3390                } catch (RemoteException e) {
3391                }
3392                if (pkgUid == -1) {
3393                    Slog.w(TAG, "Invalid packageName:" + packageName);
3394                    return false;
3395                }
3396                if (uid == pkgUid || checkComponentPermission(
3397                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3398                        pid, uid, -1, true)
3399                        == PackageManager.PERMISSION_GRANTED) {
3400                    forceStopPackageLocked(packageName, pkgUid);
3401                } else {
3402                    throw new SecurityException(pid+" does not have permission:"+
3403                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3404                                    "for process:"+packageName);
3405                }
3406            }
3407
3408            try {
3409                //clear application user data
3410                pm.clearApplicationUserData(packageName, observer, userId);
3411                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3412                        Uri.fromParts("package", packageName, null));
3413                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3414                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3415                        null, null, 0, null, null, null, false, false, userId);
3416            } catch (RemoteException e) {
3417            }
3418        } finally {
3419            Binder.restoreCallingIdentity(callingId);
3420        }
3421        return true;
3422    }
3423
3424    public void killBackgroundProcesses(final String packageName) {
3425        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3426                != PackageManager.PERMISSION_GRANTED &&
3427                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3428                        != PackageManager.PERMISSION_GRANTED) {
3429            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3430                    + Binder.getCallingPid()
3431                    + ", uid=" + Binder.getCallingUid()
3432                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3433            Slog.w(TAG, msg);
3434            throw new SecurityException(msg);
3435        }
3436
3437        int userId = UserHandle.getCallingUserId();
3438        long callingId = Binder.clearCallingIdentity();
3439        try {
3440            IPackageManager pm = AppGlobals.getPackageManager();
3441            int pkgUid = -1;
3442            synchronized(this) {
3443                try {
3444                    pkgUid = pm.getPackageUid(packageName, userId);
3445                } catch (RemoteException e) {
3446                }
3447                if (pkgUid == -1) {
3448                    Slog.w(TAG, "Invalid packageName: " + packageName);
3449                    return;
3450                }
3451                killPackageProcessesLocked(packageName, pkgUid,
3452                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3453            }
3454        } finally {
3455            Binder.restoreCallingIdentity(callingId);
3456        }
3457    }
3458
3459    public void killAllBackgroundProcesses() {
3460        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3461                != PackageManager.PERMISSION_GRANTED) {
3462            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3463                    + Binder.getCallingPid()
3464                    + ", uid=" + Binder.getCallingUid()
3465                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3466            Slog.w(TAG, msg);
3467            throw new SecurityException(msg);
3468        }
3469
3470        long callingId = Binder.clearCallingIdentity();
3471        try {
3472            synchronized(this) {
3473                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3474                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3475                    final int NA = apps.size();
3476                    for (int ia=0; ia<NA; ia++) {
3477                        ProcessRecord app = apps.valueAt(ia);
3478                        if (app.persistent) {
3479                            // we don't kill persistent processes
3480                            continue;
3481                        }
3482                        if (app.removed) {
3483                            procs.add(app);
3484                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3485                            app.removed = true;
3486                            procs.add(app);
3487                        }
3488                    }
3489                }
3490
3491                int N = procs.size();
3492                for (int i=0; i<N; i++) {
3493                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3494                }
3495            }
3496        } finally {
3497            Binder.restoreCallingIdentity(callingId);
3498        }
3499    }
3500
3501    public void forceStopPackage(final String packageName) {
3502        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3503                != PackageManager.PERMISSION_GRANTED) {
3504            String msg = "Permission Denial: forceStopPackage() from pid="
3505                    + Binder.getCallingPid()
3506                    + ", uid=" + Binder.getCallingUid()
3507                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3508            Slog.w(TAG, msg);
3509            throw new SecurityException(msg);
3510        }
3511        final int userId = UserHandle.getCallingUserId();
3512        long callingId = Binder.clearCallingIdentity();
3513        try {
3514            IPackageManager pm = AppGlobals.getPackageManager();
3515            int pkgUid = -1;
3516            synchronized(this) {
3517                try {
3518                    pkgUid = pm.getPackageUid(packageName, userId);
3519                } catch (RemoteException e) {
3520                }
3521                if (pkgUid == -1) {
3522                    Slog.w(TAG, "Invalid packageName: " + packageName);
3523                    return;
3524                }
3525                forceStopPackageLocked(packageName, pkgUid);
3526                try {
3527                    pm.setPackageStoppedState(packageName, true, userId);
3528                } catch (RemoteException e) {
3529                } catch (IllegalArgumentException e) {
3530                    Slog.w(TAG, "Failed trying to unstop package "
3531                            + packageName + ": " + e);
3532                }
3533            }
3534        } finally {
3535            Binder.restoreCallingIdentity(callingId);
3536        }
3537    }
3538
3539    /*
3540     * The pkg name and uid have to be specified.
3541     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3542     */
3543    public void killApplicationWithUid(String pkg, int uid) {
3544        if (pkg == null) {
3545            return;
3546        }
3547        // Make sure the uid is valid.
3548        if (uid < 0) {
3549            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3550            return;
3551        }
3552        int callerUid = Binder.getCallingUid();
3553        // Only the system server can kill an application
3554        if (callerUid == Process.SYSTEM_UID) {
3555            // Post an aysnc message to kill the application
3556            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3557            msg.arg1 = uid;
3558            msg.arg2 = 0;
3559            msg.obj = pkg;
3560            mHandler.sendMessage(msg);
3561        } else {
3562            throw new SecurityException(callerUid + " cannot kill pkg: " +
3563                    pkg);
3564        }
3565    }
3566
3567    public void closeSystemDialogs(String reason) {
3568        enforceNotIsolatedCaller("closeSystemDialogs");
3569
3570        final int uid = Binder.getCallingUid();
3571        final long origId = Binder.clearCallingIdentity();
3572        synchronized (this) {
3573            closeSystemDialogsLocked(uid, reason);
3574        }
3575        Binder.restoreCallingIdentity(origId);
3576    }
3577
3578    void closeSystemDialogsLocked(int callingUid, String reason) {
3579        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3580        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3581        if (reason != null) {
3582            intent.putExtra("reason", reason);
3583        }
3584        mWindowManager.closeSystemDialogs(reason);
3585
3586        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3587            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3588            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3589                r.stack.finishActivityLocked(r, i,
3590                        Activity.RESULT_CANCELED, null, "close-sys");
3591            }
3592        }
3593
3594        broadcastIntentLocked(null, null, intent, null,
3595                null, 0, null, null, null, false, false, -1,
3596                callingUid, 0 /* TODO: Verify */);
3597    }
3598
3599    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3600            throws RemoteException {
3601        enforceNotIsolatedCaller("getProcessMemoryInfo");
3602        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3603        for (int i=pids.length-1; i>=0; i--) {
3604            infos[i] = new Debug.MemoryInfo();
3605            Debug.getMemoryInfo(pids[i], infos[i]);
3606        }
3607        return infos;
3608    }
3609
3610    public long[] getProcessPss(int[] pids) throws RemoteException {
3611        enforceNotIsolatedCaller("getProcessPss");
3612        long[] pss = new long[pids.length];
3613        for (int i=pids.length-1; i>=0; i--) {
3614            pss[i] = Debug.getPss(pids[i]);
3615        }
3616        return pss;
3617    }
3618
3619    public void killApplicationProcess(String processName, int uid) {
3620        if (processName == null) {
3621            return;
3622        }
3623
3624        int callerUid = Binder.getCallingUid();
3625        // Only the system server can kill an application
3626        if (callerUid == Process.SYSTEM_UID) {
3627            synchronized (this) {
3628                ProcessRecord app = getProcessRecordLocked(processName, uid);
3629                if (app != null && app.thread != null) {
3630                    try {
3631                        app.thread.scheduleSuicide();
3632                    } catch (RemoteException e) {
3633                        // If the other end already died, then our work here is done.
3634                    }
3635                } else {
3636                    Slog.w(TAG, "Process/uid not found attempting kill of "
3637                            + processName + " / " + uid);
3638                }
3639            }
3640        } else {
3641            throw new SecurityException(callerUid + " cannot kill app process: " +
3642                    processName);
3643        }
3644    }
3645
3646    private void forceStopPackageLocked(final String packageName, int uid) {
3647        forceStopPackageLocked(packageName, uid, false, false, true, false, UserHandle.getUserId(uid));
3648        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3649                Uri.fromParts("package", packageName, null));
3650        if (!mProcessesReady) {
3651            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3652        }
3653        intent.putExtra(Intent.EXTRA_UID, uid);
3654        broadcastIntentLocked(null, null, intent,
3655                null, null, 0, null, null, null,
3656                false, false,
3657                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3658    }
3659
3660    private final boolean killPackageProcessesLocked(String packageName, int uid,
3661            int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3662            boolean evenPersistent, String reason) {
3663        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3664
3665        // Remove all processes this package may have touched: all with the
3666        // same UID (except for the system or root user), and all whose name
3667        // matches the package name.
3668        final String procNamePrefix = packageName + ":";
3669        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3670            final int NA = apps.size();
3671            for (int ia=0; ia<NA; ia++) {
3672                ProcessRecord app = apps.valueAt(ia);
3673                if (app.persistent && !evenPersistent) {
3674                    // we don't kill persistent processes
3675                    continue;
3676                }
3677                if (app.removed) {
3678                    if (doit) {
3679                        procs.add(app);
3680                    }
3681                // If uid is specified and the uid and process name match
3682                // Or, the uid is not specified and the process name matches
3683                } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3684                            || ((app.processName.equals(packageName)
3685                                 || app.processName.startsWith(procNamePrefix))
3686                                && uid < 0))) {
3687                    if (app.setAdj >= minOomAdj) {
3688                        if (!doit) {
3689                            return true;
3690                        }
3691                        app.removed = true;
3692                        procs.add(app);
3693                    }
3694                }
3695            }
3696        }
3697
3698        int N = procs.size();
3699        for (int i=0; i<N; i++) {
3700            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3701        }
3702        return N > 0;
3703    }
3704
3705    private final boolean forceStopPackageLocked(String name, int uid,
3706            boolean callerWillRestart, boolean purgeCache, boolean doit,
3707            boolean evenPersistent, int userId) {
3708        int i;
3709        int N;
3710
3711        if (uid < 0) {
3712            try {
3713                uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
3714            } catch (RemoteException e) {
3715            }
3716        }
3717
3718        if (doit) {
3719            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3720
3721            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3722            while (badApps.hasNext()) {
3723                SparseArray<Long> ba = badApps.next();
3724                if (ba.get(uid) != null) {
3725                    badApps.remove();
3726                }
3727            }
3728        }
3729
3730        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3731                callerWillRestart, false, doit, evenPersistent, "force stop");
3732
3733        TaskRecord lastTask = null;
3734        for (i=0; i<mMainStack.mHistory.size(); i++) {
3735            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3736            final boolean samePackage = r.packageName.equals(name);
3737            if (r.userId == userId
3738                    && (samePackage || r.task == lastTask)
3739                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3740                if (!doit) {
3741                    if (r.finishing) {
3742                        // If this activity is just finishing, then it is not
3743                        // interesting as far as something to stop.
3744                        continue;
3745                    }
3746                    return true;
3747                }
3748                didSomething = true;
3749                Slog.i(TAG, "  Force finishing activity " + r);
3750                if (samePackage) {
3751                    if (r.app != null) {
3752                        r.app.removed = true;
3753                    }
3754                    r.app = null;
3755                }
3756                lastTask = r.task;
3757                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3758                        null, "force-stop", true)) {
3759                    i--;
3760                }
3761            }
3762        }
3763
3764        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3765            if (!doit) {
3766                return true;
3767            }
3768            didSomething = true;
3769        }
3770
3771        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3772        for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
3773            if (provider.info.packageName.equals(name)
3774                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3775                if (!doit) {
3776                    return true;
3777                }
3778                didSomething = true;
3779                providers.add(provider);
3780            }
3781        }
3782
3783        N = providers.size();
3784        for (i=0; i<N; i++) {
3785            removeDyingProviderLocked(null, providers.get(i), true);
3786        }
3787
3788        if (doit) {
3789            if (purgeCache) {
3790                AttributeCache ac = AttributeCache.instance();
3791                if (ac != null) {
3792                    ac.removePackage(name);
3793                }
3794            }
3795            if (mBooted) {
3796                mMainStack.resumeTopActivityLocked(null);
3797                mMainStack.scheduleIdleLocked();
3798            }
3799        }
3800
3801        return didSomething;
3802    }
3803
3804    private final boolean removeProcessLocked(ProcessRecord app,
3805            boolean callerWillRestart, boolean allowRestart, String reason) {
3806        final String name = app.processName;
3807        final int uid = app.uid;
3808        if (DEBUG_PROCESSES) Slog.d(
3809            TAG, "Force removing proc " + app.toShortString() + " (" + name
3810            + "/" + uid + ")");
3811
3812        mProcessNames.remove(name, uid);
3813        mIsolatedProcesses.remove(app.uid);
3814        if (mHeavyWeightProcess == app) {
3815            mHeavyWeightProcess = null;
3816            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3817        }
3818        boolean needRestart = false;
3819        if (app.pid > 0 && app.pid != MY_PID) {
3820            int pid = app.pid;
3821            synchronized (mPidsSelfLocked) {
3822                mPidsSelfLocked.remove(pid);
3823                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3824            }
3825            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3826            handleAppDiedLocked(app, true, allowRestart);
3827            mLruProcesses.remove(app);
3828            Process.killProcessQuiet(pid);
3829
3830            if (app.persistent && !app.isolated) {
3831                if (!callerWillRestart) {
3832                    addAppLocked(app.info, false);
3833                } else {
3834                    needRestart = true;
3835                }
3836            }
3837        } else {
3838            mRemovedProcesses.add(app);
3839        }
3840
3841        return needRestart;
3842    }
3843
3844    private final void processStartTimedOutLocked(ProcessRecord app) {
3845        final int pid = app.pid;
3846        boolean gone = false;
3847        synchronized (mPidsSelfLocked) {
3848            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3849            if (knownApp != null && knownApp.thread == null) {
3850                mPidsSelfLocked.remove(pid);
3851                gone = true;
3852            }
3853        }
3854
3855        if (gone) {
3856            Slog.w(TAG, "Process " + app + " failed to attach");
3857            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
3858                    app.processName);
3859            mProcessNames.remove(app.processName, app.uid);
3860            mIsolatedProcesses.remove(app.uid);
3861            if (mHeavyWeightProcess == app) {
3862                mHeavyWeightProcess = null;
3863                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3864            }
3865            // Take care of any launching providers waiting for this process.
3866            checkAppInLaunchingProvidersLocked(app, true);
3867            // Take care of any services that are waiting for the process.
3868            mServices.processStartTimedOutLocked(app);
3869            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3870                    app.processName, app.setAdj, "start timeout");
3871            Process.killProcessQuiet(pid);
3872            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3873                Slog.w(TAG, "Unattached app died before backup, skipping");
3874                try {
3875                    IBackupManager bm = IBackupManager.Stub.asInterface(
3876                            ServiceManager.getService(Context.BACKUP_SERVICE));
3877                    bm.agentDisconnected(app.info.packageName);
3878                } catch (RemoteException e) {
3879                    // Can't happen; the backup manager is local
3880                }
3881            }
3882            if (isPendingBroadcastProcessLocked(pid)) {
3883                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3884                skipPendingBroadcastLocked(pid);
3885            }
3886        } else {
3887            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3888        }
3889    }
3890
3891    private final boolean attachApplicationLocked(IApplicationThread thread,
3892            int pid) {
3893
3894        // Find the application record that is being attached...  either via
3895        // the pid if we are running in multiple processes, or just pull the
3896        // next app record if we are emulating process with anonymous threads.
3897        ProcessRecord app;
3898        if (pid != MY_PID && pid >= 0) {
3899            synchronized (mPidsSelfLocked) {
3900                app = mPidsSelfLocked.get(pid);
3901            }
3902        } else {
3903            app = null;
3904        }
3905
3906        if (app == null) {
3907            Slog.w(TAG, "No pending application record for pid " + pid
3908                    + " (IApplicationThread " + thread + "); dropping process");
3909            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3910            if (pid > 0 && pid != MY_PID) {
3911                Process.killProcessQuiet(pid);
3912            } else {
3913                try {
3914                    thread.scheduleExit();
3915                } catch (Exception e) {
3916                    // Ignore exceptions.
3917                }
3918            }
3919            return false;
3920        }
3921
3922        // If this application record is still attached to a previous
3923        // process, clean it up now.
3924        if (app.thread != null) {
3925            handleAppDiedLocked(app, true, true);
3926        }
3927
3928        // Tell the process all about itself.
3929
3930        if (localLOGV) Slog.v(
3931                TAG, "Binding process pid " + pid + " to record " + app);
3932
3933        String processName = app.processName;
3934        try {
3935            AppDeathRecipient adr = new AppDeathRecipient(
3936                    app, pid, thread);
3937            thread.asBinder().linkToDeath(adr, 0);
3938            app.deathRecipient = adr;
3939        } catch (RemoteException e) {
3940            app.resetPackageList();
3941            startProcessLocked(app, "link fail", processName);
3942            return false;
3943        }
3944
3945        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3946
3947        app.thread = thread;
3948        app.curAdj = app.setAdj = -100;
3949        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3950        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3951        app.forcingToForeground = null;
3952        app.foregroundServices = false;
3953        app.hasShownUi = false;
3954        app.debugging = false;
3955
3956        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3957
3958        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3959        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3960
3961        if (!normalMode) {
3962            Slog.i(TAG, "Launching preboot mode app: " + app);
3963        }
3964
3965        if (localLOGV) Slog.v(
3966            TAG, "New app record " + app
3967            + " thread=" + thread.asBinder() + " pid=" + pid);
3968        try {
3969            int testMode = IApplicationThread.DEBUG_OFF;
3970            if (mDebugApp != null && mDebugApp.equals(processName)) {
3971                testMode = mWaitForDebugger
3972                    ? IApplicationThread.DEBUG_WAIT
3973                    : IApplicationThread.DEBUG_ON;
3974                app.debugging = true;
3975                if (mDebugTransient) {
3976                    mDebugApp = mOrigDebugApp;
3977                    mWaitForDebugger = mOrigWaitForDebugger;
3978                }
3979            }
3980            String profileFile = app.instrumentationProfileFile;
3981            ParcelFileDescriptor profileFd = null;
3982            boolean profileAutoStop = false;
3983            if (mProfileApp != null && mProfileApp.equals(processName)) {
3984                mProfileProc = app;
3985                profileFile = mProfileFile;
3986                profileFd = mProfileFd;
3987                profileAutoStop = mAutoStopProfiler;
3988            }
3989            boolean enableOpenGlTrace = false;
3990            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
3991                enableOpenGlTrace = true;
3992                mOpenGlTraceApp = null;
3993            }
3994
3995            // If the app is being launched for restore or full backup, set it up specially
3996            boolean isRestrictedBackupMode = false;
3997            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3998                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3999                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4000                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4001            }
4002
4003            ensurePackageDexOpt(app.instrumentationInfo != null
4004                    ? app.instrumentationInfo.packageName
4005                    : app.info.packageName);
4006            if (app.instrumentationClass != null) {
4007                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4008            }
4009            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4010                    + processName + " with config " + mConfiguration);
4011            ApplicationInfo appInfo = app.instrumentationInfo != null
4012                    ? app.instrumentationInfo : app.info;
4013            app.compat = compatibilityInfoForPackageLocked(appInfo);
4014            if (profileFd != null) {
4015                profileFd = profileFd.dup();
4016            }
4017            thread.bindApplication(processName, appInfo, providers,
4018                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4019                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4020                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4021                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4022                    mCoreSettingsObserver.getCoreSettingsLocked());
4023            updateLruProcessLocked(app, false, true);
4024            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4025        } catch (Exception e) {
4026            // todo: Yikes!  What should we do?  For now we will try to
4027            // start another process, but that could easily get us in
4028            // an infinite loop of restarting processes...
4029            Slog.w(TAG, "Exception thrown during bind!", e);
4030
4031            app.resetPackageList();
4032            app.unlinkDeathRecipient();
4033            startProcessLocked(app, "bind fail", processName);
4034            return false;
4035        }
4036
4037        // Remove this record from the list of starting applications.
4038        mPersistentStartingProcesses.remove(app);
4039        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4040                "Attach application locked removing on hold: " + app);
4041        mProcessesOnHold.remove(app);
4042
4043        boolean badApp = false;
4044        boolean didSomething = false;
4045
4046        // See if the top visible activity is waiting to run in this process...
4047        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4048        if (hr != null && normalMode) {
4049            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4050                    && processName.equals(hr.processName)) {
4051                try {
4052                    if (mHeadless) {
4053                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4054                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4055                        didSomething = true;
4056                    }
4057                } catch (Exception e) {
4058                    Slog.w(TAG, "Exception in new application when starting activity "
4059                          + hr.intent.getComponent().flattenToShortString(), e);
4060                    badApp = true;
4061                }
4062            } else {
4063                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4064            }
4065        }
4066
4067        // Find any services that should be running in this process...
4068        if (!badApp) {
4069            try {
4070                didSomething |= mServices.attachApplicationLocked(app, processName);
4071            } catch (Exception e) {
4072                badApp = true;
4073            }
4074        }
4075
4076        // Check if a next-broadcast receiver is in this process...
4077        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4078            try {
4079                didSomething = sendPendingBroadcastsLocked(app);
4080            } catch (Exception e) {
4081                // If the app died trying to launch the receiver we declare it 'bad'
4082                badApp = true;
4083            }
4084        }
4085
4086        // Check whether the next backup agent is in this process...
4087        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4088            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4089            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4090            try {
4091                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4092                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4093                        mBackupTarget.backupMode);
4094            } catch (Exception e) {
4095                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4096                e.printStackTrace();
4097            }
4098        }
4099
4100        if (badApp) {
4101            // todo: Also need to kill application to deal with all
4102            // kinds of exceptions.
4103            handleAppDiedLocked(app, false, true);
4104            return false;
4105        }
4106
4107        if (!didSomething) {
4108            updateOomAdjLocked();
4109        }
4110
4111        return true;
4112    }
4113
4114    public final void attachApplication(IApplicationThread thread) {
4115        synchronized (this) {
4116            int callingPid = Binder.getCallingPid();
4117            final long origId = Binder.clearCallingIdentity();
4118            attachApplicationLocked(thread, callingPid);
4119            Binder.restoreCallingIdentity(origId);
4120        }
4121    }
4122
4123    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4124        final long origId = Binder.clearCallingIdentity();
4125        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4126        if (stopProfiling) {
4127            synchronized (this) {
4128                if (mProfileProc == r.app) {
4129                    if (mProfileFd != null) {
4130                        try {
4131                            mProfileFd.close();
4132                        } catch (IOException e) {
4133                        }
4134                        clearProfilerLocked();
4135                    }
4136                }
4137            }
4138        }
4139        Binder.restoreCallingIdentity(origId);
4140    }
4141
4142    void enableScreenAfterBoot() {
4143        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4144                SystemClock.uptimeMillis());
4145        mWindowManager.enableScreenAfterBoot();
4146
4147        synchronized (this) {
4148            updateEventDispatchingLocked();
4149        }
4150    }
4151
4152    public void showBootMessage(final CharSequence msg, final boolean always) {
4153        enforceNotIsolatedCaller("showBootMessage");
4154        mWindowManager.showBootMessage(msg, always);
4155    }
4156
4157    public void dismissKeyguardOnNextActivity() {
4158        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4159        final long token = Binder.clearCallingIdentity();
4160        try {
4161            synchronized (this) {
4162                if (mLockScreenShown) {
4163                    mLockScreenShown = false;
4164                    comeOutOfSleepIfNeededLocked();
4165                }
4166                mMainStack.dismissKeyguardOnNextActivityLocked();
4167            }
4168        } finally {
4169            Binder.restoreCallingIdentity(token);
4170        }
4171    }
4172
4173    final void finishBooting() {
4174        IntentFilter pkgFilter = new IntentFilter();
4175        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4176        pkgFilter.addDataScheme("package");
4177        mContext.registerReceiver(new BroadcastReceiver() {
4178            @Override
4179            public void onReceive(Context context, Intent intent) {
4180                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4181                if (pkgs != null) {
4182                    for (String pkg : pkgs) {
4183                        synchronized (ActivityManagerService.this) {
4184                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4185                                setResultCode(Activity.RESULT_OK);
4186                                return;
4187                            }
4188                        }
4189                    }
4190                }
4191            }
4192        }, pkgFilter);
4193
4194        IntentFilter userFilter = new IntentFilter();
4195        userFilter.addAction(Intent.ACTION_USER_REMOVED);
4196        mContext.registerReceiver(new BroadcastReceiver() {
4197            @Override
4198            public void onReceive(Context context, Intent intent) {
4199                onUserRemoved(intent);
4200            }
4201        }, userFilter);
4202
4203        synchronized (this) {
4204            // Ensure that any processes we had put on hold are now started
4205            // up.
4206            final int NP = mProcessesOnHold.size();
4207            if (NP > 0) {
4208                ArrayList<ProcessRecord> procs =
4209                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4210                for (int ip=0; ip<NP; ip++) {
4211                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4212                            + procs.get(ip));
4213                    startProcessLocked(procs.get(ip), "on-hold", null);
4214                }
4215            }
4216
4217            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4218                // Start looking for apps that are abusing wake locks.
4219                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4220                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4221                // Tell anyone interested that we are done booting!
4222                SystemProperties.set("sys.boot_completed", "1");
4223                SystemProperties.set("dev.bootcomplete", "1");
4224                List<UserInfo> users = getUserManager().getUsers();
4225                for (UserInfo user : users) {
4226                    broadcastIntentLocked(null, null,
4227                            new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4228                            null, null, 0, null, null,
4229                            android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4230                            false, false, MY_PID, Process.SYSTEM_UID, user.id);
4231                }
4232            }
4233        }
4234    }
4235
4236    final void ensureBootCompleted() {
4237        boolean booting;
4238        boolean enableScreen;
4239        synchronized (this) {
4240            booting = mBooting;
4241            mBooting = false;
4242            enableScreen = !mBooted;
4243            mBooted = true;
4244        }
4245
4246        if (booting) {
4247            finishBooting();
4248        }
4249
4250        if (enableScreen) {
4251            enableScreenAfterBoot();
4252        }
4253    }
4254
4255    public final void activityPaused(IBinder token) {
4256        final long origId = Binder.clearCallingIdentity();
4257        mMainStack.activityPaused(token, false);
4258        Binder.restoreCallingIdentity(origId);
4259    }
4260
4261    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4262            CharSequence description) {
4263        if (localLOGV) Slog.v(
4264            TAG, "Activity stopped: token=" + token);
4265
4266        // Refuse possible leaked file descriptors
4267        if (icicle != null && icicle.hasFileDescriptors()) {
4268            throw new IllegalArgumentException("File descriptors passed in Bundle");
4269        }
4270
4271        ActivityRecord r = null;
4272
4273        final long origId = Binder.clearCallingIdentity();
4274
4275        synchronized (this) {
4276            r = mMainStack.isInStackLocked(token);
4277            if (r != null) {
4278                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4279            }
4280        }
4281
4282        if (r != null) {
4283            sendPendingThumbnail(r, null, null, null, false);
4284        }
4285
4286        trimApplications();
4287
4288        Binder.restoreCallingIdentity(origId);
4289    }
4290
4291    public final void activityDestroyed(IBinder token) {
4292        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4293        mMainStack.activityDestroyed(token);
4294    }
4295
4296    public String getCallingPackage(IBinder token) {
4297        synchronized (this) {
4298            ActivityRecord r = getCallingRecordLocked(token);
4299            return r != null && r.app != null ? r.info.packageName : null;
4300        }
4301    }
4302
4303    public ComponentName getCallingActivity(IBinder token) {
4304        synchronized (this) {
4305            ActivityRecord r = getCallingRecordLocked(token);
4306            return r != null ? r.intent.getComponent() : null;
4307        }
4308    }
4309
4310    private ActivityRecord getCallingRecordLocked(IBinder token) {
4311        ActivityRecord r = mMainStack.isInStackLocked(token);
4312        if (r == null) {
4313            return null;
4314        }
4315        return r.resultTo;
4316    }
4317
4318    public ComponentName getActivityClassForToken(IBinder token) {
4319        synchronized(this) {
4320            ActivityRecord r = mMainStack.isInStackLocked(token);
4321            if (r == null) {
4322                return null;
4323            }
4324            return r.intent.getComponent();
4325        }
4326    }
4327
4328    public String getPackageForToken(IBinder token) {
4329        synchronized(this) {
4330            ActivityRecord r = mMainStack.isInStackLocked(token);
4331            if (r == null) {
4332                return null;
4333            }
4334            return r.packageName;
4335        }
4336    }
4337
4338    public IIntentSender getIntentSender(int type,
4339            String packageName, IBinder token, String resultWho,
4340            int requestCode, Intent[] intents, String[] resolvedTypes,
4341            int flags, Bundle options) {
4342        enforceNotIsolatedCaller("getIntentSender");
4343        // Refuse possible leaked file descriptors
4344        if (intents != null) {
4345            if (intents.length < 1) {
4346                throw new IllegalArgumentException("Intents array length must be >= 1");
4347            }
4348            for (int i=0; i<intents.length; i++) {
4349                Intent intent = intents[i];
4350                if (intent != null) {
4351                    if (intent.hasFileDescriptors()) {
4352                        throw new IllegalArgumentException("File descriptors passed in Intent");
4353                    }
4354                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4355                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4356                        throw new IllegalArgumentException(
4357                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4358                    }
4359                    intents[i] = new Intent(intent);
4360                }
4361            }
4362            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4363                throw new IllegalArgumentException(
4364                        "Intent array length does not match resolvedTypes length");
4365            }
4366        }
4367        if (options != null) {
4368            if (options.hasFileDescriptors()) {
4369                throw new IllegalArgumentException("File descriptors passed in options");
4370            }
4371        }
4372
4373        synchronized(this) {
4374            int callingUid = Binder.getCallingUid();
4375            try {
4376                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4377                    int uid = AppGlobals.getPackageManager()
4378                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4379                    if (!UserHandle.isSameApp(callingUid, uid)) {
4380                        String msg = "Permission Denial: getIntentSender() from pid="
4381                            + Binder.getCallingPid()
4382                            + ", uid=" + Binder.getCallingUid()
4383                            + ", (need uid=" + uid + ")"
4384                            + " is not allowed to send as package " + packageName;
4385                        Slog.w(TAG, msg);
4386                        throw new SecurityException(msg);
4387                    }
4388                }
4389
4390                if (DEBUG_MU)
4391                    Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
4392                            + Binder.getOrigCallingUid());
4393                return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
4394                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4395
4396            } catch (RemoteException e) {
4397                throw new SecurityException(e);
4398            }
4399        }
4400    }
4401
4402    IIntentSender getIntentSenderLocked(int type,
4403            String packageName, int callingUid, IBinder token, String resultWho,
4404            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4405            Bundle options) {
4406        if (DEBUG_MU)
4407            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4408        ActivityRecord activity = null;
4409        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4410            activity = mMainStack.isInStackLocked(token);
4411            if (activity == null) {
4412                return null;
4413            }
4414            if (activity.finishing) {
4415                return null;
4416            }
4417        }
4418
4419        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4420        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4421        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4422        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4423                |PendingIntent.FLAG_UPDATE_CURRENT);
4424
4425        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4426                type, packageName, activity, resultWho,
4427                requestCode, intents, resolvedTypes, flags, options);
4428        WeakReference<PendingIntentRecord> ref;
4429        ref = mIntentSenderRecords.get(key);
4430        PendingIntentRecord rec = ref != null ? ref.get() : null;
4431        if (rec != null) {
4432            if (!cancelCurrent) {
4433                if (updateCurrent) {
4434                    if (rec.key.requestIntent != null) {
4435                        rec.key.requestIntent.replaceExtras(intents != null ?
4436                                intents[intents.length - 1] : null);
4437                    }
4438                    if (intents != null) {
4439                        intents[intents.length-1] = rec.key.requestIntent;
4440                        rec.key.allIntents = intents;
4441                        rec.key.allResolvedTypes = resolvedTypes;
4442                    } else {
4443                        rec.key.allIntents = null;
4444                        rec.key.allResolvedTypes = null;
4445                    }
4446                }
4447                return rec;
4448            }
4449            rec.canceled = true;
4450            mIntentSenderRecords.remove(key);
4451        }
4452        if (noCreate) {
4453            return rec;
4454        }
4455        rec = new PendingIntentRecord(this, key, callingUid);
4456        mIntentSenderRecords.put(key, rec.ref);
4457        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4458            if (activity.pendingResults == null) {
4459                activity.pendingResults
4460                        = new HashSet<WeakReference<PendingIntentRecord>>();
4461            }
4462            activity.pendingResults.add(rec.ref);
4463        }
4464        return rec;
4465    }
4466
4467    public void cancelIntentSender(IIntentSender sender) {
4468        if (!(sender instanceof PendingIntentRecord)) {
4469            return;
4470        }
4471        synchronized(this) {
4472            PendingIntentRecord rec = (PendingIntentRecord)sender;
4473            try {
4474                int uid = AppGlobals.getPackageManager()
4475                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4476                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4477                    String msg = "Permission Denial: cancelIntentSender() from pid="
4478                        + Binder.getCallingPid()
4479                        + ", uid=" + Binder.getCallingUid()
4480                        + " is not allowed to cancel packges "
4481                        + rec.key.packageName;
4482                    Slog.w(TAG, msg);
4483                    throw new SecurityException(msg);
4484                }
4485            } catch (RemoteException e) {
4486                throw new SecurityException(e);
4487            }
4488            cancelIntentSenderLocked(rec, true);
4489        }
4490    }
4491
4492    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4493        rec.canceled = true;
4494        mIntentSenderRecords.remove(rec.key);
4495        if (cleanActivity && rec.key.activity != null) {
4496            rec.key.activity.pendingResults.remove(rec.ref);
4497        }
4498    }
4499
4500    public String getPackageForIntentSender(IIntentSender pendingResult) {
4501        if (!(pendingResult instanceof PendingIntentRecord)) {
4502            return null;
4503        }
4504        try {
4505            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4506            return res.key.packageName;
4507        } catch (ClassCastException e) {
4508        }
4509        return null;
4510    }
4511
4512    public int getUidForIntentSender(IIntentSender sender) {
4513        if (sender instanceof PendingIntentRecord) {
4514            try {
4515                PendingIntentRecord res = (PendingIntentRecord)sender;
4516                return res.uid;
4517            } catch (ClassCastException e) {
4518            }
4519        }
4520        return -1;
4521    }
4522
4523    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4524        if (!(pendingResult instanceof PendingIntentRecord)) {
4525            return false;
4526        }
4527        try {
4528            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4529            if (res.key.allIntents == null) {
4530                return false;
4531            }
4532            for (int i=0; i<res.key.allIntents.length; i++) {
4533                Intent intent = res.key.allIntents[i];
4534                if (intent.getPackage() != null && intent.getComponent() != null) {
4535                    return false;
4536                }
4537            }
4538            return true;
4539        } catch (ClassCastException e) {
4540        }
4541        return false;
4542    }
4543
4544    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4545        if (!(pendingResult instanceof PendingIntentRecord)) {
4546            return false;
4547        }
4548        try {
4549            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4550            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4551                return true;
4552            }
4553            return false;
4554        } catch (ClassCastException e) {
4555        }
4556        return false;
4557    }
4558
4559    public void setProcessLimit(int max) {
4560        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4561                "setProcessLimit()");
4562        synchronized (this) {
4563            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4564            mProcessLimitOverride = max;
4565        }
4566        trimApplications();
4567    }
4568
4569    public int getProcessLimit() {
4570        synchronized (this) {
4571            return mProcessLimitOverride;
4572        }
4573    }
4574
4575    void foregroundTokenDied(ForegroundToken token) {
4576        synchronized (ActivityManagerService.this) {
4577            synchronized (mPidsSelfLocked) {
4578                ForegroundToken cur
4579                    = mForegroundProcesses.get(token.pid);
4580                if (cur != token) {
4581                    return;
4582                }
4583                mForegroundProcesses.remove(token.pid);
4584                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4585                if (pr == null) {
4586                    return;
4587                }
4588                pr.forcingToForeground = null;
4589                pr.foregroundServices = false;
4590            }
4591            updateOomAdjLocked();
4592        }
4593    }
4594
4595    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4596        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4597                "setProcessForeground()");
4598        synchronized(this) {
4599            boolean changed = false;
4600
4601            synchronized (mPidsSelfLocked) {
4602                ProcessRecord pr = mPidsSelfLocked.get(pid);
4603                if (pr == null && isForeground) {
4604                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4605                    return;
4606                }
4607                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4608                if (oldToken != null) {
4609                    oldToken.token.unlinkToDeath(oldToken, 0);
4610                    mForegroundProcesses.remove(pid);
4611                    if (pr != null) {
4612                        pr.forcingToForeground = null;
4613                    }
4614                    changed = true;
4615                }
4616                if (isForeground && token != null) {
4617                    ForegroundToken newToken = new ForegroundToken() {
4618                        public void binderDied() {
4619                            foregroundTokenDied(this);
4620                        }
4621                    };
4622                    newToken.pid = pid;
4623                    newToken.token = token;
4624                    try {
4625                        token.linkToDeath(newToken, 0);
4626                        mForegroundProcesses.put(pid, newToken);
4627                        pr.forcingToForeground = token;
4628                        changed = true;
4629                    } catch (RemoteException e) {
4630                        // If the process died while doing this, we will later
4631                        // do the cleanup with the process death link.
4632                    }
4633                }
4634            }
4635
4636            if (changed) {
4637                updateOomAdjLocked();
4638            }
4639        }
4640    }
4641
4642    // =========================================================
4643    // PERMISSIONS
4644    // =========================================================
4645
4646    static class PermissionController extends IPermissionController.Stub {
4647        ActivityManagerService mActivityManagerService;
4648        PermissionController(ActivityManagerService activityManagerService) {
4649            mActivityManagerService = activityManagerService;
4650        }
4651
4652        public boolean checkPermission(String permission, int pid, int uid) {
4653            return mActivityManagerService.checkPermission(permission, pid,
4654                    uid) == PackageManager.PERMISSION_GRANTED;
4655        }
4656    }
4657
4658    /**
4659     * This can be called with or without the global lock held.
4660     */
4661    int checkComponentPermission(String permission, int pid, int uid,
4662            int owningUid, boolean exported) {
4663        // We might be performing an operation on behalf of an indirect binder
4664        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4665        // client identity accordingly before proceeding.
4666        Identity tlsIdentity = sCallerIdentity.get();
4667        if (tlsIdentity != null) {
4668            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4669                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4670            uid = tlsIdentity.uid;
4671            pid = tlsIdentity.pid;
4672        }
4673
4674        if (pid == MY_PID) {
4675            return PackageManager.PERMISSION_GRANTED;
4676        }
4677
4678        return ActivityManager.checkComponentPermission(permission, uid,
4679                owningUid, exported);
4680    }
4681
4682    /**
4683     * As the only public entry point for permissions checking, this method
4684     * can enforce the semantic that requesting a check on a null global
4685     * permission is automatically denied.  (Internally a null permission
4686     * string is used when calling {@link #checkComponentPermission} in cases
4687     * when only uid-based security is needed.)
4688     *
4689     * This can be called with or without the global lock held.
4690     */
4691    public int checkPermission(String permission, int pid, int uid) {
4692        if (permission == null) {
4693            return PackageManager.PERMISSION_DENIED;
4694        }
4695        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4696    }
4697
4698    /**
4699     * Binder IPC calls go through the public entry point.
4700     * This can be called with or without the global lock held.
4701     */
4702    int checkCallingPermission(String permission) {
4703        return checkPermission(permission,
4704                Binder.getCallingPid(),
4705                UserHandle.getAppId(Binder.getCallingUid()));
4706    }
4707
4708    /**
4709     * This can be called with or without the global lock held.
4710     */
4711    void enforceCallingPermission(String permission, String func) {
4712        if (checkCallingPermission(permission)
4713                == PackageManager.PERMISSION_GRANTED) {
4714            return;
4715        }
4716
4717        String msg = "Permission Denial: " + func + " from pid="
4718                + Binder.getCallingPid()
4719                + ", uid=" + Binder.getCallingUid()
4720                + " requires " + permission;
4721        Slog.w(TAG, msg);
4722        throw new SecurityException(msg);
4723    }
4724
4725    /**
4726     * Determine if UID is holding permissions required to access {@link Uri} in
4727     * the given {@link ProviderInfo}. Final permission checking is always done
4728     * in {@link ContentProvider}.
4729     */
4730    private final boolean checkHoldingPermissionsLocked(
4731            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4732        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4733                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4734
4735        if (pi.applicationInfo.uid == uid) {
4736            return true;
4737        } else if (!pi.exported) {
4738            return false;
4739        }
4740
4741        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4742        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4743        try {
4744            // check if target holds top-level <provider> permissions
4745            if (!readMet && pi.readPermission != null
4746                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4747                readMet = true;
4748            }
4749            if (!writeMet && pi.writePermission != null
4750                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4751                writeMet = true;
4752            }
4753
4754            // track if unprotected read/write is allowed; any denied
4755            // <path-permission> below removes this ability
4756            boolean allowDefaultRead = pi.readPermission == null;
4757            boolean allowDefaultWrite = pi.writePermission == null;
4758
4759            // check if target holds any <path-permission> that match uri
4760            final PathPermission[] pps = pi.pathPermissions;
4761            if (pps != null) {
4762                final String path = uri.getPath();
4763                int i = pps.length;
4764                while (i > 0 && (!readMet || !writeMet)) {
4765                    i--;
4766                    PathPermission pp = pps[i];
4767                    if (pp.match(path)) {
4768                        if (!readMet) {
4769                            final String pprperm = pp.getReadPermission();
4770                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4771                                    + pprperm + " for " + pp.getPath()
4772                                    + ": match=" + pp.match(path)
4773                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4774                            if (pprperm != null) {
4775                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4776                                    readMet = true;
4777                                } else {
4778                                    allowDefaultRead = false;
4779                                }
4780                            }
4781                        }
4782                        if (!writeMet) {
4783                            final String ppwperm = pp.getWritePermission();
4784                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4785                                    + ppwperm + " for " + pp.getPath()
4786                                    + ": match=" + pp.match(path)
4787                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4788                            if (ppwperm != null) {
4789                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4790                                    writeMet = true;
4791                                } else {
4792                                    allowDefaultWrite = false;
4793                                }
4794                            }
4795                        }
4796                    }
4797                }
4798            }
4799
4800            // grant unprotected <provider> read/write, if not blocked by
4801            // <path-permission> above
4802            if (allowDefaultRead) readMet = true;
4803            if (allowDefaultWrite) writeMet = true;
4804
4805        } catch (RemoteException e) {
4806            return false;
4807        }
4808
4809        return readMet && writeMet;
4810    }
4811
4812    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4813            int modeFlags) {
4814        // Root gets to do everything.
4815        if (uid == 0) {
4816            return true;
4817        }
4818        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4819        if (perms == null) return false;
4820        UriPermission perm = perms.get(uri);
4821        if (perm == null) return false;
4822        return (modeFlags&perm.modeFlags) == modeFlags;
4823    }
4824
4825    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4826        enforceNotIsolatedCaller("checkUriPermission");
4827
4828        // Another redirected-binder-call permissions check as in
4829        // {@link checkComponentPermission}.
4830        Identity tlsIdentity = sCallerIdentity.get();
4831        if (tlsIdentity != null) {
4832            uid = tlsIdentity.uid;
4833            pid = tlsIdentity.pid;
4834        }
4835
4836        uid = UserHandle.getAppId(uid);
4837        // Our own process gets to do everything.
4838        if (pid == MY_PID) {
4839            return PackageManager.PERMISSION_GRANTED;
4840        }
4841        synchronized(this) {
4842            return checkUriPermissionLocked(uri, uid, modeFlags)
4843                    ? PackageManager.PERMISSION_GRANTED
4844                    : PackageManager.PERMISSION_DENIED;
4845        }
4846    }
4847
4848    /**
4849     * Check if the targetPkg can be granted permission to access uri by
4850     * the callingUid using the given modeFlags.  Throws a security exception
4851     * if callingUid is not allowed to do this.  Returns the uid of the target
4852     * if the URI permission grant should be performed; returns -1 if it is not
4853     * needed (for example targetPkg already has permission to access the URI).
4854     * If you already know the uid of the target, you can supply it in
4855     * lastTargetUid else set that to -1.
4856     */
4857    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4858            Uri uri, int modeFlags, int lastTargetUid) {
4859        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4860                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4861        if (modeFlags == 0) {
4862            return -1;
4863        }
4864
4865        if (targetPkg != null) {
4866            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4867                    "Checking grant " + targetPkg + " permission to " + uri);
4868        }
4869
4870        final IPackageManager pm = AppGlobals.getPackageManager();
4871
4872        // If this is not a content: uri, we can't do anything with it.
4873        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4874            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4875                    "Can't grant URI permission for non-content URI: " + uri);
4876            return -1;
4877        }
4878
4879        String name = uri.getAuthority();
4880        ProviderInfo pi = null;
4881        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4882                UserHandle.getUserId(callingUid));
4883        if (cpr != null) {
4884            pi = cpr.info;
4885        } else {
4886            try {
4887                pi = pm.resolveContentProvider(name,
4888                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid));
4889            } catch (RemoteException ex) {
4890            }
4891        }
4892        if (pi == null) {
4893            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4894            return -1;
4895        }
4896
4897        int targetUid = lastTargetUid;
4898        if (targetUid < 0 && targetPkg != null) {
4899            try {
4900                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
4901                if (targetUid < 0) {
4902                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4903                            "Can't grant URI permission no uid for: " + targetPkg);
4904                    return -1;
4905                }
4906            } catch (RemoteException ex) {
4907                return -1;
4908            }
4909        }
4910
4911        if (targetUid >= 0) {
4912            // First...  does the target actually need this permission?
4913            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4914                // No need to grant the target this permission.
4915                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4916                        "Target " + targetPkg + " already has full permission to " + uri);
4917                return -1;
4918            }
4919        } else {
4920            // First...  there is no target package, so can anyone access it?
4921            boolean allowed = pi.exported;
4922            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4923                if (pi.readPermission != null) {
4924                    allowed = false;
4925                }
4926            }
4927            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4928                if (pi.writePermission != null) {
4929                    allowed = false;
4930                }
4931            }
4932            if (allowed) {
4933                return -1;
4934            }
4935        }
4936
4937        // Second...  is the provider allowing granting of URI permissions?
4938        if (!pi.grantUriPermissions) {
4939            throw new SecurityException("Provider " + pi.packageName
4940                    + "/" + pi.name
4941                    + " does not allow granting of Uri permissions (uri "
4942                    + uri + ")");
4943        }
4944        if (pi.uriPermissionPatterns != null) {
4945            final int N = pi.uriPermissionPatterns.length;
4946            boolean allowed = false;
4947            for (int i=0; i<N; i++) {
4948                if (pi.uriPermissionPatterns[i] != null
4949                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4950                    allowed = true;
4951                    break;
4952                }
4953            }
4954            if (!allowed) {
4955                throw new SecurityException("Provider " + pi.packageName
4956                        + "/" + pi.name
4957                        + " does not allow granting of permission to path of Uri "
4958                        + uri);
4959            }
4960        }
4961
4962        // Third...  does the caller itself have permission to access
4963        // this uri?
4964        if (callingUid != Process.myUid()) {
4965            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4966                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4967                    throw new SecurityException("Uid " + callingUid
4968                            + " does not have permission to uri " + uri);
4969                }
4970            }
4971        }
4972
4973        return targetUid;
4974    }
4975
4976    public int checkGrantUriPermission(int callingUid, String targetPkg,
4977            Uri uri, int modeFlags) {
4978        enforceNotIsolatedCaller("checkGrantUriPermission");
4979        synchronized(this) {
4980            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
4981        }
4982    }
4983
4984    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4985            Uri uri, int modeFlags, UriPermissionOwner owner) {
4986        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4987                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4988        if (modeFlags == 0) {
4989            return;
4990        }
4991
4992        // So here we are: the caller has the assumed permission
4993        // to the uri, and the target doesn't.  Let's now give this to
4994        // the target.
4995
4996        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4997                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
4998
4999        HashMap<Uri, UriPermission> targetUris
5000                = mGrantedUriPermissions.get(targetUid);
5001        if (targetUris == null) {
5002            targetUris = new HashMap<Uri, UriPermission>();
5003            mGrantedUriPermissions.put(targetUid, targetUris);
5004        }
5005
5006        UriPermission perm = targetUris.get(uri);
5007        if (perm == null) {
5008            perm = new UriPermission(targetUid, uri);
5009            targetUris.put(uri, perm);
5010        }
5011
5012        perm.modeFlags |= modeFlags;
5013        if (owner == null) {
5014            perm.globalModeFlags |= modeFlags;
5015        } else {
5016            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5017                 perm.readOwners.add(owner);
5018                 owner.addReadPermission(perm);
5019            }
5020            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5021                 perm.writeOwners.add(owner);
5022                 owner.addWritePermission(perm);
5023            }
5024        }
5025    }
5026
5027    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5028            int modeFlags, UriPermissionOwner owner) {
5029        if (targetPkg == null) {
5030            throw new NullPointerException("targetPkg");
5031        }
5032
5033        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5034        if (targetUid < 0) {
5035            return;
5036        }
5037
5038        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5039    }
5040
5041    static class NeededUriGrants extends ArrayList<Uri> {
5042        final String targetPkg;
5043        final int targetUid;
5044        final int flags;
5045
5046        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5047            targetPkg = _targetPkg;
5048            targetUid = _targetUid;
5049            flags = _flags;
5050        }
5051    }
5052
5053    /**
5054     * Like checkGrantUriPermissionLocked, but takes an Intent.
5055     */
5056    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5057            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5058        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5059                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5060                + " clip=" + (intent != null ? intent.getClipData() : null)
5061                + " from " + intent + "; flags=0x"
5062                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5063
5064        if (targetPkg == null) {
5065            throw new NullPointerException("targetPkg");
5066        }
5067
5068        if (intent == null) {
5069            return null;
5070        }
5071        Uri data = intent.getData();
5072        ClipData clip = intent.getClipData();
5073        if (data == null && clip == null) {
5074            return null;
5075        }
5076        if (data != null) {
5077            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5078                mode, needed != null ? needed.targetUid : -1);
5079            if (target > 0) {
5080                if (needed == null) {
5081                    needed = new NeededUriGrants(targetPkg, target, mode);
5082                }
5083                needed.add(data);
5084            }
5085        }
5086        if (clip != null) {
5087            for (int i=0; i<clip.getItemCount(); i++) {
5088                Uri uri = clip.getItemAt(i).getUri();
5089                if (uri != null) {
5090                    int target = -1;
5091                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5092                            mode, needed != null ? needed.targetUid : -1);
5093                    if (target > 0) {
5094                        if (needed == null) {
5095                            needed = new NeededUriGrants(targetPkg, target, mode);
5096                        }
5097                        needed.add(uri);
5098                    }
5099                } else {
5100                    Intent clipIntent = clip.getItemAt(i).getIntent();
5101                    if (clipIntent != null) {
5102                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5103                                callingUid, targetPkg, clipIntent, mode, needed);
5104                        if (newNeeded != null) {
5105                            needed = newNeeded;
5106                        }
5107                    }
5108                }
5109            }
5110        }
5111
5112        return needed;
5113    }
5114
5115    /**
5116     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5117     */
5118    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5119            UriPermissionOwner owner) {
5120        if (needed != null) {
5121            for (int i=0; i<needed.size(); i++) {
5122                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5123                        needed.get(i), needed.flags, owner);
5124            }
5125        }
5126    }
5127
5128    void grantUriPermissionFromIntentLocked(int callingUid,
5129            String targetPkg, Intent intent, UriPermissionOwner owner) {
5130        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5131                intent, intent != null ? intent.getFlags() : 0, null);
5132        if (needed == null) {
5133            return;
5134        }
5135
5136        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5137    }
5138
5139    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5140            Uri uri, int modeFlags) {
5141        enforceNotIsolatedCaller("grantUriPermission");
5142        synchronized(this) {
5143            final ProcessRecord r = getRecordForAppLocked(caller);
5144            if (r == null) {
5145                throw new SecurityException("Unable to find app for caller "
5146                        + caller
5147                        + " when granting permission to uri " + uri);
5148            }
5149            if (targetPkg == null) {
5150                throw new IllegalArgumentException("null target");
5151            }
5152            if (uri == null) {
5153                throw new IllegalArgumentException("null uri");
5154            }
5155
5156            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5157                    null);
5158        }
5159    }
5160
5161    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5162        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5163                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5164            HashMap<Uri, UriPermission> perms
5165                    = mGrantedUriPermissions.get(perm.uid);
5166            if (perms != null) {
5167                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5168                        "Removing " + perm.uid + " permission to " + perm.uri);
5169                perms.remove(perm.uri);
5170                if (perms.size() == 0) {
5171                    mGrantedUriPermissions.remove(perm.uid);
5172                }
5173            }
5174        }
5175    }
5176
5177    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5178            int modeFlags) {
5179        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5180                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5181        if (modeFlags == 0) {
5182            return;
5183        }
5184
5185        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5186                "Revoking all granted permissions to " + uri);
5187
5188        final IPackageManager pm = AppGlobals.getPackageManager();
5189
5190        final String authority = uri.getAuthority();
5191        ProviderInfo pi = null;
5192        int userId = UserHandle.getUserId(callingUid);
5193        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5194        if (cpr != null) {
5195            pi = cpr.info;
5196        } else {
5197            try {
5198                pi = pm.resolveContentProvider(authority,
5199                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5200            } catch (RemoteException ex) {
5201            }
5202        }
5203        if (pi == null) {
5204            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5205            return;
5206        }
5207
5208        // Does the caller have this permission on the URI?
5209        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5210            // Right now, if you are not the original owner of the permission,
5211            // you are not allowed to revoke it.
5212            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5213                throw new SecurityException("Uid " + callingUid
5214                        + " does not have permission to uri " + uri);
5215            //}
5216        }
5217
5218        // Go through all of the permissions and remove any that match.
5219        final List<String> SEGMENTS = uri.getPathSegments();
5220        if (SEGMENTS != null) {
5221            final int NS = SEGMENTS.size();
5222            int N = mGrantedUriPermissions.size();
5223            for (int i=0; i<N; i++) {
5224                HashMap<Uri, UriPermission> perms
5225                        = mGrantedUriPermissions.valueAt(i);
5226                Iterator<UriPermission> it = perms.values().iterator();
5227            toploop:
5228                while (it.hasNext()) {
5229                    UriPermission perm = it.next();
5230                    Uri targetUri = perm.uri;
5231                    if (!authority.equals(targetUri.getAuthority())) {
5232                        continue;
5233                    }
5234                    List<String> targetSegments = targetUri.getPathSegments();
5235                    if (targetSegments == null) {
5236                        continue;
5237                    }
5238                    if (targetSegments.size() < NS) {
5239                        continue;
5240                    }
5241                    for (int j=0; j<NS; j++) {
5242                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5243                            continue toploop;
5244                        }
5245                    }
5246                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5247                            "Revoking " + perm.uid + " permission to " + perm.uri);
5248                    perm.clearModes(modeFlags);
5249                    if (perm.modeFlags == 0) {
5250                        it.remove();
5251                    }
5252                }
5253                if (perms.size() == 0) {
5254                    mGrantedUriPermissions.remove(
5255                            mGrantedUriPermissions.keyAt(i));
5256                    N--;
5257                    i--;
5258                }
5259            }
5260        }
5261    }
5262
5263    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5264            int modeFlags) {
5265        enforceNotIsolatedCaller("revokeUriPermission");
5266        synchronized(this) {
5267            final ProcessRecord r = getRecordForAppLocked(caller);
5268            if (r == null) {
5269                throw new SecurityException("Unable to find app for caller "
5270                        + caller
5271                        + " when revoking permission to uri " + uri);
5272            }
5273            if (uri == null) {
5274                Slog.w(TAG, "revokeUriPermission: null uri");
5275                return;
5276            }
5277
5278            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5279                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5280            if (modeFlags == 0) {
5281                return;
5282            }
5283
5284            final IPackageManager pm = AppGlobals.getPackageManager();
5285
5286            final String authority = uri.getAuthority();
5287            ProviderInfo pi = null;
5288            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5289            if (cpr != null) {
5290                pi = cpr.info;
5291            } else {
5292                try {
5293                    pi = pm.resolveContentProvider(authority,
5294                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5295                } catch (RemoteException ex) {
5296                }
5297            }
5298            if (pi == null) {
5299                Slog.w(TAG, "No content provider found for permission revoke: "
5300                        + uri.toSafeString());
5301                return;
5302            }
5303
5304            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5305        }
5306    }
5307
5308    @Override
5309    public IBinder newUriPermissionOwner(String name) {
5310        enforceNotIsolatedCaller("newUriPermissionOwner");
5311        synchronized(this) {
5312            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5313            return owner.getExternalTokenLocked();
5314        }
5315    }
5316
5317    @Override
5318    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5319            Uri uri, int modeFlags) {
5320        synchronized(this) {
5321            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5322            if (owner == null) {
5323                throw new IllegalArgumentException("Unknown owner: " + token);
5324            }
5325            if (fromUid != Binder.getCallingUid()) {
5326                if (Binder.getCallingUid() != Process.myUid()) {
5327                    // Only system code can grant URI permissions on behalf
5328                    // of other users.
5329                    throw new SecurityException("nice try");
5330                }
5331            }
5332            if (targetPkg == null) {
5333                throw new IllegalArgumentException("null target");
5334            }
5335            if (uri == null) {
5336                throw new IllegalArgumentException("null uri");
5337            }
5338
5339            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5340        }
5341    }
5342
5343    @Override
5344    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5345        synchronized(this) {
5346            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5347            if (owner == null) {
5348                throw new IllegalArgumentException("Unknown owner: " + token);
5349            }
5350
5351            if (uri == null) {
5352                owner.removeUriPermissionsLocked(mode);
5353            } else {
5354                owner.removeUriPermissionLocked(uri, mode);
5355            }
5356        }
5357    }
5358
5359    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5360        synchronized (this) {
5361            ProcessRecord app =
5362                who != null ? getRecordForAppLocked(who) : null;
5363            if (app == null) return;
5364
5365            Message msg = Message.obtain();
5366            msg.what = WAIT_FOR_DEBUGGER_MSG;
5367            msg.obj = app;
5368            msg.arg1 = waiting ? 1 : 0;
5369            mHandler.sendMessage(msg);
5370        }
5371    }
5372
5373    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5374        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5375        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5376        outInfo.availMem = Process.getFreeMemory();
5377        outInfo.totalMem = Process.getTotalMemory();
5378        outInfo.threshold = homeAppMem;
5379        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5380        outInfo.hiddenAppThreshold = hiddenAppMem;
5381        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5382                ProcessList.SERVICE_ADJ);
5383        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5384                ProcessList.VISIBLE_APP_ADJ);
5385        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5386                ProcessList.FOREGROUND_APP_ADJ);
5387    }
5388
5389    // =========================================================
5390    // TASK MANAGEMENT
5391    // =========================================================
5392
5393    public List getTasks(int maxNum, int flags,
5394                         IThumbnailReceiver receiver) {
5395        ArrayList list = new ArrayList();
5396
5397        PendingThumbnailsRecord pending = null;
5398        IApplicationThread topThumbnail = null;
5399        ActivityRecord topRecord = null;
5400
5401        synchronized(this) {
5402            if (localLOGV) Slog.v(
5403                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5404                + ", receiver=" + receiver);
5405
5406            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5407                    != PackageManager.PERMISSION_GRANTED) {
5408                if (receiver != null) {
5409                    // If the caller wants to wait for pending thumbnails,
5410                    // it ain't gonna get them.
5411                    try {
5412                        receiver.finished();
5413                    } catch (RemoteException ex) {
5414                    }
5415                }
5416                String msg = "Permission Denial: getTasks() from pid="
5417                        + Binder.getCallingPid()
5418                        + ", uid=" + Binder.getCallingUid()
5419                        + " requires " + android.Manifest.permission.GET_TASKS;
5420                Slog.w(TAG, msg);
5421                throw new SecurityException(msg);
5422            }
5423
5424            int pos = mMainStack.mHistory.size()-1;
5425            ActivityRecord next =
5426                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5427            ActivityRecord top = null;
5428            TaskRecord curTask = null;
5429            int numActivities = 0;
5430            int numRunning = 0;
5431            while (pos >= 0 && maxNum > 0) {
5432                final ActivityRecord r = next;
5433                pos--;
5434                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5435
5436                // Initialize state for next task if needed.
5437                if (top == null ||
5438                        (top.state == ActivityState.INITIALIZING
5439                            && top.task == r.task)) {
5440                    top = r;
5441                    curTask = r.task;
5442                    numActivities = numRunning = 0;
5443                }
5444
5445                // Add 'r' into the current task.
5446                numActivities++;
5447                if (r.app != null && r.app.thread != null) {
5448                    numRunning++;
5449                }
5450
5451                if (localLOGV) Slog.v(
5452                    TAG, r.intent.getComponent().flattenToShortString()
5453                    + ": task=" + r.task);
5454
5455                // If the next one is a different task, generate a new
5456                // TaskInfo entry for what we have.
5457                if (next == null || next.task != curTask) {
5458                    ActivityManager.RunningTaskInfo ci
5459                            = new ActivityManager.RunningTaskInfo();
5460                    ci.id = curTask.taskId;
5461                    ci.baseActivity = r.intent.getComponent();
5462                    ci.topActivity = top.intent.getComponent();
5463                    if (top.thumbHolder != null) {
5464                        ci.description = top.thumbHolder.lastDescription;
5465                    }
5466                    ci.numActivities = numActivities;
5467                    ci.numRunning = numRunning;
5468                    //System.out.println(
5469                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5470                    if (ci.thumbnail == null && receiver != null) {
5471                        if (localLOGV) Slog.v(
5472                            TAG, "State=" + top.state + "Idle=" + top.idle
5473                            + " app=" + top.app
5474                            + " thr=" + (top.app != null ? top.app.thread : null));
5475                        if (top.state == ActivityState.RESUMED
5476                                || top.state == ActivityState.PAUSING) {
5477                            if (top.idle && top.app != null
5478                                && top.app.thread != null) {
5479                                topRecord = top;
5480                                topThumbnail = top.app.thread;
5481                            } else {
5482                                top.thumbnailNeeded = true;
5483                            }
5484                        }
5485                        if (pending == null) {
5486                            pending = new PendingThumbnailsRecord(receiver);
5487                        }
5488                        pending.pendingRecords.add(top);
5489                    }
5490                    list.add(ci);
5491                    maxNum--;
5492                    top = null;
5493                }
5494            }
5495
5496            if (pending != null) {
5497                mPendingThumbnails.add(pending);
5498            }
5499        }
5500
5501        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5502
5503        if (topThumbnail != null) {
5504            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5505            try {
5506                topThumbnail.requestThumbnail(topRecord.appToken);
5507            } catch (Exception e) {
5508                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5509                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5510            }
5511        }
5512
5513        if (pending == null && receiver != null) {
5514            // In this case all thumbnails were available and the client
5515            // is being asked to be told when the remaining ones come in...
5516            // which is unusually, since the top-most currently running
5517            // activity should never have a canned thumbnail!  Oh well.
5518            try {
5519                receiver.finished();
5520            } catch (RemoteException ex) {
5521            }
5522        }
5523
5524        return list;
5525    }
5526
5527    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5528            int flags, int userId) {
5529        final int callingUid = Binder.getCallingUid();
5530        if (userId != UserHandle.getCallingUserId()) {
5531            // Check if the caller is holding permissions for cross-user requests.
5532            if (checkComponentPermission(
5533                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5534                    Binder.getCallingPid(), callingUid, -1, true)
5535                    != PackageManager.PERMISSION_GRANTED) {
5536                String msg = "Permission Denial: "
5537                        + "Request to get recent tasks for user " + userId
5538                        + " but is calling from user " + UserHandle.getUserId(callingUid)
5539                        + "; this requires "
5540                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5541                Slog.w(TAG, msg);
5542                throw new SecurityException(msg);
5543            } else {
5544                if (userId == UserHandle.USER_CURRENT) {
5545                    userId = mCurrentUserId;
5546                }
5547            }
5548        }
5549
5550        synchronized (this) {
5551            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5552                    "getRecentTasks()");
5553            final boolean detailed = checkCallingPermission(
5554                    android.Manifest.permission.GET_DETAILED_TASKS)
5555                    == PackageManager.PERMISSION_GRANTED;
5556
5557            IPackageManager pm = AppGlobals.getPackageManager();
5558
5559            final int N = mRecentTasks.size();
5560            ArrayList<ActivityManager.RecentTaskInfo> res
5561                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5562                            maxNum < N ? maxNum : N);
5563            for (int i=0; i<N && maxNum > 0; i++) {
5564                TaskRecord tr = mRecentTasks.get(i);
5565                // Only add calling user's recent tasks
5566                if (tr.userId != userId) continue;
5567                // Return the entry if desired by the caller.  We always return
5568                // the first entry, because callers always expect this to be the
5569                // foreground app.  We may filter others if the caller has
5570                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5571                // we should exclude the entry.
5572
5573                if (i == 0
5574                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5575                        || (tr.intent == null)
5576                        || ((tr.intent.getFlags()
5577                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5578                    ActivityManager.RecentTaskInfo rti
5579                            = new ActivityManager.RecentTaskInfo();
5580                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5581                    rti.persistentId = tr.taskId;
5582                    rti.baseIntent = new Intent(
5583                            tr.intent != null ? tr.intent : tr.affinityIntent);
5584                    if (!detailed) {
5585                        rti.baseIntent.replaceExtras((Bundle)null);
5586                    }
5587                    rti.origActivity = tr.origActivity;
5588                    rti.description = tr.lastDescription;
5589
5590                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5591                        // Check whether this activity is currently available.
5592                        try {
5593                            if (rti.origActivity != null) {
5594                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5595                                        == null) {
5596                                    continue;
5597                                }
5598                            } else if (rti.baseIntent != null) {
5599                                if (pm.queryIntentActivities(rti.baseIntent,
5600                                        null, 0, userId) == null) {
5601                                    continue;
5602                                }
5603                            }
5604                        } catch (RemoteException e) {
5605                            // Will never happen.
5606                        }
5607                    }
5608
5609                    res.add(rti);
5610                    maxNum--;
5611                }
5612            }
5613            return res;
5614        }
5615    }
5616
5617    private TaskRecord taskForIdLocked(int id) {
5618        final int N = mRecentTasks.size();
5619        for (int i=0; i<N; i++) {
5620            TaskRecord tr = mRecentTasks.get(i);
5621            if (tr.taskId == id) {
5622                return tr;
5623            }
5624        }
5625        return null;
5626    }
5627
5628    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5629        synchronized (this) {
5630            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5631                    "getTaskThumbnails()");
5632            TaskRecord tr = taskForIdLocked(id);
5633            if (tr != null) {
5634                return mMainStack.getTaskThumbnailsLocked(tr);
5635            }
5636        }
5637        return null;
5638    }
5639
5640    public boolean removeSubTask(int taskId, int subTaskIndex) {
5641        synchronized (this) {
5642            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5643                    "removeSubTask()");
5644            long ident = Binder.clearCallingIdentity();
5645            try {
5646                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5647                        true) != null;
5648            } finally {
5649                Binder.restoreCallingIdentity(ident);
5650            }
5651        }
5652    }
5653
5654    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5655        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5656        Intent baseIntent = new Intent(
5657                tr.intent != null ? tr.intent : tr.affinityIntent);
5658        ComponentName component = baseIntent.getComponent();
5659        if (component == null) {
5660            Slog.w(TAG, "Now component for base intent of task: " + tr);
5661            return;
5662        }
5663
5664        // Find any running services associated with this app.
5665        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5666
5667        if (killProcesses) {
5668            // Find any running processes associated with this app.
5669            final String pkg = component.getPackageName();
5670            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5671            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5672            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5673                for (int i=0; i<uids.size(); i++) {
5674                    ProcessRecord proc = uids.valueAt(i);
5675                    if (proc.userId != tr.userId) {
5676                        continue;
5677                    }
5678                    if (!proc.pkgList.contains(pkg)) {
5679                        continue;
5680                    }
5681                    procs.add(proc);
5682                }
5683            }
5684
5685            // Kill the running processes.
5686            for (int i=0; i<procs.size(); i++) {
5687                ProcessRecord pr = procs.get(i);
5688                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5689                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5690                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5691                            pr.processName, pr.setAdj, "remove task");
5692                    pr.killedBackground = true;
5693                    Process.killProcessQuiet(pr.pid);
5694                } else {
5695                    pr.waitingToKill = "remove task";
5696                }
5697            }
5698        }
5699    }
5700
5701    public boolean removeTask(int taskId, int flags) {
5702        synchronized (this) {
5703            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5704                    "removeTask()");
5705            long ident = Binder.clearCallingIdentity();
5706            try {
5707                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5708                        false);
5709                if (r != null) {
5710                    mRecentTasks.remove(r.task);
5711                    cleanUpRemovedTaskLocked(r.task, flags);
5712                    return true;
5713                } else {
5714                    TaskRecord tr = null;
5715                    int i=0;
5716                    while (i < mRecentTasks.size()) {
5717                        TaskRecord t = mRecentTasks.get(i);
5718                        if (t.taskId == taskId) {
5719                            tr = t;
5720                            break;
5721                        }
5722                        i++;
5723                    }
5724                    if (tr != null) {
5725                        if (tr.numActivities <= 0) {
5726                            // Caller is just removing a recent task that is
5727                            // not actively running.  That is easy!
5728                            mRecentTasks.remove(i);
5729                            cleanUpRemovedTaskLocked(tr, flags);
5730                            return true;
5731                        } else {
5732                            Slog.w(TAG, "removeTask: task " + taskId
5733                                    + " does not have activities to remove, "
5734                                    + " but numActivities=" + tr.numActivities
5735                                    + ": " + tr);
5736                        }
5737                    }
5738                }
5739            } finally {
5740                Binder.restoreCallingIdentity(ident);
5741            }
5742        }
5743        return false;
5744    }
5745
5746    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5747        int j;
5748        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5749        TaskRecord jt = startTask;
5750
5751        // First look backwards
5752        for (j=startIndex-1; j>=0; j--) {
5753            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5754            if (r.task != jt) {
5755                jt = r.task;
5756                if (affinity.equals(jt.affinity)) {
5757                    return j;
5758                }
5759            }
5760        }
5761
5762        // Now look forwards
5763        final int N = mMainStack.mHistory.size();
5764        jt = startTask;
5765        for (j=startIndex+1; j<N; j++) {
5766            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5767            if (r.task != jt) {
5768                if (affinity.equals(jt.affinity)) {
5769                    return j;
5770                }
5771                jt = r.task;
5772            }
5773        }
5774
5775        // Might it be at the top?
5776        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5777            return N-1;
5778        }
5779
5780        return -1;
5781    }
5782
5783    /**
5784     * TODO: Add mController hook
5785     */
5786    public void moveTaskToFront(int task, int flags, Bundle options) {
5787        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5788                "moveTaskToFront()");
5789
5790        synchronized(this) {
5791            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5792                    Binder.getCallingUid(), "Task to front")) {
5793                ActivityOptions.abort(options);
5794                return;
5795            }
5796            final long origId = Binder.clearCallingIdentity();
5797            try {
5798                TaskRecord tr = taskForIdLocked(task);
5799                if (tr != null) {
5800                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5801                        mMainStack.mUserLeaving = true;
5802                    }
5803                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5804                        // Caller wants the home activity moved with it.  To accomplish this,
5805                        // we'll just move the home task to the top first.
5806                        mMainStack.moveHomeToFrontLocked();
5807                    }
5808                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5809                    return;
5810                }
5811                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5812                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5813                    if (hr.task.taskId == task) {
5814                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5815                            mMainStack.mUserLeaving = true;
5816                        }
5817                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5818                            // Caller wants the home activity moved with it.  To accomplish this,
5819                            // we'll just move the home task to the top first.
5820                            mMainStack.moveHomeToFrontLocked();
5821                        }
5822                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5823                        return;
5824                    }
5825                }
5826            } finally {
5827                Binder.restoreCallingIdentity(origId);
5828            }
5829            ActivityOptions.abort(options);
5830        }
5831    }
5832
5833    public void moveTaskToBack(int task) {
5834        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5835                "moveTaskToBack()");
5836
5837        synchronized(this) {
5838            if (mMainStack.mResumedActivity != null
5839                    && mMainStack.mResumedActivity.task.taskId == task) {
5840                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5841                        Binder.getCallingUid(), "Task to back")) {
5842                    return;
5843                }
5844            }
5845            final long origId = Binder.clearCallingIdentity();
5846            mMainStack.moveTaskToBackLocked(task, null);
5847            Binder.restoreCallingIdentity(origId);
5848        }
5849    }
5850
5851    /**
5852     * Moves an activity, and all of the other activities within the same task, to the bottom
5853     * of the history stack.  The activity's order within the task is unchanged.
5854     *
5855     * @param token A reference to the activity we wish to move
5856     * @param nonRoot If false then this only works if the activity is the root
5857     *                of a task; if true it will work for any activity in a task.
5858     * @return Returns true if the move completed, false if not.
5859     */
5860    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5861        enforceNotIsolatedCaller("moveActivityTaskToBack");
5862        synchronized(this) {
5863            final long origId = Binder.clearCallingIdentity();
5864            int taskId = getTaskForActivityLocked(token, !nonRoot);
5865            if (taskId >= 0) {
5866                return mMainStack.moveTaskToBackLocked(taskId, null);
5867            }
5868            Binder.restoreCallingIdentity(origId);
5869        }
5870        return false;
5871    }
5872
5873    public void moveTaskBackwards(int task) {
5874        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5875                "moveTaskBackwards()");
5876
5877        synchronized(this) {
5878            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5879                    Binder.getCallingUid(), "Task backwards")) {
5880                return;
5881            }
5882            final long origId = Binder.clearCallingIdentity();
5883            moveTaskBackwardsLocked(task);
5884            Binder.restoreCallingIdentity(origId);
5885        }
5886    }
5887
5888    private final void moveTaskBackwardsLocked(int task) {
5889        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5890    }
5891
5892    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5893        synchronized(this) {
5894            return getTaskForActivityLocked(token, onlyRoot);
5895        }
5896    }
5897
5898    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5899        final int N = mMainStack.mHistory.size();
5900        TaskRecord lastTask = null;
5901        for (int i=0; i<N; i++) {
5902            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5903            if (r.appToken == token) {
5904                if (!onlyRoot || lastTask != r.task) {
5905                    return r.task.taskId;
5906                }
5907                return -1;
5908            }
5909            lastTask = r.task;
5910        }
5911
5912        return -1;
5913    }
5914
5915    // =========================================================
5916    // THUMBNAILS
5917    // =========================================================
5918
5919    public void reportThumbnail(IBinder token,
5920            Bitmap thumbnail, CharSequence description) {
5921        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5922        final long origId = Binder.clearCallingIdentity();
5923        sendPendingThumbnail(null, token, thumbnail, description, true);
5924        Binder.restoreCallingIdentity(origId);
5925    }
5926
5927    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5928            Bitmap thumbnail, CharSequence description, boolean always) {
5929        TaskRecord task = null;
5930        ArrayList receivers = null;
5931
5932        //System.out.println("Send pending thumbnail: " + r);
5933
5934        synchronized(this) {
5935            if (r == null) {
5936                r = mMainStack.isInStackLocked(token);
5937                if (r == null) {
5938                    return;
5939                }
5940            }
5941            if (thumbnail == null && r.thumbHolder != null) {
5942                thumbnail = r.thumbHolder.lastThumbnail;
5943                description = r.thumbHolder.lastDescription;
5944            }
5945            if (thumbnail == null && !always) {
5946                // If there is no thumbnail, and this entry is not actually
5947                // going away, then abort for now and pick up the next
5948                // thumbnail we get.
5949                return;
5950            }
5951            task = r.task;
5952
5953            int N = mPendingThumbnails.size();
5954            int i=0;
5955            while (i<N) {
5956                PendingThumbnailsRecord pr =
5957                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5958                //System.out.println("Looking in " + pr.pendingRecords);
5959                if (pr.pendingRecords.remove(r)) {
5960                    if (receivers == null) {
5961                        receivers = new ArrayList();
5962                    }
5963                    receivers.add(pr);
5964                    if (pr.pendingRecords.size() == 0) {
5965                        pr.finished = true;
5966                        mPendingThumbnails.remove(i);
5967                        N--;
5968                        continue;
5969                    }
5970                }
5971                i++;
5972            }
5973        }
5974
5975        if (receivers != null) {
5976            final int N = receivers.size();
5977            for (int i=0; i<N; i++) {
5978                try {
5979                    PendingThumbnailsRecord pr =
5980                        (PendingThumbnailsRecord)receivers.get(i);
5981                    pr.receiver.newThumbnail(
5982                        task != null ? task.taskId : -1, thumbnail, description);
5983                    if (pr.finished) {
5984                        pr.receiver.finished();
5985                    }
5986                } catch (Exception e) {
5987                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
5988                }
5989            }
5990        }
5991    }
5992
5993    // =========================================================
5994    // CONTENT PROVIDERS
5995    // =========================================================
5996
5997    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5998        List<ProviderInfo> providers = null;
5999        try {
6000            providers = AppGlobals.getPackageManager().
6001                queryContentProviders(app.processName, app.uid,
6002                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6003        } catch (RemoteException ex) {
6004        }
6005        if (DEBUG_MU)
6006            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6007        int userId = app.userId;
6008        if (providers != null) {
6009            int N = providers.size();
6010            for (int i=0; i<N; i++) {
6011                ProviderInfo cpi =
6012                    (ProviderInfo)providers.get(i);
6013                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6014                        cpi.name, cpi.flags);
6015                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6016                    // This is a singleton provider, but a user besides the
6017                    // default user is asking to initialize a process it runs
6018                    // in...  well, no, it doesn't actually run in this process,
6019                    // it runs in the process of the default user.  Get rid of it.
6020                    providers.remove(i);
6021                    N--;
6022                    continue;
6023                }
6024
6025                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6026                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6027                if (cpr == null) {
6028                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6029                    mProviderMap.putProviderByClass(comp, cpr);
6030                }
6031                if (DEBUG_MU)
6032                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6033                app.pubProviders.put(cpi.name, cpr);
6034                app.addPackage(cpi.applicationInfo.packageName);
6035                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6036            }
6037        }
6038        return providers;
6039    }
6040
6041    /**
6042     * Check if {@link ProcessRecord} has a possible chance at accessing the
6043     * given {@link ProviderInfo}. Final permission checking is always done
6044     * in {@link ContentProvider}.
6045     */
6046    private final String checkContentProviderPermissionLocked(
6047            ProviderInfo cpi, ProcessRecord r) {
6048        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6049        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6050        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6051                cpi.applicationInfo.uid, cpi.exported)
6052                == PackageManager.PERMISSION_GRANTED) {
6053            return null;
6054        }
6055        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6056                cpi.applicationInfo.uid, cpi.exported)
6057                == PackageManager.PERMISSION_GRANTED) {
6058            return null;
6059        }
6060
6061        PathPermission[] pps = cpi.pathPermissions;
6062        if (pps != null) {
6063            int i = pps.length;
6064            while (i > 0) {
6065                i--;
6066                PathPermission pp = pps[i];
6067                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6068                        cpi.applicationInfo.uid, cpi.exported)
6069                        == PackageManager.PERMISSION_GRANTED) {
6070                    return null;
6071                }
6072                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6073                        cpi.applicationInfo.uid, cpi.exported)
6074                        == PackageManager.PERMISSION_GRANTED) {
6075                    return null;
6076                }
6077            }
6078        }
6079
6080        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6081        if (perms != null) {
6082            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6083                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6084                    return null;
6085                }
6086            }
6087        }
6088
6089        String msg;
6090        if (!cpi.exported) {
6091            msg = "Permission Denial: opening provider " + cpi.name
6092                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6093                    + ", uid=" + callingUid + ") that is not exported from uid "
6094                    + cpi.applicationInfo.uid;
6095        } else {
6096            msg = "Permission Denial: opening provider " + cpi.name
6097                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6098                    + ", uid=" + callingUid + ") requires "
6099                    + cpi.readPermission + " or " + cpi.writePermission;
6100        }
6101        Slog.w(TAG, msg);
6102        return msg;
6103    }
6104
6105    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6106            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6107        if (r != null) {
6108            for (int i=0; i<r.conProviders.size(); i++) {
6109                ContentProviderConnection conn = r.conProviders.get(i);
6110                if (conn.provider == cpr) {
6111                    if (DEBUG_PROVIDER) Slog.v(TAG,
6112                            "Adding provider requested by "
6113                            + r.processName + " from process "
6114                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6115                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6116                    if (stable) {
6117                        conn.stableCount++;
6118                        conn.numStableIncs++;
6119                    } else {
6120                        conn.unstableCount++;
6121                        conn.numUnstableIncs++;
6122                    }
6123                    return conn;
6124                }
6125            }
6126            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6127            if (stable) {
6128                conn.stableCount = 1;
6129                conn.numStableIncs = 1;
6130            } else {
6131                conn.unstableCount = 1;
6132                conn.numUnstableIncs = 1;
6133            }
6134            cpr.connections.add(conn);
6135            r.conProviders.add(conn);
6136            return conn;
6137        }
6138        cpr.addExternalProcessHandleLocked(externalProcessToken);
6139        return null;
6140    }
6141
6142    boolean decProviderCountLocked(ContentProviderConnection conn,
6143            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6144        if (conn != null) {
6145            cpr = conn.provider;
6146            if (DEBUG_PROVIDER) Slog.v(TAG,
6147                    "Removing provider requested by "
6148                    + conn.client.processName + " from process "
6149                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6150                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6151            if (stable) {
6152                conn.stableCount--;
6153            } else {
6154                conn.unstableCount--;
6155            }
6156            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6157                cpr.connections.remove(conn);
6158                conn.client.conProviders.remove(conn);
6159                return true;
6160            }
6161            return false;
6162        }
6163        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6164        return false;
6165    }
6166
6167    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6168            String name, IBinder token, boolean stable) {
6169        ContentProviderRecord cpr;
6170        ContentProviderConnection conn = null;
6171        ProviderInfo cpi = null;
6172
6173        synchronized(this) {
6174            ProcessRecord r = null;
6175            if (caller != null) {
6176                r = getRecordForAppLocked(caller);
6177                if (r == null) {
6178                    throw new SecurityException(
6179                            "Unable to find app for caller " + caller
6180                          + " (pid=" + Binder.getCallingPid()
6181                          + ") when getting content provider " + name);
6182                }
6183            }
6184
6185            // First check if this content provider has been published...
6186            int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid());
6187            cpr = mProviderMap.getProviderByName(name, userId);
6188            boolean providerRunning = cpr != null;
6189            if (providerRunning) {
6190                cpi = cpr.info;
6191                String msg;
6192                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6193                    throw new SecurityException(msg);
6194                }
6195
6196                if (r != null && cpr.canRunHere(r)) {
6197                    // This provider has been published or is in the process
6198                    // of being published...  but it is also allowed to run
6199                    // in the caller's process, so don't make a connection
6200                    // and just let the caller instantiate its own instance.
6201                    ContentProviderHolder holder = cpr.newHolder(null);
6202                    // don't give caller the provider object, it needs
6203                    // to make its own.
6204                    holder.provider = null;
6205                    return holder;
6206                }
6207
6208                final long origId = Binder.clearCallingIdentity();
6209
6210                // In this case the provider instance already exists, so we can
6211                // return it right away.
6212                conn = incProviderCountLocked(r, cpr, token, stable);
6213                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6214                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6215                        // If this is a perceptible app accessing the provider,
6216                        // make sure to count it as being accessed and thus
6217                        // back up on the LRU list.  This is good because
6218                        // content providers are often expensive to start.
6219                        updateLruProcessLocked(cpr.proc, false, true);
6220                    }
6221                }
6222
6223                if (cpr.proc != null) {
6224                    if (false) {
6225                        if (cpr.name.flattenToShortString().equals(
6226                                "com.android.providers.calendar/.CalendarProvider2")) {
6227                            Slog.v(TAG, "****************** KILLING "
6228                                + cpr.name.flattenToShortString());
6229                            Process.killProcess(cpr.proc.pid);
6230                        }
6231                    }
6232                    boolean success = updateOomAdjLocked(cpr.proc);
6233                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6234                    // NOTE: there is still a race here where a signal could be
6235                    // pending on the process even though we managed to update its
6236                    // adj level.  Not sure what to do about this, but at least
6237                    // the race is now smaller.
6238                    if (!success) {
6239                        // Uh oh...  it looks like the provider's process
6240                        // has been killed on us.  We need to wait for a new
6241                        // process to be started, and make sure its death
6242                        // doesn't kill our process.
6243                        Slog.i(TAG,
6244                                "Existing provider " + cpr.name.flattenToShortString()
6245                                + " is crashing; detaching " + r);
6246                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6247                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6248                        if (!lastRef) {
6249                            // This wasn't the last ref our process had on
6250                            // the provider...  we have now been killed, bail.
6251                            return null;
6252                        }
6253                        providerRunning = false;
6254                        conn = null;
6255                    }
6256                }
6257
6258                Binder.restoreCallingIdentity(origId);
6259            }
6260
6261            boolean singleton;
6262            if (!providerRunning) {
6263                try {
6264                    cpi = AppGlobals.getPackageManager().
6265                        resolveContentProvider(name,
6266                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6267                } catch (RemoteException ex) {
6268                }
6269                if (cpi == null) {
6270                    return null;
6271                }
6272                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6273                        cpi.name, cpi.flags);
6274                if (singleton) {
6275                    userId = 0;
6276                }
6277                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6278
6279                String msg;
6280                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6281                    throw new SecurityException(msg);
6282                }
6283
6284                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6285                        && !cpi.processName.equals("system")) {
6286                    // If this content provider does not run in the system
6287                    // process, and the system is not yet ready to run other
6288                    // processes, then fail fast instead of hanging.
6289                    throw new IllegalArgumentException(
6290                            "Attempt to launch content provider before system ready");
6291                }
6292
6293                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6294                cpr = mProviderMap.getProviderByClass(comp, userId);
6295                final boolean firstClass = cpr == null;
6296                if (firstClass) {
6297                    try {
6298                        ApplicationInfo ai =
6299                            AppGlobals.getPackageManager().
6300                                getApplicationInfo(
6301                                        cpi.applicationInfo.packageName,
6302                                        STOCK_PM_FLAGS, userId);
6303                        if (ai == null) {
6304                            Slog.w(TAG, "No package info for content provider "
6305                                    + cpi.name);
6306                            return null;
6307                        }
6308                        ai = getAppInfoForUser(ai, userId);
6309                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6310                    } catch (RemoteException ex) {
6311                        // pm is in same process, this will never happen.
6312                    }
6313                }
6314
6315                if (r != null && cpr.canRunHere(r)) {
6316                    // If this is a multiprocess provider, then just return its
6317                    // info and allow the caller to instantiate it.  Only do
6318                    // this if the provider is the same user as the caller's
6319                    // process, or can run as root (so can be in any process).
6320                    return cpr.newHolder(null);
6321                }
6322
6323                if (DEBUG_PROVIDER) {
6324                    RuntimeException e = new RuntimeException("here");
6325                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6326                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6327                }
6328
6329                // This is single process, and our app is now connecting to it.
6330                // See if we are already in the process of launching this
6331                // provider.
6332                final int N = mLaunchingProviders.size();
6333                int i;
6334                for (i=0; i<N; i++) {
6335                    if (mLaunchingProviders.get(i) == cpr) {
6336                        break;
6337                    }
6338                }
6339
6340                // If the provider is not already being launched, then get it
6341                // started.
6342                if (i >= N) {
6343                    final long origId = Binder.clearCallingIdentity();
6344
6345                    try {
6346                        // Content provider is now in use, its package can't be stopped.
6347                        try {
6348                            AppGlobals.getPackageManager().setPackageStoppedState(
6349                                    cpr.appInfo.packageName, false, userId);
6350                        } catch (RemoteException e) {
6351                        } catch (IllegalArgumentException e) {
6352                            Slog.w(TAG, "Failed trying to unstop package "
6353                                    + cpr.appInfo.packageName + ": " + e);
6354                        }
6355
6356                        ProcessRecord proc = startProcessLocked(cpi.processName,
6357                                cpr.appInfo, false, 0, "content provider",
6358                                new ComponentName(cpi.applicationInfo.packageName,
6359                                        cpi.name), false, false);
6360                        if (proc == null) {
6361                            Slog.w(TAG, "Unable to launch app "
6362                                    + cpi.applicationInfo.packageName + "/"
6363                                    + cpi.applicationInfo.uid + " for provider "
6364                                    + name + ": process is bad");
6365                            return null;
6366                        }
6367                        cpr.launchingApp = proc;
6368                        mLaunchingProviders.add(cpr);
6369                    } finally {
6370                        Binder.restoreCallingIdentity(origId);
6371                    }
6372                }
6373
6374                // Make sure the provider is published (the same provider class
6375                // may be published under multiple names).
6376                if (firstClass) {
6377                    mProviderMap.putProviderByClass(comp, cpr);
6378                }
6379
6380                mProviderMap.putProviderByName(name, cpr);
6381                conn = incProviderCountLocked(r, cpr, token, stable);
6382                if (conn != null) {
6383                    conn.waiting = true;
6384                }
6385            }
6386        }
6387
6388        // Wait for the provider to be published...
6389        synchronized (cpr) {
6390            while (cpr.provider == null) {
6391                if (cpr.launchingApp == null) {
6392                    Slog.w(TAG, "Unable to launch app "
6393                            + cpi.applicationInfo.packageName + "/"
6394                            + cpi.applicationInfo.uid + " for provider "
6395                            + name + ": launching app became null");
6396                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6397                            cpi.applicationInfo.packageName,
6398                            cpi.applicationInfo.uid, name);
6399                    return null;
6400                }
6401                try {
6402                    if (DEBUG_MU) {
6403                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6404                                + cpr.launchingApp);
6405                    }
6406                    if (conn != null) {
6407                        conn.waiting = true;
6408                    }
6409                    cpr.wait();
6410                } catch (InterruptedException ex) {
6411                } finally {
6412                    if (conn != null) {
6413                        conn.waiting = false;
6414                    }
6415                }
6416            }
6417        }
6418        return cpr != null ? cpr.newHolder(conn) : null;
6419    }
6420
6421    public final ContentProviderHolder getContentProvider(
6422            IApplicationThread caller, String name, boolean stable) {
6423        enforceNotIsolatedCaller("getContentProvider");
6424        if (caller == null) {
6425            String msg = "null IApplicationThread when getting content provider "
6426                    + name;
6427            Slog.w(TAG, msg);
6428            throw new SecurityException(msg);
6429        }
6430
6431        return getContentProviderImpl(caller, name, null, stable);
6432    }
6433
6434    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6435        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6436            "Do not have permission in call getContentProviderExternal()");
6437        return getContentProviderExternalUnchecked(name, token);
6438    }
6439
6440    private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
6441        return getContentProviderImpl(null, name, token, true);
6442    }
6443
6444    /**
6445     * Drop a content provider from a ProcessRecord's bookkeeping
6446     * @param cpr
6447     */
6448    public void removeContentProvider(IBinder connection, boolean stable) {
6449        enforceNotIsolatedCaller("removeContentProvider");
6450        synchronized (this) {
6451            ContentProviderConnection conn;
6452            try {
6453                conn = (ContentProviderConnection)connection;
6454            } catch (ClassCastException e) {
6455                String msg ="removeContentProvider: " + connection
6456                        + " not a ContentProviderConnection";
6457                Slog.w(TAG, msg);
6458                throw new IllegalArgumentException(msg);
6459            }
6460            if (conn == null) {
6461                throw new NullPointerException("connection is null");
6462            }
6463            if (decProviderCountLocked(conn, null, null, stable)) {
6464                updateOomAdjLocked();
6465            }
6466        }
6467    }
6468
6469    public void removeContentProviderExternal(String name, IBinder token) {
6470        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6471            "Do not have permission in call removeContentProviderExternal()");
6472        removeContentProviderExternalUnchecked(name, token);
6473    }
6474
6475    private void removeContentProviderExternalUnchecked(String name, IBinder token) {
6476        synchronized (this) {
6477            ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6478                    Binder.getOrigCallingUser());
6479            if(cpr == null) {
6480                //remove from mProvidersByClass
6481                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6482                return;
6483            }
6484
6485            //update content provider record entry info
6486            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6487            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6488                    Binder.getOrigCallingUser());
6489            if (localCpr.hasExternalProcessHandles()) {
6490                if (localCpr.removeExternalProcessHandleLocked(token)) {
6491                    updateOomAdjLocked();
6492                } else {
6493                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6494                            + " with no external reference for token: "
6495                            + token + ".");
6496                }
6497            } else {
6498                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6499                        + " with no external references.");
6500            }
6501        }
6502    }
6503
6504    public final void publishContentProviders(IApplicationThread caller,
6505            List<ContentProviderHolder> providers) {
6506        if (providers == null) {
6507            return;
6508        }
6509
6510        enforceNotIsolatedCaller("publishContentProviders");
6511        synchronized (this) {
6512            final ProcessRecord r = getRecordForAppLocked(caller);
6513            if (DEBUG_MU)
6514                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6515            if (r == null) {
6516                throw new SecurityException(
6517                        "Unable to find app for caller " + caller
6518                      + " (pid=" + Binder.getCallingPid()
6519                      + ") when publishing content providers");
6520            }
6521
6522            final long origId = Binder.clearCallingIdentity();
6523
6524            final int N = providers.size();
6525            for (int i=0; i<N; i++) {
6526                ContentProviderHolder src = providers.get(i);
6527                if (src == null || src.info == null || src.provider == null) {
6528                    continue;
6529                }
6530                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6531                if (DEBUG_MU)
6532                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6533                if (dst != null) {
6534                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6535                    mProviderMap.putProviderByClass(comp, dst);
6536                    String names[] = dst.info.authority.split(";");
6537                    for (int j = 0; j < names.length; j++) {
6538                        mProviderMap.putProviderByName(names[j], dst);
6539                    }
6540
6541                    int NL = mLaunchingProviders.size();
6542                    int j;
6543                    for (j=0; j<NL; j++) {
6544                        if (mLaunchingProviders.get(j) == dst) {
6545                            mLaunchingProviders.remove(j);
6546                            j--;
6547                            NL--;
6548                        }
6549                    }
6550                    synchronized (dst) {
6551                        dst.provider = src.provider;
6552                        dst.proc = r;
6553                        dst.notifyAll();
6554                    }
6555                    updateOomAdjLocked(r);
6556                }
6557            }
6558
6559            Binder.restoreCallingIdentity(origId);
6560        }
6561    }
6562
6563    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6564        ContentProviderConnection conn;
6565        try {
6566            conn = (ContentProviderConnection)connection;
6567        } catch (ClassCastException e) {
6568            String msg ="refContentProvider: " + connection
6569                    + " not a ContentProviderConnection";
6570            Slog.w(TAG, msg);
6571            throw new IllegalArgumentException(msg);
6572        }
6573        if (conn == null) {
6574            throw new NullPointerException("connection is null");
6575        }
6576
6577        synchronized (this) {
6578            if (stable > 0) {
6579                conn.numStableIncs += stable;
6580            }
6581            stable = conn.stableCount + stable;
6582            if (stable < 0) {
6583                throw new IllegalStateException("stableCount < 0: " + stable);
6584            }
6585
6586            if (unstable > 0) {
6587                conn.numUnstableIncs += unstable;
6588            }
6589            unstable = conn.unstableCount + unstable;
6590            if (unstable < 0) {
6591                throw new IllegalStateException("unstableCount < 0: " + unstable);
6592            }
6593
6594            if ((stable+unstable) <= 0) {
6595                throw new IllegalStateException("ref counts can't go to zero here: stable="
6596                        + stable + " unstable=" + unstable);
6597            }
6598            conn.stableCount = stable;
6599            conn.unstableCount = unstable;
6600            return !conn.dead;
6601        }
6602    }
6603
6604    public void unstableProviderDied(IBinder connection) {
6605        ContentProviderConnection conn;
6606        try {
6607            conn = (ContentProviderConnection)connection;
6608        } catch (ClassCastException e) {
6609            String msg ="refContentProvider: " + connection
6610                    + " not a ContentProviderConnection";
6611            Slog.w(TAG, msg);
6612            throw new IllegalArgumentException(msg);
6613        }
6614        if (conn == null) {
6615            throw new NullPointerException("connection is null");
6616        }
6617
6618        // Safely retrieve the content provider associated with the connection.
6619        IContentProvider provider;
6620        synchronized (this) {
6621            provider = conn.provider.provider;
6622        }
6623
6624        if (provider == null) {
6625            // Um, yeah, we're way ahead of you.
6626            return;
6627        }
6628
6629        // Make sure the caller is being honest with us.
6630        if (provider.asBinder().pingBinder()) {
6631            // Er, no, still looks good to us.
6632            synchronized (this) {
6633                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6634                        + " says " + conn + " died, but we don't agree");
6635                return;
6636            }
6637        }
6638
6639        // Well look at that!  It's dead!
6640        synchronized (this) {
6641            if (conn.provider.provider != provider) {
6642                // But something changed...  good enough.
6643                return;
6644            }
6645
6646            ProcessRecord proc = conn.provider.proc;
6647            if (proc == null || proc.thread == null) {
6648                // Seems like the process is already cleaned up.
6649                return;
6650            }
6651
6652            // As far as we're concerned, this is just like receiving a
6653            // death notification...  just a bit prematurely.
6654            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6655                    + ") early provider death");
6656            final long ident = Binder.clearCallingIdentity();
6657            try {
6658                appDiedLocked(proc, proc.pid, proc.thread);
6659            } finally {
6660                Binder.restoreCallingIdentity(ident);
6661            }
6662        }
6663    }
6664
6665    public static final void installSystemProviders() {
6666        List<ProviderInfo> providers;
6667        synchronized (mSelf) {
6668            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6669            providers = mSelf.generateApplicationProvidersLocked(app);
6670            if (providers != null) {
6671                for (int i=providers.size()-1; i>=0; i--) {
6672                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6673                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6674                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6675                                + ": not system .apk");
6676                        providers.remove(i);
6677                    }
6678                }
6679            }
6680        }
6681        if (providers != null) {
6682            mSystemThread.installSystemProviders(providers);
6683        }
6684
6685        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6686
6687        mSelf.mUsageStatsService.monitorPackages();
6688    }
6689
6690    /**
6691     * Allows app to retrieve the MIME type of a URI without having permission
6692     * to access its content provider.
6693     *
6694     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6695     *
6696     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6697     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6698     */
6699    public String getProviderMimeType(Uri uri) {
6700        enforceNotIsolatedCaller("getProviderMimeType");
6701        final String name = uri.getAuthority();
6702        final long ident = Binder.clearCallingIdentity();
6703        ContentProviderHolder holder = null;
6704
6705        try {
6706            holder = getContentProviderExternalUnchecked(name, null);
6707            if (holder != null) {
6708                return holder.provider.getType(uri);
6709            }
6710        } catch (RemoteException e) {
6711            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6712            return null;
6713        } finally {
6714            if (holder != null) {
6715                removeContentProviderExternalUnchecked(name, null);
6716            }
6717            Binder.restoreCallingIdentity(ident);
6718        }
6719
6720        return null;
6721    }
6722
6723    // =========================================================
6724    // GLOBAL MANAGEMENT
6725    // =========================================================
6726
6727    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6728            ApplicationInfo info, String customProcess, boolean isolated) {
6729        String proc = customProcess != null ? customProcess : info.processName;
6730        BatteryStatsImpl.Uid.Proc ps = null;
6731        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6732        int uid = info.uid;
6733        if (isolated) {
6734            int userId = UserHandle.getUserId(uid);
6735            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6736            uid = 0;
6737            while (true) {
6738                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6739                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6740                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6741                }
6742                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6743                mNextIsolatedProcessUid++;
6744                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6745                    // No process for this uid, use it.
6746                    break;
6747                }
6748                stepsLeft--;
6749                if (stepsLeft <= 0) {
6750                    return null;
6751                }
6752            }
6753        }
6754        synchronized (stats) {
6755            ps = stats.getProcessStatsLocked(info.uid, proc);
6756        }
6757        return new ProcessRecord(ps, thread, info, proc, uid);
6758    }
6759
6760    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6761        ProcessRecord app;
6762        if (!isolated) {
6763            app = getProcessRecordLocked(info.processName, info.uid);
6764        } else {
6765            app = null;
6766        }
6767
6768        if (app == null) {
6769            app = newProcessRecordLocked(null, info, null, isolated);
6770            mProcessNames.put(info.processName, app.uid, app);
6771            if (isolated) {
6772                mIsolatedProcesses.put(app.uid, app);
6773            }
6774            updateLruProcessLocked(app, true, true);
6775        }
6776
6777        // This package really, really can not be stopped.
6778        try {
6779            AppGlobals.getPackageManager().setPackageStoppedState(
6780                    info.packageName, false, UserHandle.getUserId(app.uid));
6781        } catch (RemoteException e) {
6782        } catch (IllegalArgumentException e) {
6783            Slog.w(TAG, "Failed trying to unstop package "
6784                    + info.packageName + ": " + e);
6785        }
6786
6787        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6788                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6789            app.persistent = true;
6790            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6791        }
6792        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6793            mPersistentStartingProcesses.add(app);
6794            startProcessLocked(app, "added application", app.processName);
6795        }
6796
6797        return app;
6798    }
6799
6800    public void unhandledBack() {
6801        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6802                "unhandledBack()");
6803
6804        synchronized(this) {
6805            int count = mMainStack.mHistory.size();
6806            if (DEBUG_SWITCH) Slog.d(
6807                TAG, "Performing unhandledBack(): stack size = " + count);
6808            if (count > 1) {
6809                final long origId = Binder.clearCallingIdentity();
6810                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6811                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6812                Binder.restoreCallingIdentity(origId);
6813            }
6814        }
6815    }
6816
6817    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6818        enforceNotIsolatedCaller("openContentUri");
6819        String name = uri.getAuthority();
6820        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
6821        ParcelFileDescriptor pfd = null;
6822        if (cph != null) {
6823            // We record the binder invoker's uid in thread-local storage before
6824            // going to the content provider to open the file.  Later, in the code
6825            // that handles all permissions checks, we look for this uid and use
6826            // that rather than the Activity Manager's own uid.  The effect is that
6827            // we do the check against the caller's permissions even though it looks
6828            // to the content provider like the Activity Manager itself is making
6829            // the request.
6830            sCallerIdentity.set(new Identity(
6831                    Binder.getCallingPid(), Binder.getCallingUid()));
6832            try {
6833                pfd = cph.provider.openFile(uri, "r");
6834            } catch (FileNotFoundException e) {
6835                // do nothing; pfd will be returned null
6836            } finally {
6837                // Ensure that whatever happens, we clean up the identity state
6838                sCallerIdentity.remove();
6839            }
6840
6841            // We've got the fd now, so we're done with the provider.
6842            removeContentProviderExternalUnchecked(name, null);
6843        } else {
6844            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6845        }
6846        return pfd;
6847    }
6848
6849    // Actually is sleeping or shutting down or whatever else in the future
6850    // is an inactive state.
6851    public boolean isSleeping() {
6852        return mSleeping || mShuttingDown;
6853    }
6854
6855    public void goingToSleep() {
6856        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6857                != PackageManager.PERMISSION_GRANTED) {
6858            throw new SecurityException("Requires permission "
6859                    + android.Manifest.permission.DEVICE_POWER);
6860        }
6861
6862        synchronized(this) {
6863            mWentToSleep = true;
6864            updateEventDispatchingLocked();
6865
6866            if (!mSleeping) {
6867                mSleeping = true;
6868                mMainStack.stopIfSleepingLocked();
6869
6870                // Initialize the wake times of all processes.
6871                checkExcessivePowerUsageLocked(false);
6872                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6873                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6874                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6875            }
6876        }
6877    }
6878
6879    public boolean shutdown(int timeout) {
6880        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6881                != PackageManager.PERMISSION_GRANTED) {
6882            throw new SecurityException("Requires permission "
6883                    + android.Manifest.permission.SHUTDOWN);
6884        }
6885
6886        boolean timedout = false;
6887
6888        synchronized(this) {
6889            mShuttingDown = true;
6890            updateEventDispatchingLocked();
6891
6892            if (mMainStack.mResumedActivity != null) {
6893                mMainStack.stopIfSleepingLocked();
6894                final long endTime = System.currentTimeMillis() + timeout;
6895                while (mMainStack.mResumedActivity != null
6896                        || mMainStack.mPausingActivity != null) {
6897                    long delay = endTime - System.currentTimeMillis();
6898                    if (delay <= 0) {
6899                        Slog.w(TAG, "Activity manager shutdown timed out");
6900                        timedout = true;
6901                        break;
6902                    }
6903                    try {
6904                        this.wait();
6905                    } catch (InterruptedException e) {
6906                    }
6907                }
6908            }
6909        }
6910
6911        mUsageStatsService.shutdown();
6912        mBatteryStatsService.shutdown();
6913
6914        return timedout;
6915    }
6916
6917    public final void activitySlept(IBinder token) {
6918        if (localLOGV) Slog.v(
6919            TAG, "Activity slept: token=" + token);
6920
6921        ActivityRecord r = null;
6922
6923        final long origId = Binder.clearCallingIdentity();
6924
6925        synchronized (this) {
6926            r = mMainStack.isInStackLocked(token);
6927            if (r != null) {
6928                mMainStack.activitySleptLocked(r);
6929            }
6930        }
6931
6932        Binder.restoreCallingIdentity(origId);
6933    }
6934
6935    private void comeOutOfSleepIfNeededLocked() {
6936        if (!mWentToSleep && !mLockScreenShown) {
6937            if (mSleeping) {
6938                mSleeping = false;
6939                mMainStack.awakeFromSleepingLocked();
6940                mMainStack.resumeTopActivityLocked(null);
6941            }
6942        }
6943    }
6944
6945    public void wakingUp() {
6946        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6947                != PackageManager.PERMISSION_GRANTED) {
6948            throw new SecurityException("Requires permission "
6949                    + android.Manifest.permission.DEVICE_POWER);
6950        }
6951
6952        synchronized(this) {
6953            mWentToSleep = false;
6954            updateEventDispatchingLocked();
6955            comeOutOfSleepIfNeededLocked();
6956        }
6957    }
6958
6959    private void updateEventDispatchingLocked() {
6960        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
6961    }
6962
6963    public void setLockScreenShown(boolean shown) {
6964        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6965                != PackageManager.PERMISSION_GRANTED) {
6966            throw new SecurityException("Requires permission "
6967                    + android.Manifest.permission.DEVICE_POWER);
6968        }
6969
6970        synchronized(this) {
6971            mLockScreenShown = shown;
6972            comeOutOfSleepIfNeededLocked();
6973        }
6974    }
6975
6976    public void stopAppSwitches() {
6977        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6978                != PackageManager.PERMISSION_GRANTED) {
6979            throw new SecurityException("Requires permission "
6980                    + android.Manifest.permission.STOP_APP_SWITCHES);
6981        }
6982
6983        synchronized(this) {
6984            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6985                    + APP_SWITCH_DELAY_TIME;
6986            mDidAppSwitch = false;
6987            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6988            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6989            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6990        }
6991    }
6992
6993    public void resumeAppSwitches() {
6994        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6995                != PackageManager.PERMISSION_GRANTED) {
6996            throw new SecurityException("Requires permission "
6997                    + android.Manifest.permission.STOP_APP_SWITCHES);
6998        }
6999
7000        synchronized(this) {
7001            // Note that we don't execute any pending app switches... we will
7002            // let those wait until either the timeout, or the next start
7003            // activity request.
7004            mAppSwitchesAllowedTime = 0;
7005        }
7006    }
7007
7008    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7009            String name) {
7010        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7011            return true;
7012        }
7013
7014        final int perm = checkComponentPermission(
7015                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7016                callingUid, -1, true);
7017        if (perm == PackageManager.PERMISSION_GRANTED) {
7018            return true;
7019        }
7020
7021        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7022        return false;
7023    }
7024
7025    public void setDebugApp(String packageName, boolean waitForDebugger,
7026            boolean persistent) {
7027        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7028                "setDebugApp()");
7029
7030        // Note that this is not really thread safe if there are multiple
7031        // callers into it at the same time, but that's not a situation we
7032        // care about.
7033        if (persistent) {
7034            final ContentResolver resolver = mContext.getContentResolver();
7035            Settings.System.putString(
7036                resolver, Settings.System.DEBUG_APP,
7037                packageName);
7038            Settings.System.putInt(
7039                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7040                waitForDebugger ? 1 : 0);
7041        }
7042
7043        synchronized (this) {
7044            if (!persistent) {
7045                mOrigDebugApp = mDebugApp;
7046                mOrigWaitForDebugger = mWaitForDebugger;
7047            }
7048            mDebugApp = packageName;
7049            mWaitForDebugger = waitForDebugger;
7050            mDebugTransient = !persistent;
7051            if (packageName != null) {
7052                final long origId = Binder.clearCallingIdentity();
7053                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
7054                Binder.restoreCallingIdentity(origId);
7055            }
7056        }
7057    }
7058
7059    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7060        synchronized (this) {
7061            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7062            if (!isDebuggable) {
7063                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7064                    throw new SecurityException("Process not debuggable: " + app.packageName);
7065                }
7066            }
7067
7068            mOpenGlTraceApp = processName;
7069        }
7070    }
7071
7072    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7073            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7074        synchronized (this) {
7075            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7076            if (!isDebuggable) {
7077                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7078                    throw new SecurityException("Process not debuggable: " + app.packageName);
7079                }
7080            }
7081            mProfileApp = processName;
7082            mProfileFile = profileFile;
7083            if (mProfileFd != null) {
7084                try {
7085                    mProfileFd.close();
7086                } catch (IOException e) {
7087                }
7088                mProfileFd = null;
7089            }
7090            mProfileFd = profileFd;
7091            mProfileType = 0;
7092            mAutoStopProfiler = autoStopProfiler;
7093        }
7094    }
7095
7096    public void setAlwaysFinish(boolean enabled) {
7097        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7098                "setAlwaysFinish()");
7099
7100        Settings.System.putInt(
7101                mContext.getContentResolver(),
7102                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7103
7104        synchronized (this) {
7105            mAlwaysFinishActivities = enabled;
7106        }
7107    }
7108
7109    public void setActivityController(IActivityController controller) {
7110        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7111                "setActivityController()");
7112        synchronized (this) {
7113            mController = controller;
7114        }
7115    }
7116
7117    public boolean isUserAMonkey() {
7118        // For now the fact that there is a controller implies
7119        // we have a monkey.
7120        synchronized (this) {
7121            return mController != null;
7122        }
7123    }
7124
7125    public void registerProcessObserver(IProcessObserver observer) {
7126        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7127                "registerProcessObserver()");
7128        synchronized (this) {
7129            mProcessObservers.register(observer);
7130        }
7131    }
7132
7133    public void unregisterProcessObserver(IProcessObserver observer) {
7134        synchronized (this) {
7135            mProcessObservers.unregister(observer);
7136        }
7137    }
7138
7139    public void setImmersive(IBinder token, boolean immersive) {
7140        synchronized(this) {
7141            ActivityRecord r = mMainStack.isInStackLocked(token);
7142            if (r == null) {
7143                throw new IllegalArgumentException();
7144            }
7145            r.immersive = immersive;
7146        }
7147    }
7148
7149    public boolean isImmersive(IBinder token) {
7150        synchronized (this) {
7151            ActivityRecord r = mMainStack.isInStackLocked(token);
7152            if (r == null) {
7153                throw new IllegalArgumentException();
7154            }
7155            return r.immersive;
7156        }
7157    }
7158
7159    public boolean isTopActivityImmersive() {
7160        enforceNotIsolatedCaller("startActivity");
7161        synchronized (this) {
7162            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7163            return (r != null) ? r.immersive : false;
7164        }
7165    }
7166
7167    public final void enterSafeMode() {
7168        synchronized(this) {
7169            // It only makes sense to do this before the system is ready
7170            // and started launching other packages.
7171            if (!mSystemReady) {
7172                try {
7173                    AppGlobals.getPackageManager().enterSafeMode();
7174                } catch (RemoteException e) {
7175                }
7176            }
7177        }
7178    }
7179
7180    public final void showSafeModeOverlay() {
7181        View v = LayoutInflater.from(mContext).inflate(
7182                com.android.internal.R.layout.safe_mode, null);
7183        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7184        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7185        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7186        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7187        lp.gravity = Gravity.BOTTOM | Gravity.START;
7188        lp.format = v.getBackground().getOpacity();
7189        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7190                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7191        ((WindowManager)mContext.getSystemService(
7192                Context.WINDOW_SERVICE)).addView(v, lp);
7193    }
7194
7195    public void noteWakeupAlarm(IIntentSender sender) {
7196        if (!(sender instanceof PendingIntentRecord)) {
7197            return;
7198        }
7199        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7200        synchronized (stats) {
7201            if (mBatteryStatsService.isOnBattery()) {
7202                mBatteryStatsService.enforceCallingPermission();
7203                PendingIntentRecord rec = (PendingIntentRecord)sender;
7204                int MY_UID = Binder.getCallingUid();
7205                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7206                BatteryStatsImpl.Uid.Pkg pkg =
7207                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7208                pkg.incWakeupsLocked();
7209            }
7210        }
7211    }
7212
7213    public boolean killPids(int[] pids, String pReason, boolean secure) {
7214        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7215            throw new SecurityException("killPids only available to the system");
7216        }
7217        String reason = (pReason == null) ? "Unknown" : pReason;
7218        // XXX Note: don't acquire main activity lock here, because the window
7219        // manager calls in with its locks held.
7220
7221        boolean killed = false;
7222        synchronized (mPidsSelfLocked) {
7223            int[] types = new int[pids.length];
7224            int worstType = 0;
7225            for (int i=0; i<pids.length; i++) {
7226                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7227                if (proc != null) {
7228                    int type = proc.setAdj;
7229                    types[i] = type;
7230                    if (type > worstType) {
7231                        worstType = type;
7232                    }
7233                }
7234            }
7235
7236            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7237            // then constrain it so we will kill all hidden procs.
7238            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7239                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7240                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7241            }
7242
7243            // If this is not a secure call, don't let it kill processes that
7244            // are important.
7245            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7246                worstType = ProcessList.SERVICE_ADJ;
7247            }
7248
7249            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7250            for (int i=0; i<pids.length; i++) {
7251                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7252                if (proc == null) {
7253                    continue;
7254                }
7255                int adj = proc.setAdj;
7256                if (adj >= worstType && !proc.killedBackground) {
7257                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7258                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7259                            proc.processName, adj, reason);
7260                    killed = true;
7261                    proc.killedBackground = true;
7262                    Process.killProcessQuiet(pids[i]);
7263                }
7264            }
7265        }
7266        return killed;
7267    }
7268
7269    @Override
7270    public boolean killProcessesBelowForeground(String reason) {
7271        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7272            throw new SecurityException("killProcessesBelowForeground() only available to system");
7273        }
7274
7275        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7276    }
7277
7278    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7279        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7280            throw new SecurityException("killProcessesBelowAdj() only available to system");
7281        }
7282
7283        boolean killed = false;
7284        synchronized (mPidsSelfLocked) {
7285            final int size = mPidsSelfLocked.size();
7286            for (int i = 0; i < size; i++) {
7287                final int pid = mPidsSelfLocked.keyAt(i);
7288                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7289                if (proc == null) continue;
7290
7291                final int adj = proc.setAdj;
7292                if (adj > belowAdj && !proc.killedBackground) {
7293                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7294                    EventLog.writeEvent(
7295                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7296                    killed = true;
7297                    proc.killedBackground = true;
7298                    Process.killProcessQuiet(pid);
7299                }
7300            }
7301        }
7302        return killed;
7303    }
7304
7305    public final void startRunning(String pkg, String cls, String action,
7306            String data) {
7307        synchronized(this) {
7308            if (mStartRunning) {
7309                return;
7310            }
7311            mStartRunning = true;
7312            mTopComponent = pkg != null && cls != null
7313                    ? new ComponentName(pkg, cls) : null;
7314            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7315            mTopData = data;
7316            if (!mSystemReady) {
7317                return;
7318            }
7319        }
7320
7321        systemReady(null);
7322    }
7323
7324    private void retrieveSettings() {
7325        final ContentResolver resolver = mContext.getContentResolver();
7326        String debugApp = Settings.System.getString(
7327            resolver, Settings.System.DEBUG_APP);
7328        boolean waitForDebugger = Settings.System.getInt(
7329            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7330        boolean alwaysFinishActivities = Settings.System.getInt(
7331            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7332
7333        Configuration configuration = new Configuration();
7334        Settings.System.getConfiguration(resolver, configuration);
7335
7336        synchronized (this) {
7337            mDebugApp = mOrigDebugApp = debugApp;
7338            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7339            mAlwaysFinishActivities = alwaysFinishActivities;
7340            // This happens before any activities are started, so we can
7341            // change mConfiguration in-place.
7342            updateConfigurationLocked(configuration, null, false, true);
7343            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7344        }
7345    }
7346
7347    public boolean testIsSystemReady() {
7348        // no need to synchronize(this) just to read & return the value
7349        return mSystemReady;
7350    }
7351
7352    private static File getCalledPreBootReceiversFile() {
7353        File dataDir = Environment.getDataDirectory();
7354        File systemDir = new File(dataDir, "system");
7355        File fname = new File(systemDir, "called_pre_boots.dat");
7356        return fname;
7357    }
7358
7359    static final int LAST_DONE_VERSION = 10000;
7360
7361    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7362        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7363        File file = getCalledPreBootReceiversFile();
7364        FileInputStream fis = null;
7365        try {
7366            fis = new FileInputStream(file);
7367            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7368            int fvers = dis.readInt();
7369            if (fvers == LAST_DONE_VERSION) {
7370                String vers = dis.readUTF();
7371                String codename = dis.readUTF();
7372                String build = dis.readUTF();
7373                if (android.os.Build.VERSION.RELEASE.equals(vers)
7374                        && android.os.Build.VERSION.CODENAME.equals(codename)
7375                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7376                    int num = dis.readInt();
7377                    while (num > 0) {
7378                        num--;
7379                        String pkg = dis.readUTF();
7380                        String cls = dis.readUTF();
7381                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7382                    }
7383                }
7384            }
7385        } catch (FileNotFoundException e) {
7386        } catch (IOException e) {
7387            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7388        } finally {
7389            if (fis != null) {
7390                try {
7391                    fis.close();
7392                } catch (IOException e) {
7393                }
7394            }
7395        }
7396        return lastDoneReceivers;
7397    }
7398
7399    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7400        File file = getCalledPreBootReceiversFile();
7401        FileOutputStream fos = null;
7402        DataOutputStream dos = null;
7403        try {
7404            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7405            fos = new FileOutputStream(file);
7406            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7407            dos.writeInt(LAST_DONE_VERSION);
7408            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7409            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7410            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7411            dos.writeInt(list.size());
7412            for (int i=0; i<list.size(); i++) {
7413                dos.writeUTF(list.get(i).getPackageName());
7414                dos.writeUTF(list.get(i).getClassName());
7415            }
7416        } catch (IOException e) {
7417            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7418            file.delete();
7419        } finally {
7420            FileUtils.sync(fos);
7421            if (dos != null) {
7422                try {
7423                    dos.close();
7424                } catch (IOException e) {
7425                    // TODO Auto-generated catch block
7426                    e.printStackTrace();
7427                }
7428            }
7429        }
7430    }
7431
7432    public void systemReady(final Runnable goingCallback) {
7433        synchronized(this) {
7434            if (mSystemReady) {
7435                if (goingCallback != null) goingCallback.run();
7436                return;
7437            }
7438
7439            // Check to see if there are any update receivers to run.
7440            if (!mDidUpdate) {
7441                if (mWaitingUpdate) {
7442                    return;
7443                }
7444                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7445                List<ResolveInfo> ris = null;
7446                try {
7447                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7448                            intent, null, 0, 0);
7449                } catch (RemoteException e) {
7450                }
7451                if (ris != null) {
7452                    for (int i=ris.size()-1; i>=0; i--) {
7453                        if ((ris.get(i).activityInfo.applicationInfo.flags
7454                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7455                            ris.remove(i);
7456                        }
7457                    }
7458                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7459
7460                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7461
7462                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7463                    for (int i=0; i<ris.size(); i++) {
7464                        ActivityInfo ai = ris.get(i).activityInfo;
7465                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7466                        if (lastDoneReceivers.contains(comp)) {
7467                            ris.remove(i);
7468                            i--;
7469                        }
7470                    }
7471
7472                    for (int i=0; i<ris.size(); i++) {
7473                        ActivityInfo ai = ris.get(i).activityInfo;
7474                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7475                        doneReceivers.add(comp);
7476                        intent.setComponent(comp);
7477                        IIntentReceiver finisher = null;
7478                        if (i == ris.size()-1) {
7479                            finisher = new IIntentReceiver.Stub() {
7480                                public void performReceive(Intent intent, int resultCode,
7481                                        String data, Bundle extras, boolean ordered,
7482                                        boolean sticky) {
7483                                    // The raw IIntentReceiver interface is called
7484                                    // with the AM lock held, so redispatch to
7485                                    // execute our code without the lock.
7486                                    mHandler.post(new Runnable() {
7487                                        public void run() {
7488                                            synchronized (ActivityManagerService.this) {
7489                                                mDidUpdate = true;
7490                                            }
7491                                            writeLastDonePreBootReceivers(doneReceivers);
7492                                            showBootMessage(mContext.getText(
7493                                                    R.string.android_upgrading_complete),
7494                                                    false);
7495                                            systemReady(goingCallback);
7496                                        }
7497                                    });
7498                                }
7499                            };
7500                        }
7501                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7502                        /* TODO: Send this to all users */
7503                        broadcastIntentLocked(null, null, intent, null, finisher,
7504                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7505                                0 /* UserId zero */);
7506                        if (finisher != null) {
7507                            mWaitingUpdate = true;
7508                        }
7509                    }
7510                }
7511                if (mWaitingUpdate) {
7512                    return;
7513                }
7514                mDidUpdate = true;
7515            }
7516
7517            mSystemReady = true;
7518            if (!mStartRunning) {
7519                return;
7520            }
7521        }
7522
7523        ArrayList<ProcessRecord> procsToKill = null;
7524        synchronized(mPidsSelfLocked) {
7525            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7526                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7527                if (!isAllowedWhileBooting(proc.info)){
7528                    if (procsToKill == null) {
7529                        procsToKill = new ArrayList<ProcessRecord>();
7530                    }
7531                    procsToKill.add(proc);
7532                }
7533            }
7534        }
7535
7536        synchronized(this) {
7537            if (procsToKill != null) {
7538                for (int i=procsToKill.size()-1; i>=0; i--) {
7539                    ProcessRecord proc = procsToKill.get(i);
7540                    Slog.i(TAG, "Removing system update proc: " + proc);
7541                    removeProcessLocked(proc, true, false, "system update done");
7542                }
7543            }
7544
7545            // Now that we have cleaned up any update processes, we
7546            // are ready to start launching real processes and know that
7547            // we won't trample on them any more.
7548            mProcessesReady = true;
7549        }
7550
7551        Slog.i(TAG, "System now ready");
7552        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7553            SystemClock.uptimeMillis());
7554
7555        synchronized(this) {
7556            // Make sure we have no pre-ready processes sitting around.
7557
7558            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7559                ResolveInfo ri = mContext.getPackageManager()
7560                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7561                                STOCK_PM_FLAGS);
7562                CharSequence errorMsg = null;
7563                if (ri != null) {
7564                    ActivityInfo ai = ri.activityInfo;
7565                    ApplicationInfo app = ai.applicationInfo;
7566                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7567                        mTopAction = Intent.ACTION_FACTORY_TEST;
7568                        mTopData = null;
7569                        mTopComponent = new ComponentName(app.packageName,
7570                                ai.name);
7571                    } else {
7572                        errorMsg = mContext.getResources().getText(
7573                                com.android.internal.R.string.factorytest_not_system);
7574                    }
7575                } else {
7576                    errorMsg = mContext.getResources().getText(
7577                            com.android.internal.R.string.factorytest_no_action);
7578                }
7579                if (errorMsg != null) {
7580                    mTopAction = null;
7581                    mTopData = null;
7582                    mTopComponent = null;
7583                    Message msg = Message.obtain();
7584                    msg.what = SHOW_FACTORY_ERROR_MSG;
7585                    msg.getData().putCharSequence("msg", errorMsg);
7586                    mHandler.sendMessage(msg);
7587                }
7588            }
7589        }
7590
7591        retrieveSettings();
7592
7593        if (goingCallback != null) goingCallback.run();
7594
7595        synchronized (this) {
7596            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7597                try {
7598                    List apps = AppGlobals.getPackageManager().
7599                        getPersistentApplications(STOCK_PM_FLAGS);
7600                    if (apps != null) {
7601                        int N = apps.size();
7602                        int i;
7603                        for (i=0; i<N; i++) {
7604                            ApplicationInfo info
7605                                = (ApplicationInfo)apps.get(i);
7606                            if (info != null &&
7607                                    !info.packageName.equals("android")) {
7608                                addAppLocked(info, false);
7609                            }
7610                        }
7611                    }
7612                } catch (RemoteException ex) {
7613                    // pm is in same process, this will never happen.
7614                }
7615            }
7616
7617            // Start up initial activity.
7618            mBooting = true;
7619
7620            try {
7621                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7622                    Message msg = Message.obtain();
7623                    msg.what = SHOW_UID_ERROR_MSG;
7624                    mHandler.sendMessage(msg);
7625                }
7626            } catch (RemoteException e) {
7627            }
7628
7629            mMainStack.resumeTopActivityLocked(null);
7630        }
7631    }
7632
7633    private boolean makeAppCrashingLocked(ProcessRecord app,
7634            String shortMsg, String longMsg, String stackTrace) {
7635        app.crashing = true;
7636        app.crashingReport = generateProcessError(app,
7637                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7638        startAppProblemLocked(app);
7639        app.stopFreezingAllLocked();
7640        return handleAppCrashLocked(app);
7641    }
7642
7643    private void makeAppNotRespondingLocked(ProcessRecord app,
7644            String activity, String shortMsg, String longMsg) {
7645        app.notResponding = true;
7646        app.notRespondingReport = generateProcessError(app,
7647                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7648                activity, shortMsg, longMsg, null);
7649        startAppProblemLocked(app);
7650        app.stopFreezingAllLocked();
7651    }
7652
7653    /**
7654     * Generate a process error record, suitable for attachment to a ProcessRecord.
7655     *
7656     * @param app The ProcessRecord in which the error occurred.
7657     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7658     *                      ActivityManager.AppErrorStateInfo
7659     * @param activity The activity associated with the crash, if known.
7660     * @param shortMsg Short message describing the crash.
7661     * @param longMsg Long message describing the crash.
7662     * @param stackTrace Full crash stack trace, may be null.
7663     *
7664     * @return Returns a fully-formed AppErrorStateInfo record.
7665     */
7666    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7667            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7668        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7669
7670        report.condition = condition;
7671        report.processName = app.processName;
7672        report.pid = app.pid;
7673        report.uid = app.info.uid;
7674        report.tag = activity;
7675        report.shortMsg = shortMsg;
7676        report.longMsg = longMsg;
7677        report.stackTrace = stackTrace;
7678
7679        return report;
7680    }
7681
7682    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7683        synchronized (this) {
7684            app.crashing = false;
7685            app.crashingReport = null;
7686            app.notResponding = false;
7687            app.notRespondingReport = null;
7688            if (app.anrDialog == fromDialog) {
7689                app.anrDialog = null;
7690            }
7691            if (app.waitDialog == fromDialog) {
7692                app.waitDialog = null;
7693            }
7694            if (app.pid > 0 && app.pid != MY_PID) {
7695                handleAppCrashLocked(app);
7696                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7697                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7698                        app.processName, app.setAdj, "user's request after error");
7699                Process.killProcessQuiet(app.pid);
7700            }
7701        }
7702    }
7703
7704    private boolean handleAppCrashLocked(ProcessRecord app) {
7705        if (mHeadless) {
7706            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7707            return false;
7708        }
7709        long now = SystemClock.uptimeMillis();
7710
7711        Long crashTime;
7712        if (!app.isolated) {
7713            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7714        } else {
7715            crashTime = null;
7716        }
7717        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7718            // This process loses!
7719            Slog.w(TAG, "Process " + app.info.processName
7720                    + " has crashed too many times: killing!");
7721            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7722                    app.info.processName, app.uid);
7723            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7724                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7725                if (r.app == app) {
7726                    Slog.w(TAG, "  Force finishing activity "
7727                        + r.intent.getComponent().flattenToShortString());
7728                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7729                }
7730            }
7731            if (!app.persistent) {
7732                // We don't want to start this process again until the user
7733                // explicitly does so...  but for persistent process, we really
7734                // need to keep it running.  If a persistent process is actually
7735                // repeatedly crashing, then badness for everyone.
7736                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7737                        app.info.processName);
7738                if (!app.isolated) {
7739                    // XXX We don't have a way to mark isolated processes
7740                    // as bad, since they don't have a peristent identity.
7741                    mBadProcesses.put(app.info.processName, app.uid, now);
7742                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7743                }
7744                app.bad = true;
7745                app.removed = true;
7746                // Don't let services in this process be restarted and potentially
7747                // annoy the user repeatedly.  Unless it is persistent, since those
7748                // processes run critical code.
7749                removeProcessLocked(app, false, false, "crash");
7750                mMainStack.resumeTopActivityLocked(null);
7751                return false;
7752            }
7753            mMainStack.resumeTopActivityLocked(null);
7754        } else {
7755            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7756            if (r != null && r.app == app) {
7757                // If the top running activity is from this crashing
7758                // process, then terminate it to avoid getting in a loop.
7759                Slog.w(TAG, "  Force finishing activity "
7760                        + r.intent.getComponent().flattenToShortString());
7761                int index = mMainStack.indexOfActivityLocked(r);
7762                r.stack.finishActivityLocked(r, index,
7763                        Activity.RESULT_CANCELED, null, "crashed");
7764                // Also terminate any activities below it that aren't yet
7765                // stopped, to avoid a situation where one will get
7766                // re-start our crashing activity once it gets resumed again.
7767                index--;
7768                if (index >= 0) {
7769                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7770                    if (r.state == ActivityState.RESUMED
7771                            || r.state == ActivityState.PAUSING
7772                            || r.state == ActivityState.PAUSED) {
7773                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7774                            Slog.w(TAG, "  Force finishing activity "
7775                                    + r.intent.getComponent().flattenToShortString());
7776                            r.stack.finishActivityLocked(r, index,
7777                                    Activity.RESULT_CANCELED, null, "crashed");
7778                        }
7779                    }
7780                }
7781            }
7782        }
7783
7784        // Bump up the crash count of any services currently running in the proc.
7785        if (app.services.size() != 0) {
7786            // Any services running in the application need to be placed
7787            // back in the pending list.
7788            Iterator<ServiceRecord> it = app.services.iterator();
7789            while (it.hasNext()) {
7790                ServiceRecord sr = it.next();
7791                sr.crashCount++;
7792            }
7793        }
7794
7795        // If the crashing process is what we consider to be the "home process" and it has been
7796        // replaced by a third-party app, clear the package preferred activities from packages
7797        // with a home activity running in the process to prevent a repeatedly crashing app
7798        // from blocking the user to manually clear the list.
7799        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7800                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7801            Iterator it = mHomeProcess.activities.iterator();
7802            while (it.hasNext()) {
7803                ActivityRecord r = (ActivityRecord)it.next();
7804                if (r.isHomeActivity) {
7805                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7806                    try {
7807                        ActivityThread.getPackageManager()
7808                                .clearPackagePreferredActivities(r.packageName);
7809                    } catch (RemoteException c) {
7810                        // pm is in same process, this will never happen.
7811                    }
7812                }
7813            }
7814        }
7815
7816        if (!app.isolated) {
7817            // XXX Can't keep track of crash times for isolated processes,
7818            // because they don't have a perisistent identity.
7819            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7820        }
7821
7822        return true;
7823    }
7824
7825    void startAppProblemLocked(ProcessRecord app) {
7826        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7827                mContext, app.info.packageName, app.info.flags);
7828        skipCurrentReceiverLocked(app);
7829    }
7830
7831    void skipCurrentReceiverLocked(ProcessRecord app) {
7832        for (BroadcastQueue queue : mBroadcastQueues) {
7833            queue.skipCurrentReceiverLocked(app);
7834        }
7835    }
7836
7837    /**
7838     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7839     * The application process will exit immediately after this call returns.
7840     * @param app object of the crashing app, null for the system server
7841     * @param crashInfo describing the exception
7842     */
7843    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7844        ProcessRecord r = findAppProcess(app, "Crash");
7845        final String processName = app == null ? "system_server"
7846                : (r == null ? "unknown" : r.processName);
7847
7848        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7849                processName,
7850                r == null ? -1 : r.info.flags,
7851                crashInfo.exceptionClassName,
7852                crashInfo.exceptionMessage,
7853                crashInfo.throwFileName,
7854                crashInfo.throwLineNumber);
7855
7856        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7857
7858        crashApplication(r, crashInfo);
7859    }
7860
7861    public void handleApplicationStrictModeViolation(
7862            IBinder app,
7863            int violationMask,
7864            StrictMode.ViolationInfo info) {
7865        ProcessRecord r = findAppProcess(app, "StrictMode");
7866        if (r == null) {
7867            return;
7868        }
7869
7870        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7871            Integer stackFingerprint = info.hashCode();
7872            boolean logIt = true;
7873            synchronized (mAlreadyLoggedViolatedStacks) {
7874                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7875                    logIt = false;
7876                    // TODO: sub-sample into EventLog for these, with
7877                    // the info.durationMillis?  Then we'd get
7878                    // the relative pain numbers, without logging all
7879                    // the stack traces repeatedly.  We'd want to do
7880                    // likewise in the client code, which also does
7881                    // dup suppression, before the Binder call.
7882                } else {
7883                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7884                        mAlreadyLoggedViolatedStacks.clear();
7885                    }
7886                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7887                }
7888            }
7889            if (logIt) {
7890                logStrictModeViolationToDropBox(r, info);
7891            }
7892        }
7893
7894        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7895            AppErrorResult result = new AppErrorResult();
7896            synchronized (this) {
7897                final long origId = Binder.clearCallingIdentity();
7898
7899                Message msg = Message.obtain();
7900                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7901                HashMap<String, Object> data = new HashMap<String, Object>();
7902                data.put("result", result);
7903                data.put("app", r);
7904                data.put("violationMask", violationMask);
7905                data.put("info", info);
7906                msg.obj = data;
7907                mHandler.sendMessage(msg);
7908
7909                Binder.restoreCallingIdentity(origId);
7910            }
7911            int res = result.get();
7912            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7913        }
7914    }
7915
7916    // Depending on the policy in effect, there could be a bunch of
7917    // these in quick succession so we try to batch these together to
7918    // minimize disk writes, number of dropbox entries, and maximize
7919    // compression, by having more fewer, larger records.
7920    private void logStrictModeViolationToDropBox(
7921            ProcessRecord process,
7922            StrictMode.ViolationInfo info) {
7923        if (info == null) {
7924            return;
7925        }
7926        final boolean isSystemApp = process == null ||
7927                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7928                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7929        final String processName = process == null ? "unknown" : process.processName;
7930        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7931        final DropBoxManager dbox = (DropBoxManager)
7932                mContext.getSystemService(Context.DROPBOX_SERVICE);
7933
7934        // Exit early if the dropbox isn't configured to accept this report type.
7935        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7936
7937        boolean bufferWasEmpty;
7938        boolean needsFlush;
7939        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7940        synchronized (sb) {
7941            bufferWasEmpty = sb.length() == 0;
7942            appendDropBoxProcessHeaders(process, processName, sb);
7943            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7944            sb.append("System-App: ").append(isSystemApp).append("\n");
7945            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7946            if (info.violationNumThisLoop != 0) {
7947                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7948            }
7949            if (info.numAnimationsRunning != 0) {
7950                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7951            }
7952            if (info.broadcastIntentAction != null) {
7953                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7954            }
7955            if (info.durationMillis != -1) {
7956                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
7957            }
7958            if (info.numInstances != -1) {
7959                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7960            }
7961            if (info.tags != null) {
7962                for (String tag : info.tags) {
7963                    sb.append("Span-Tag: ").append(tag).append("\n");
7964                }
7965            }
7966            sb.append("\n");
7967            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7968                sb.append(info.crashInfo.stackTrace);
7969            }
7970            sb.append("\n");
7971
7972            // Only buffer up to ~64k.  Various logging bits truncate
7973            // things at 128k.
7974            needsFlush = (sb.length() > 64 * 1024);
7975        }
7976
7977        // Flush immediately if the buffer's grown too large, or this
7978        // is a non-system app.  Non-system apps are isolated with a
7979        // different tag & policy and not batched.
7980        //
7981        // Batching is useful during internal testing with
7982        // StrictMode settings turned up high.  Without batching,
7983        // thousands of separate files could be created on boot.
7984        if (!isSystemApp || needsFlush) {
7985            new Thread("Error dump: " + dropboxTag) {
7986                @Override
7987                public void run() {
7988                    String report;
7989                    synchronized (sb) {
7990                        report = sb.toString();
7991                        sb.delete(0, sb.length());
7992                        sb.trimToSize();
7993                    }
7994                    if (report.length() != 0) {
7995                        dbox.addText(dropboxTag, report);
7996                    }
7997                }
7998            }.start();
7999            return;
8000        }
8001
8002        // System app batching:
8003        if (!bufferWasEmpty) {
8004            // An existing dropbox-writing thread is outstanding, so
8005            // we don't need to start it up.  The existing thread will
8006            // catch the buffer appends we just did.
8007            return;
8008        }
8009
8010        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8011        // (After this point, we shouldn't access AMS internal data structures.)
8012        new Thread("Error dump: " + dropboxTag) {
8013            @Override
8014            public void run() {
8015                // 5 second sleep to let stacks arrive and be batched together
8016                try {
8017                    Thread.sleep(5000);  // 5 seconds
8018                } catch (InterruptedException e) {}
8019
8020                String errorReport;
8021                synchronized (mStrictModeBuffer) {
8022                    errorReport = mStrictModeBuffer.toString();
8023                    if (errorReport.length() == 0) {
8024                        return;
8025                    }
8026                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8027                    mStrictModeBuffer.trimToSize();
8028                }
8029                dbox.addText(dropboxTag, errorReport);
8030            }
8031        }.start();
8032    }
8033
8034    /**
8035     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8036     * @param app object of the crashing app, null for the system server
8037     * @param tag reported by the caller
8038     * @param crashInfo describing the context of the error
8039     * @return true if the process should exit immediately (WTF is fatal)
8040     */
8041    public boolean handleApplicationWtf(IBinder app, String tag,
8042            ApplicationErrorReport.CrashInfo crashInfo) {
8043        ProcessRecord r = findAppProcess(app, "WTF");
8044        final String processName = app == null ? "system_server"
8045                : (r == null ? "unknown" : r.processName);
8046
8047        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8048                processName,
8049                r == null ? -1 : r.info.flags,
8050                tag, crashInfo.exceptionMessage);
8051
8052        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8053
8054        if (r != null && r.pid != Process.myPid() &&
8055                Settings.Secure.getInt(mContext.getContentResolver(),
8056                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8057            crashApplication(r, crashInfo);
8058            return true;
8059        } else {
8060            return false;
8061        }
8062    }
8063
8064    /**
8065     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8066     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8067     */
8068    private ProcessRecord findAppProcess(IBinder app, String reason) {
8069        if (app == null) {
8070            return null;
8071        }
8072
8073        synchronized (this) {
8074            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8075                final int NA = apps.size();
8076                for (int ia=0; ia<NA; ia++) {
8077                    ProcessRecord p = apps.valueAt(ia);
8078                    if (p.thread != null && p.thread.asBinder() == app) {
8079                        return p;
8080                    }
8081                }
8082            }
8083
8084            Slog.w(TAG, "Can't find mystery application for " + reason
8085                    + " from pid=" + Binder.getCallingPid()
8086                    + " uid=" + Binder.getCallingUid() + ": " + app);
8087            return null;
8088        }
8089    }
8090
8091    /**
8092     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8093     * to append various headers to the dropbox log text.
8094     */
8095    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8096            StringBuilder sb) {
8097        // Watchdog thread ends up invoking this function (with
8098        // a null ProcessRecord) to add the stack file to dropbox.
8099        // Do not acquire a lock on this (am) in such cases, as it
8100        // could cause a potential deadlock, if and when watchdog
8101        // is invoked due to unavailability of lock on am and it
8102        // would prevent watchdog from killing system_server.
8103        if (process == null) {
8104            sb.append("Process: ").append(processName).append("\n");
8105            return;
8106        }
8107        // Note: ProcessRecord 'process' is guarded by the service
8108        // instance.  (notably process.pkgList, which could otherwise change
8109        // concurrently during execution of this method)
8110        synchronized (this) {
8111            sb.append("Process: ").append(processName).append("\n");
8112            int flags = process.info.flags;
8113            IPackageManager pm = AppGlobals.getPackageManager();
8114            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8115            for (String pkg : process.pkgList) {
8116                sb.append("Package: ").append(pkg);
8117                try {
8118                    PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
8119                    if (pi != null) {
8120                        sb.append(" v").append(pi.versionCode);
8121                        if (pi.versionName != null) {
8122                            sb.append(" (").append(pi.versionName).append(")");
8123                        }
8124                    }
8125                } catch (RemoteException e) {
8126                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8127                }
8128                sb.append("\n");
8129            }
8130        }
8131    }
8132
8133    private static String processClass(ProcessRecord process) {
8134        if (process == null || process.pid == MY_PID) {
8135            return "system_server";
8136        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8137            return "system_app";
8138        } else {
8139            return "data_app";
8140        }
8141    }
8142
8143    /**
8144     * Write a description of an error (crash, WTF, ANR) to the drop box.
8145     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8146     * @param process which caused the error, null means the system server
8147     * @param activity which triggered the error, null if unknown
8148     * @param parent activity related to the error, null if unknown
8149     * @param subject line related to the error, null if absent
8150     * @param report in long form describing the error, null if absent
8151     * @param logFile to include in the report, null if none
8152     * @param crashInfo giving an application stack trace, null if absent
8153     */
8154    public void addErrorToDropBox(String eventType,
8155            ProcessRecord process, String processName, ActivityRecord activity,
8156            ActivityRecord parent, String subject,
8157            final String report, final File logFile,
8158            final ApplicationErrorReport.CrashInfo crashInfo) {
8159        // NOTE -- this must never acquire the ActivityManagerService lock,
8160        // otherwise the watchdog may be prevented from resetting the system.
8161
8162        final String dropboxTag = processClass(process) + "_" + eventType;
8163        final DropBoxManager dbox = (DropBoxManager)
8164                mContext.getSystemService(Context.DROPBOX_SERVICE);
8165
8166        // Exit early if the dropbox isn't configured to accept this report type.
8167        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8168
8169        final StringBuilder sb = new StringBuilder(1024);
8170        appendDropBoxProcessHeaders(process, processName, sb);
8171        if (activity != null) {
8172            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8173        }
8174        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8175            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8176        }
8177        if (parent != null && parent != activity) {
8178            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8179        }
8180        if (subject != null) {
8181            sb.append("Subject: ").append(subject).append("\n");
8182        }
8183        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8184        if (Debug.isDebuggerConnected()) {
8185            sb.append("Debugger: Connected\n");
8186        }
8187        sb.append("\n");
8188
8189        // Do the rest in a worker thread to avoid blocking the caller on I/O
8190        // (After this point, we shouldn't access AMS internal data structures.)
8191        Thread worker = new Thread("Error dump: " + dropboxTag) {
8192            @Override
8193            public void run() {
8194                if (report != null) {
8195                    sb.append(report);
8196                }
8197                if (logFile != null) {
8198                    try {
8199                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8200                    } catch (IOException e) {
8201                        Slog.e(TAG, "Error reading " + logFile, e);
8202                    }
8203                }
8204                if (crashInfo != null && crashInfo.stackTrace != null) {
8205                    sb.append(crashInfo.stackTrace);
8206                }
8207
8208                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8209                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8210                if (lines > 0) {
8211                    sb.append("\n");
8212
8213                    // Merge several logcat streams, and take the last N lines
8214                    InputStreamReader input = null;
8215                    try {
8216                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8217                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8218                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8219
8220                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8221                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8222                        input = new InputStreamReader(logcat.getInputStream());
8223
8224                        int num;
8225                        char[] buf = new char[8192];
8226                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8227                    } catch (IOException e) {
8228                        Slog.e(TAG, "Error running logcat", e);
8229                    } finally {
8230                        if (input != null) try { input.close(); } catch (IOException e) {}
8231                    }
8232                }
8233
8234                dbox.addText(dropboxTag, sb.toString());
8235            }
8236        };
8237
8238        if (process == null) {
8239            // If process is null, we are being called from some internal code
8240            // and may be about to die -- run this synchronously.
8241            worker.run();
8242        } else {
8243            worker.start();
8244        }
8245    }
8246
8247    /**
8248     * Bring up the "unexpected error" dialog box for a crashing app.
8249     * Deal with edge cases (intercepts from instrumented applications,
8250     * ActivityController, error intent receivers, that sort of thing).
8251     * @param r the application crashing
8252     * @param crashInfo describing the failure
8253     */
8254    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8255        long timeMillis = System.currentTimeMillis();
8256        String shortMsg = crashInfo.exceptionClassName;
8257        String longMsg = crashInfo.exceptionMessage;
8258        String stackTrace = crashInfo.stackTrace;
8259        if (shortMsg != null && longMsg != null) {
8260            longMsg = shortMsg + ": " + longMsg;
8261        } else if (shortMsg != null) {
8262            longMsg = shortMsg;
8263        }
8264
8265        AppErrorResult result = new AppErrorResult();
8266        synchronized (this) {
8267            if (mController != null) {
8268                try {
8269                    String name = r != null ? r.processName : null;
8270                    int pid = r != null ? r.pid : Binder.getCallingPid();
8271                    if (!mController.appCrashed(name, pid,
8272                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8273                        Slog.w(TAG, "Force-killing crashed app " + name
8274                                + " at watcher's request");
8275                        Process.killProcess(pid);
8276                        return;
8277                    }
8278                } catch (RemoteException e) {
8279                    mController = null;
8280                }
8281            }
8282
8283            final long origId = Binder.clearCallingIdentity();
8284
8285            // If this process is running instrumentation, finish it.
8286            if (r != null && r.instrumentationClass != null) {
8287                Slog.w(TAG, "Error in app " + r.processName
8288                      + " running instrumentation " + r.instrumentationClass + ":");
8289                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8290                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8291                Bundle info = new Bundle();
8292                info.putString("shortMsg", shortMsg);
8293                info.putString("longMsg", longMsg);
8294                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8295                Binder.restoreCallingIdentity(origId);
8296                return;
8297            }
8298
8299            // If we can't identify the process or it's already exceeded its crash quota,
8300            // quit right away without showing a crash dialog.
8301            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8302                Binder.restoreCallingIdentity(origId);
8303                return;
8304            }
8305
8306            Message msg = Message.obtain();
8307            msg.what = SHOW_ERROR_MSG;
8308            HashMap data = new HashMap();
8309            data.put("result", result);
8310            data.put("app", r);
8311            msg.obj = data;
8312            mHandler.sendMessage(msg);
8313
8314            Binder.restoreCallingIdentity(origId);
8315        }
8316
8317        int res = result.get();
8318
8319        Intent appErrorIntent = null;
8320        synchronized (this) {
8321            if (r != null && !r.isolated) {
8322                // XXX Can't keep track of crash time for isolated processes,
8323                // since they don't have a persistent identity.
8324                mProcessCrashTimes.put(r.info.processName, r.uid,
8325                        SystemClock.uptimeMillis());
8326            }
8327            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8328                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8329            }
8330        }
8331
8332        if (appErrorIntent != null) {
8333            try {
8334                mContext.startActivity(appErrorIntent);
8335            } catch (ActivityNotFoundException e) {
8336                Slog.w(TAG, "bug report receiver dissappeared", e);
8337            }
8338        }
8339    }
8340
8341    Intent createAppErrorIntentLocked(ProcessRecord r,
8342            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8343        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8344        if (report == null) {
8345            return null;
8346        }
8347        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8348        result.setComponent(r.errorReportReceiver);
8349        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8350        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8351        return result;
8352    }
8353
8354    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8355            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8356        if (r.errorReportReceiver == null) {
8357            return null;
8358        }
8359
8360        if (!r.crashing && !r.notResponding) {
8361            return null;
8362        }
8363
8364        ApplicationErrorReport report = new ApplicationErrorReport();
8365        report.packageName = r.info.packageName;
8366        report.installerPackageName = r.errorReportReceiver.getPackageName();
8367        report.processName = r.processName;
8368        report.time = timeMillis;
8369        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8370
8371        if (r.crashing) {
8372            report.type = ApplicationErrorReport.TYPE_CRASH;
8373            report.crashInfo = crashInfo;
8374        } else if (r.notResponding) {
8375            report.type = ApplicationErrorReport.TYPE_ANR;
8376            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8377
8378            report.anrInfo.activity = r.notRespondingReport.tag;
8379            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8380            report.anrInfo.info = r.notRespondingReport.longMsg;
8381        }
8382
8383        return report;
8384    }
8385
8386    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8387        enforceNotIsolatedCaller("getProcessesInErrorState");
8388        // assume our apps are happy - lazy create the list
8389        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8390
8391        final boolean allUsers = ActivityManager.checkUidPermission(
8392                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8393                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8394        int userId = UserHandle.getUserId(Binder.getCallingUid());
8395
8396        synchronized (this) {
8397
8398            // iterate across all processes
8399            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8400                ProcessRecord app = mLruProcesses.get(i);
8401                if (!allUsers && app.userId != userId) {
8402                    continue;
8403                }
8404                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8405                    // This one's in trouble, so we'll generate a report for it
8406                    // crashes are higher priority (in case there's a crash *and* an anr)
8407                    ActivityManager.ProcessErrorStateInfo report = null;
8408                    if (app.crashing) {
8409                        report = app.crashingReport;
8410                    } else if (app.notResponding) {
8411                        report = app.notRespondingReport;
8412                    }
8413
8414                    if (report != null) {
8415                        if (errList == null) {
8416                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8417                        }
8418                        errList.add(report);
8419                    } else {
8420                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8421                                " crashing = " + app.crashing +
8422                                " notResponding = " + app.notResponding);
8423                    }
8424                }
8425            }
8426        }
8427
8428        return errList;
8429    }
8430
8431    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8432        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8433            if (currApp != null) {
8434                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8435            }
8436            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8437        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8438            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8439        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8440            if (currApp != null) {
8441                currApp.lru = 0;
8442            }
8443            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8444        } else if (adj >= ProcessList.SERVICE_ADJ) {
8445            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8446        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8447            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8448        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8449            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8450        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8451            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8452        } else {
8453            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8454        }
8455    }
8456
8457    private void fillInProcMemInfo(ProcessRecord app,
8458            ActivityManager.RunningAppProcessInfo outInfo) {
8459        outInfo.pid = app.pid;
8460        outInfo.uid = app.info.uid;
8461        if (mHeavyWeightProcess == app) {
8462            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8463        }
8464        if (app.persistent) {
8465            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8466        }
8467        if (app.hasActivities) {
8468            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8469        }
8470        outInfo.lastTrimLevel = app.trimMemoryLevel;
8471        int adj = app.curAdj;
8472        outInfo.importance = oomAdjToImportance(adj, outInfo);
8473        outInfo.importanceReasonCode = app.adjTypeCode;
8474    }
8475
8476    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8477        enforceNotIsolatedCaller("getRunningAppProcesses");
8478        // Lazy instantiation of list
8479        List<ActivityManager.RunningAppProcessInfo> runList = null;
8480        final boolean allUsers = ActivityManager.checkUidPermission(
8481                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8482                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8483        int userId = UserHandle.getUserId(Binder.getCallingUid());
8484        synchronized (this) {
8485            // Iterate across all processes
8486            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8487                ProcessRecord app = mLruProcesses.get(i);
8488                if (!allUsers && app.userId != userId) {
8489                    continue;
8490                }
8491                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8492                    // Generate process state info for running application
8493                    ActivityManager.RunningAppProcessInfo currApp =
8494                        new ActivityManager.RunningAppProcessInfo(app.processName,
8495                                app.pid, app.getPackageList());
8496                    fillInProcMemInfo(app, currApp);
8497                    if (app.adjSource instanceof ProcessRecord) {
8498                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8499                        currApp.importanceReasonImportance = oomAdjToImportance(
8500                                app.adjSourceOom, null);
8501                    } else if (app.adjSource instanceof ActivityRecord) {
8502                        ActivityRecord r = (ActivityRecord)app.adjSource;
8503                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8504                    }
8505                    if (app.adjTarget instanceof ComponentName) {
8506                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8507                    }
8508                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8509                    //        + " lru=" + currApp.lru);
8510                    if (runList == null) {
8511                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8512                    }
8513                    runList.add(currApp);
8514                }
8515            }
8516        }
8517        return runList;
8518    }
8519
8520    public List<ApplicationInfo> getRunningExternalApplications() {
8521        enforceNotIsolatedCaller("getRunningExternalApplications");
8522        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8523        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8524        if (runningApps != null && runningApps.size() > 0) {
8525            Set<String> extList = new HashSet<String>();
8526            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8527                if (app.pkgList != null) {
8528                    for (String pkg : app.pkgList) {
8529                        extList.add(pkg);
8530                    }
8531                }
8532            }
8533            IPackageManager pm = AppGlobals.getPackageManager();
8534            for (String pkg : extList) {
8535                try {
8536                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8537                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8538                        retList.add(info);
8539                    }
8540                } catch (RemoteException e) {
8541                }
8542            }
8543        }
8544        return retList;
8545    }
8546
8547    @Override
8548    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8549        enforceNotIsolatedCaller("getMyMemoryState");
8550        synchronized (this) {
8551            ProcessRecord proc;
8552            synchronized (mPidsSelfLocked) {
8553                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8554            }
8555            fillInProcMemInfo(proc, outInfo);
8556        }
8557    }
8558
8559    @Override
8560    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8561        if (checkCallingPermission(android.Manifest.permission.DUMP)
8562                != PackageManager.PERMISSION_GRANTED) {
8563            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8564                    + Binder.getCallingPid()
8565                    + ", uid=" + Binder.getCallingUid()
8566                    + " without permission "
8567                    + android.Manifest.permission.DUMP);
8568            return;
8569        }
8570
8571        boolean dumpAll = false;
8572        boolean dumpClient = false;
8573        String dumpPackage = null;
8574
8575        int opti = 0;
8576        while (opti < args.length) {
8577            String opt = args[opti];
8578            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8579                break;
8580            }
8581            opti++;
8582            if ("-a".equals(opt)) {
8583                dumpAll = true;
8584            } else if ("-c".equals(opt)) {
8585                dumpClient = true;
8586            } else if ("-h".equals(opt)) {
8587                pw.println("Activity manager dump options:");
8588                pw.println("  [-a] [-c] [-h] [cmd] ...");
8589                pw.println("  cmd may be one of:");
8590                pw.println("    a[ctivities]: activity stack state");
8591                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8592                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8593                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8594                pw.println("    o[om]: out of memory management");
8595                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8596                pw.println("    provider [COMP_SPEC]: provider client-side state");
8597                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8598                pw.println("    service [COMP_SPEC]: service client-side state");
8599                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8600                pw.println("    all: dump all activities");
8601                pw.println("    top: dump the top activity");
8602                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8603                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8604                pw.println("    a partial substring in a component name, a");
8605                pw.println("    hex object identifier.");
8606                pw.println("  -a: include all available server state.");
8607                pw.println("  -c: include client state.");
8608                return;
8609            } else {
8610                pw.println("Unknown argument: " + opt + "; use -h for help");
8611            }
8612        }
8613
8614        long origId = Binder.clearCallingIdentity();
8615        boolean more = false;
8616        // Is the caller requesting to dump a particular piece of data?
8617        if (opti < args.length) {
8618            String cmd = args[opti];
8619            opti++;
8620            if ("activities".equals(cmd) || "a".equals(cmd)) {
8621                synchronized (this) {
8622                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8623                }
8624            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8625                String[] newArgs;
8626                String name;
8627                if (opti >= args.length) {
8628                    name = null;
8629                    newArgs = EMPTY_STRING_ARRAY;
8630                } else {
8631                    name = args[opti];
8632                    opti++;
8633                    newArgs = new String[args.length - opti];
8634                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8635                            args.length - opti);
8636                }
8637                synchronized (this) {
8638                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8639                }
8640            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8641                String[] newArgs;
8642                String name;
8643                if (opti >= args.length) {
8644                    name = null;
8645                    newArgs = EMPTY_STRING_ARRAY;
8646                } else {
8647                    name = args[opti];
8648                    opti++;
8649                    newArgs = new String[args.length - opti];
8650                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8651                            args.length - opti);
8652                }
8653                synchronized (this) {
8654                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8655                }
8656            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8657                String[] newArgs;
8658                String name;
8659                if (opti >= args.length) {
8660                    name = null;
8661                    newArgs = EMPTY_STRING_ARRAY;
8662                } else {
8663                    name = args[opti];
8664                    opti++;
8665                    newArgs = new String[args.length - opti];
8666                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8667                            args.length - opti);
8668                }
8669                synchronized (this) {
8670                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8671                }
8672            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8673                synchronized (this) {
8674                    dumpOomLocked(fd, pw, args, opti, true);
8675                }
8676            } else if ("provider".equals(cmd)) {
8677                String[] newArgs;
8678                String name;
8679                if (opti >= args.length) {
8680                    name = null;
8681                    newArgs = EMPTY_STRING_ARRAY;
8682                } else {
8683                    name = args[opti];
8684                    opti++;
8685                    newArgs = new String[args.length - opti];
8686                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8687                }
8688                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8689                    pw.println("No providers match: " + name);
8690                    pw.println("Use -h for help.");
8691                }
8692            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8693                synchronized (this) {
8694                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8695                }
8696            } else if ("service".equals(cmd)) {
8697                String[] newArgs;
8698                String name;
8699                if (opti >= args.length) {
8700                    name = null;
8701                    newArgs = EMPTY_STRING_ARRAY;
8702                } else {
8703                    name = args[opti];
8704                    opti++;
8705                    newArgs = new String[args.length - opti];
8706                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8707                            args.length - opti);
8708                }
8709                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8710                    pw.println("No services match: " + name);
8711                    pw.println("Use -h for help.");
8712                }
8713            } else if ("package".equals(cmd)) {
8714                String[] newArgs;
8715                if (opti >= args.length) {
8716                    pw.println("package: no package name specified");
8717                    pw.println("Use -h for help.");
8718                } else {
8719                    dumpPackage = args[opti];
8720                    opti++;
8721                    newArgs = new String[args.length - opti];
8722                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8723                            args.length - opti);
8724                    args = newArgs;
8725                    opti = 0;
8726                    more = true;
8727                }
8728            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8729                synchronized (this) {
8730                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8731                }
8732            } else {
8733                // Dumping a single activity?
8734                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8735                    pw.println("Bad activity command, or no activities match: " + cmd);
8736                    pw.println("Use -h for help.");
8737                }
8738            }
8739            if (!more) {
8740                Binder.restoreCallingIdentity(origId);
8741                return;
8742            }
8743        }
8744
8745        // No piece of data specified, dump everything.
8746        synchronized (this) {
8747            boolean needSep;
8748            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8749            if (needSep) {
8750                pw.println(" ");
8751            }
8752            if (dumpAll) {
8753                pw.println("-------------------------------------------------------------------------------");
8754            }
8755            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8756            if (needSep) {
8757                pw.println(" ");
8758            }
8759            if (dumpAll) {
8760                pw.println("-------------------------------------------------------------------------------");
8761            }
8762            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8763            if (needSep) {
8764                pw.println(" ");
8765            }
8766            if (dumpAll) {
8767                pw.println("-------------------------------------------------------------------------------");
8768            }
8769            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8770            if (needSep) {
8771                pw.println(" ");
8772            }
8773            if (dumpAll) {
8774                pw.println("-------------------------------------------------------------------------------");
8775            }
8776            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8777            if (needSep) {
8778                pw.println(" ");
8779            }
8780            if (dumpAll) {
8781                pw.println("-------------------------------------------------------------------------------");
8782            }
8783            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8784        }
8785        Binder.restoreCallingIdentity(origId);
8786    }
8787
8788    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8789            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8790        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8791        pw.println("  Main stack:");
8792        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8793                dumpPackage);
8794        pw.println(" ");
8795        pw.println("  Running activities (most recent first):");
8796        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8797                dumpPackage);
8798        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8799            pw.println(" ");
8800            pw.println("  Activities waiting for another to become visible:");
8801            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8802                    !dumpAll, false, dumpPackage);
8803        }
8804        if (mMainStack.mStoppingActivities.size() > 0) {
8805            pw.println(" ");
8806            pw.println("  Activities waiting to stop:");
8807            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8808                    !dumpAll, false, dumpPackage);
8809        }
8810        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8811            pw.println(" ");
8812            pw.println("  Activities waiting to sleep:");
8813            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8814                    !dumpAll, false, dumpPackage);
8815        }
8816        if (mMainStack.mFinishingActivities.size() > 0) {
8817            pw.println(" ");
8818            pw.println("  Activities waiting to finish:");
8819            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8820                    !dumpAll, false, dumpPackage);
8821        }
8822
8823        pw.println(" ");
8824        if (mMainStack.mPausingActivity != null) {
8825            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8826        }
8827        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8828        pw.println("  mFocusedActivity: " + mFocusedActivity);
8829        if (dumpAll) {
8830            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8831            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8832            pw.println("  mDismissKeyguardOnNextActivity: "
8833                    + mMainStack.mDismissKeyguardOnNextActivity);
8834        }
8835
8836        if (mRecentTasks.size() > 0) {
8837            pw.println();
8838            pw.println("  Recent tasks:");
8839
8840            final int N = mRecentTasks.size();
8841            for (int i=0; i<N; i++) {
8842                TaskRecord tr = mRecentTasks.get(i);
8843                if (dumpPackage != null) {
8844                    if (tr.realActivity == null ||
8845                            !dumpPackage.equals(tr.realActivity)) {
8846                        continue;
8847                    }
8848                }
8849                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8850                        pw.println(tr);
8851                if (dumpAll) {
8852                    mRecentTasks.get(i).dump(pw, "    ");
8853                }
8854            }
8855        }
8856
8857        if (dumpAll) {
8858            pw.println(" ");
8859            pw.println("  mCurTask: " + mCurTask);
8860        }
8861
8862        return true;
8863    }
8864
8865    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8866            int opti, boolean dumpAll, String dumpPackage) {
8867        boolean needSep = false;
8868        int numPers = 0;
8869
8870        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8871
8872        if (dumpAll) {
8873            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8874                final int NA = procs.size();
8875                for (int ia=0; ia<NA; ia++) {
8876                    ProcessRecord r = procs.valueAt(ia);
8877                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8878                        continue;
8879                    }
8880                    if (!needSep) {
8881                        pw.println("  All known processes:");
8882                        needSep = true;
8883                    }
8884                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8885                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8886                        pw.print(" "); pw.println(r);
8887                    r.dump(pw, "    ");
8888                    if (r.persistent) {
8889                        numPers++;
8890                    }
8891                }
8892            }
8893        }
8894
8895        if (mIsolatedProcesses.size() > 0) {
8896            if (needSep) pw.println(" ");
8897            needSep = true;
8898            pw.println("  Isolated process list (sorted by uid):");
8899            for (int i=0; i<mIsolatedProcesses.size(); i++) {
8900                ProcessRecord r = mIsolatedProcesses.valueAt(i);
8901                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8902                    continue;
8903                }
8904                pw.println(String.format("%sIsolated #%2d: %s",
8905                        "    ", i, r.toString()));
8906            }
8907        }
8908
8909        if (mLruProcesses.size() > 0) {
8910            if (needSep) pw.println(" ");
8911            needSep = true;
8912            pw.println("  Process LRU list (sorted by oom_adj):");
8913            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8914                    "Proc", "PERS", false, dumpPackage);
8915            needSep = true;
8916        }
8917
8918        if (dumpAll) {
8919            synchronized (mPidsSelfLocked) {
8920                boolean printed = false;
8921                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8922                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8923                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8924                        continue;
8925                    }
8926                    if (!printed) {
8927                        if (needSep) pw.println(" ");
8928                        needSep = true;
8929                        pw.println("  PID mappings:");
8930                        printed = true;
8931                    }
8932                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8933                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8934                }
8935            }
8936        }
8937
8938        if (mForegroundProcesses.size() > 0) {
8939            synchronized (mPidsSelfLocked) {
8940                boolean printed = false;
8941                for (int i=0; i<mForegroundProcesses.size(); i++) {
8942                    ProcessRecord r = mPidsSelfLocked.get(
8943                            mForegroundProcesses.valueAt(i).pid);
8944                    if (dumpPackage != null && (r == null
8945                            || !dumpPackage.equals(r.info.packageName))) {
8946                        continue;
8947                    }
8948                    if (!printed) {
8949                        if (needSep) pw.println(" ");
8950                        needSep = true;
8951                        pw.println("  Foreground Processes:");
8952                        printed = true;
8953                    }
8954                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
8955                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8956                }
8957            }
8958        }
8959
8960        if (mPersistentStartingProcesses.size() > 0) {
8961            if (needSep) pw.println(" ");
8962            needSep = true;
8963            pw.println("  Persisent processes that are starting:");
8964            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
8965                    "Starting Norm", "Restarting PERS", dumpPackage);
8966        }
8967
8968        if (mRemovedProcesses.size() > 0) {
8969            if (needSep) pw.println(" ");
8970            needSep = true;
8971            pw.println("  Processes that are being removed:");
8972            dumpProcessList(pw, this, mRemovedProcesses, "    ",
8973                    "Removed Norm", "Removed PERS", dumpPackage);
8974        }
8975
8976        if (mProcessesOnHold.size() > 0) {
8977            if (needSep) pw.println(" ");
8978            needSep = true;
8979            pw.println("  Processes that are on old until the system is ready:");
8980            dumpProcessList(pw, this, mProcessesOnHold, "    ",
8981                    "OnHold Norm", "OnHold PERS", dumpPackage);
8982        }
8983
8984        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
8985
8986        if (mProcessCrashTimes.getMap().size() > 0) {
8987            boolean printed = false;
8988            long now = SystemClock.uptimeMillis();
8989            for (Map.Entry<String, SparseArray<Long>> procs
8990                    : mProcessCrashTimes.getMap().entrySet()) {
8991                String pname = procs.getKey();
8992                SparseArray<Long> uids = procs.getValue();
8993                final int N = uids.size();
8994                for (int i=0; i<N; i++) {
8995                    int puid = uids.keyAt(i);
8996                    ProcessRecord r = mProcessNames.get(pname, puid);
8997                    if (dumpPackage != null && (r == null
8998                            || !dumpPackage.equals(r.info.packageName))) {
8999                        continue;
9000                    }
9001                    if (!printed) {
9002                        if (needSep) pw.println(" ");
9003                        needSep = true;
9004                        pw.println("  Time since processes crashed:");
9005                        printed = true;
9006                    }
9007                    pw.print("    Process "); pw.print(pname);
9008                            pw.print(" uid "); pw.print(puid);
9009                            pw.print(": last crashed ");
9010                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9011                            pw.println(" ago");
9012                }
9013            }
9014        }
9015
9016        if (mBadProcesses.getMap().size() > 0) {
9017            boolean printed = false;
9018            for (Map.Entry<String, SparseArray<Long>> procs
9019                    : mBadProcesses.getMap().entrySet()) {
9020                String pname = procs.getKey();
9021                SparseArray<Long> uids = procs.getValue();
9022                final int N = uids.size();
9023                for (int i=0; i<N; i++) {
9024                    int puid = uids.keyAt(i);
9025                    ProcessRecord r = mProcessNames.get(pname, puid);
9026                    if (dumpPackage != null && (r == null
9027                            || !dumpPackage.equals(r.info.packageName))) {
9028                        continue;
9029                    }
9030                    if (!printed) {
9031                        if (needSep) pw.println(" ");
9032                        needSep = true;
9033                        pw.println("  Bad processes:");
9034                    }
9035                    pw.print("    Bad process "); pw.print(pname);
9036                            pw.print(" uid "); pw.print(puid);
9037                            pw.print(": crashed at time ");
9038                            pw.println(uids.valueAt(i));
9039                }
9040            }
9041        }
9042
9043        pw.println();
9044        pw.println("  mHomeProcess: " + mHomeProcess);
9045        pw.println("  mPreviousProcess: " + mPreviousProcess);
9046        if (dumpAll) {
9047            StringBuilder sb = new StringBuilder(128);
9048            sb.append("  mPreviousProcessVisibleTime: ");
9049            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9050            pw.println(sb);
9051        }
9052        if (mHeavyWeightProcess != null) {
9053            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9054        }
9055        pw.println("  mConfiguration: " + mConfiguration);
9056        if (dumpAll) {
9057            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9058            if (mCompatModePackages.getPackages().size() > 0) {
9059                boolean printed = false;
9060                for (Map.Entry<String, Integer> entry
9061                        : mCompatModePackages.getPackages().entrySet()) {
9062                    String pkg = entry.getKey();
9063                    int mode = entry.getValue();
9064                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9065                        continue;
9066                    }
9067                    if (!printed) {
9068                        pw.println("  mScreenCompatPackages:");
9069                        printed = true;
9070                    }
9071                    pw.print("    "); pw.print(pkg); pw.print(": ");
9072                            pw.print(mode); pw.println();
9073                }
9074            }
9075        }
9076        if (mSleeping || mWentToSleep || mLockScreenShown) {
9077            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9078                    + " mLockScreenShown " + mLockScreenShown);
9079        }
9080        if (mShuttingDown) {
9081            pw.println("  mShuttingDown=" + mShuttingDown);
9082        }
9083        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9084                || mOrigWaitForDebugger) {
9085            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9086                    + " mDebugTransient=" + mDebugTransient
9087                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9088        }
9089        if (mOpenGlTraceApp != null) {
9090            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9091        }
9092        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9093                || mProfileFd != null) {
9094            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9095            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9096            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9097                    + mAutoStopProfiler);
9098        }
9099        if (mAlwaysFinishActivities || mController != null) {
9100            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9101                    + " mController=" + mController);
9102        }
9103        if (dumpAll) {
9104            pw.println("  Total persistent processes: " + numPers);
9105            pw.println("  mStartRunning=" + mStartRunning
9106                    + " mProcessesReady=" + mProcessesReady
9107                    + " mSystemReady=" + mSystemReady);
9108            pw.println("  mBooting=" + mBooting
9109                    + " mBooted=" + mBooted
9110                    + " mFactoryTest=" + mFactoryTest);
9111            pw.print("  mLastPowerCheckRealtime=");
9112                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9113                    pw.println("");
9114            pw.print("  mLastPowerCheckUptime=");
9115                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9116                    pw.println("");
9117            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9118            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9119            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9120            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9121                    + " mNumHiddenProcs=" + mNumHiddenProcs
9122                    + " mNumServiceProcs=" + mNumServiceProcs
9123                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9124        }
9125
9126        return true;
9127    }
9128
9129    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9130            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9131        if (mProcessesToGc.size() > 0) {
9132            boolean printed = false;
9133            long now = SystemClock.uptimeMillis();
9134            for (int i=0; i<mProcessesToGc.size(); i++) {
9135                ProcessRecord proc = mProcessesToGc.get(i);
9136                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9137                    continue;
9138                }
9139                if (!printed) {
9140                    if (needSep) pw.println(" ");
9141                    needSep = true;
9142                    pw.println("  Processes that are waiting to GC:");
9143                    printed = true;
9144                }
9145                pw.print("    Process "); pw.println(proc);
9146                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9147                        pw.print(", last gced=");
9148                        pw.print(now-proc.lastRequestedGc);
9149                        pw.print(" ms ago, last lowMem=");
9150                        pw.print(now-proc.lastLowMemory);
9151                        pw.println(" ms ago");
9152
9153            }
9154        }
9155        return needSep;
9156    }
9157
9158    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9159            int opti, boolean dumpAll) {
9160        boolean needSep = false;
9161
9162        if (mLruProcesses.size() > 0) {
9163            if (needSep) pw.println(" ");
9164            needSep = true;
9165            pw.println("  OOM levels:");
9166            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9167            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9168            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9169            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9170            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9171            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9172            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9173            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9174            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9175            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9176            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9177            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9178            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9179
9180            if (needSep) pw.println(" ");
9181            needSep = true;
9182            pw.println("  Process OOM control:");
9183            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9184                    "Proc", "PERS", true, null);
9185            needSep = true;
9186        }
9187
9188        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9189
9190        pw.println();
9191        pw.println("  mHomeProcess: " + mHomeProcess);
9192        pw.println("  mPreviousProcess: " + mPreviousProcess);
9193        if (mHeavyWeightProcess != null) {
9194            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9195        }
9196
9197        return true;
9198    }
9199
9200    /**
9201     * There are three ways to call this:
9202     *  - no provider specified: dump all the providers
9203     *  - a flattened component name that matched an existing provider was specified as the
9204     *    first arg: dump that one provider
9205     *  - the first arg isn't the flattened component name of an existing provider:
9206     *    dump all providers whose component contains the first arg as a substring
9207     */
9208    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9209            int opti, boolean dumpAll) {
9210        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9211    }
9212
9213    static class ItemMatcher {
9214        ArrayList<ComponentName> components;
9215        ArrayList<String> strings;
9216        ArrayList<Integer> objects;
9217        boolean all;
9218
9219        ItemMatcher() {
9220            all = true;
9221        }
9222
9223        void build(String name) {
9224            ComponentName componentName = ComponentName.unflattenFromString(name);
9225            if (componentName != null) {
9226                if (components == null) {
9227                    components = new ArrayList<ComponentName>();
9228                }
9229                components.add(componentName);
9230                all = false;
9231            } else {
9232                int objectId = 0;
9233                // Not a '/' separated full component name; maybe an object ID?
9234                try {
9235                    objectId = Integer.parseInt(name, 16);
9236                    if (objects == null) {
9237                        objects = new ArrayList<Integer>();
9238                    }
9239                    objects.add(objectId);
9240                    all = false;
9241                } catch (RuntimeException e) {
9242                    // Not an integer; just do string match.
9243                    if (strings == null) {
9244                        strings = new ArrayList<String>();
9245                    }
9246                    strings.add(name);
9247                    all = false;
9248                }
9249            }
9250        }
9251
9252        int build(String[] args, int opti) {
9253            for (; opti<args.length; opti++) {
9254                String name = args[opti];
9255                if ("--".equals(name)) {
9256                    return opti+1;
9257                }
9258                build(name);
9259            }
9260            return opti;
9261        }
9262
9263        boolean match(Object object, ComponentName comp) {
9264            if (all) {
9265                return true;
9266            }
9267            if (components != null) {
9268                for (int i=0; i<components.size(); i++) {
9269                    if (components.get(i).equals(comp)) {
9270                        return true;
9271                    }
9272                }
9273            }
9274            if (objects != null) {
9275                for (int i=0; i<objects.size(); i++) {
9276                    if (System.identityHashCode(object) == objects.get(i)) {
9277                        return true;
9278                    }
9279                }
9280            }
9281            if (strings != null) {
9282                String flat = comp.flattenToString();
9283                for (int i=0; i<strings.size(); i++) {
9284                    if (flat.contains(strings.get(i))) {
9285                        return true;
9286                    }
9287                }
9288            }
9289            return false;
9290        }
9291    }
9292
9293    /**
9294     * There are three things that cmd can be:
9295     *  - a flattened component name that matches an existing activity
9296     *  - the cmd arg isn't the flattened component name of an existing activity:
9297     *    dump all activity whose component contains the cmd as a substring
9298     *  - A hex number of the ActivityRecord object instance.
9299     */
9300    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9301            int opti, boolean dumpAll) {
9302        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9303
9304        if ("all".equals(name)) {
9305            synchronized (this) {
9306                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9307                    activities.add(r1);
9308                }
9309            }
9310        } else if ("top".equals(name)) {
9311            synchronized (this) {
9312                final int N = mMainStack.mHistory.size();
9313                if (N > 0) {
9314                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9315                }
9316            }
9317        } else {
9318            ItemMatcher matcher = new ItemMatcher();
9319            matcher.build(name);
9320
9321            synchronized (this) {
9322                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9323                    if (matcher.match(r1, r1.intent.getComponent())) {
9324                        activities.add(r1);
9325                    }
9326                }
9327            }
9328        }
9329
9330        if (activities.size() <= 0) {
9331            return false;
9332        }
9333
9334        String[] newArgs = new String[args.length - opti];
9335        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9336
9337        TaskRecord lastTask = null;
9338        boolean needSep = false;
9339        for (int i=activities.size()-1; i>=0; i--) {
9340            ActivityRecord r = (ActivityRecord)activities.get(i);
9341            if (needSep) {
9342                pw.println();
9343            }
9344            needSep = true;
9345            synchronized (this) {
9346                if (lastTask != r.task) {
9347                    lastTask = r.task;
9348                    pw.print("TASK "); pw.print(lastTask.affinity);
9349                            pw.print(" id="); pw.println(lastTask.taskId);
9350                    if (dumpAll) {
9351                        lastTask.dump(pw, "  ");
9352                    }
9353                }
9354            }
9355            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9356        }
9357        return true;
9358    }
9359
9360    /**
9361     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9362     * there is a thread associated with the activity.
9363     */
9364    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9365            final ActivityRecord r, String[] args, boolean dumpAll) {
9366        String innerPrefix = prefix + "  ";
9367        synchronized (this) {
9368            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9369                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9370                    pw.print(" pid=");
9371                    if (r.app != null) pw.println(r.app.pid);
9372                    else pw.println("(not running)");
9373            if (dumpAll) {
9374                r.dump(pw, innerPrefix);
9375            }
9376        }
9377        if (r.app != null && r.app.thread != null) {
9378            // flush anything that is already in the PrintWriter since the thread is going
9379            // to write to the file descriptor directly
9380            pw.flush();
9381            try {
9382                TransferPipe tp = new TransferPipe();
9383                try {
9384                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9385                            r.appToken, innerPrefix, args);
9386                    tp.go(fd);
9387                } finally {
9388                    tp.kill();
9389                }
9390            } catch (IOException e) {
9391                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9392            } catch (RemoteException e) {
9393                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9394            }
9395        }
9396    }
9397
9398    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9399            int opti, boolean dumpAll, String dumpPackage) {
9400        boolean needSep = false;
9401
9402        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9403        if (dumpAll) {
9404            if (mRegisteredReceivers.size() > 0) {
9405                boolean printed = false;
9406                Iterator it = mRegisteredReceivers.values().iterator();
9407                while (it.hasNext()) {
9408                    ReceiverList r = (ReceiverList)it.next();
9409                    if (dumpPackage != null && (r.app == null ||
9410                            !dumpPackage.equals(r.app.info.packageName))) {
9411                        continue;
9412                    }
9413                    if (!printed) {
9414                        pw.println("  Registered Receivers:");
9415                        needSep = true;
9416                        printed = true;
9417                    }
9418                    pw.print("  * "); pw.println(r);
9419                    r.dump(pw, "    ");
9420                }
9421            }
9422
9423            if (mReceiverResolver.dump(pw, needSep ?
9424                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9425                    "    ", dumpPackage, false)) {
9426                needSep = true;
9427            }
9428        }
9429
9430        for (BroadcastQueue q : mBroadcastQueues) {
9431            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9432        }
9433
9434        needSep = true;
9435
9436        if (mStickyBroadcasts != null && dumpPackage == null) {
9437            if (needSep) {
9438                pw.println();
9439            }
9440            needSep = true;
9441            pw.println("  Sticky broadcasts:");
9442            StringBuilder sb = new StringBuilder(128);
9443            for (Map.Entry<String, ArrayList<Intent>> ent
9444                    : mStickyBroadcasts.entrySet()) {
9445                pw.print("  * Sticky action "); pw.print(ent.getKey());
9446                if (dumpAll) {
9447                    pw.println(":");
9448                    ArrayList<Intent> intents = ent.getValue();
9449                    final int N = intents.size();
9450                    for (int i=0; i<N; i++) {
9451                        sb.setLength(0);
9452                        sb.append("    Intent: ");
9453                        intents.get(i).toShortString(sb, false, true, false, false);
9454                        pw.println(sb.toString());
9455                        Bundle bundle = intents.get(i).getExtras();
9456                        if (bundle != null) {
9457                            pw.print("      ");
9458                            pw.println(bundle.toString());
9459                        }
9460                    }
9461                } else {
9462                    pw.println("");
9463                }
9464            }
9465            needSep = true;
9466        }
9467
9468        if (dumpAll) {
9469            pw.println();
9470            for (BroadcastQueue queue : mBroadcastQueues) {
9471                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9472                        + queue.mBroadcastsScheduled);
9473            }
9474            pw.println("  mHandler:");
9475            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9476            needSep = true;
9477        }
9478
9479        return needSep;
9480    }
9481
9482    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9483            int opti, boolean dumpAll, String dumpPackage) {
9484        boolean needSep = true;
9485
9486        ItemMatcher matcher = new ItemMatcher();
9487        matcher.build(args, opti);
9488
9489        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9490
9491        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9492
9493        if (mLaunchingProviders.size() > 0) {
9494            boolean printed = false;
9495            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9496                ContentProviderRecord r = mLaunchingProviders.get(i);
9497                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9498                    continue;
9499                }
9500                if (!printed) {
9501                    if (needSep) pw.println(" ");
9502                    needSep = true;
9503                    pw.println("  Launching content providers:");
9504                    printed = true;
9505                }
9506                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9507                        pw.println(r);
9508            }
9509        }
9510
9511        if (mGrantedUriPermissions.size() > 0) {
9512            if (needSep) pw.println();
9513            needSep = true;
9514            pw.println("Granted Uri Permissions:");
9515            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9516                int uid = mGrantedUriPermissions.keyAt(i);
9517                HashMap<Uri, UriPermission> perms
9518                        = mGrantedUriPermissions.valueAt(i);
9519                pw.print("  * UID "); pw.print(uid);
9520                        pw.println(" holds:");
9521                for (UriPermission perm : perms.values()) {
9522                    pw.print("    "); pw.println(perm);
9523                    if (dumpAll) {
9524                        perm.dump(pw, "      ");
9525                    }
9526                }
9527            }
9528            needSep = true;
9529        }
9530
9531        return needSep;
9532    }
9533
9534    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9535            int opti, boolean dumpAll, String dumpPackage) {
9536        boolean needSep = false;
9537
9538        if (mIntentSenderRecords.size() > 0) {
9539            boolean printed = false;
9540            Iterator<WeakReference<PendingIntentRecord>> it
9541                    = mIntentSenderRecords.values().iterator();
9542            while (it.hasNext()) {
9543                WeakReference<PendingIntentRecord> ref = it.next();
9544                PendingIntentRecord rec = ref != null ? ref.get(): null;
9545                if (dumpPackage != null && (rec == null
9546                        || !dumpPackage.equals(rec.key.packageName))) {
9547                    continue;
9548                }
9549                if (!printed) {
9550                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9551                    printed = true;
9552                }
9553                needSep = true;
9554                if (rec != null) {
9555                    pw.print("  * "); pw.println(rec);
9556                    if (dumpAll) {
9557                        rec.dump(pw, "    ");
9558                    }
9559                } else {
9560                    pw.print("  * "); pw.println(ref);
9561                }
9562            }
9563        }
9564
9565        return needSep;
9566    }
9567
9568    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9569            String prefix, String label, boolean complete, boolean brief, boolean client,
9570            String dumpPackage) {
9571        TaskRecord lastTask = null;
9572        boolean needNL = false;
9573        final String innerPrefix = prefix + "      ";
9574        final String[] args = new String[0];
9575        for (int i=list.size()-1; i>=0; i--) {
9576            final ActivityRecord r = (ActivityRecord)list.get(i);
9577            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9578                continue;
9579            }
9580            final boolean full = !brief && (complete || !r.isInHistory());
9581            if (needNL) {
9582                pw.println(" ");
9583                needNL = false;
9584            }
9585            if (lastTask != r.task) {
9586                lastTask = r.task;
9587                pw.print(prefix);
9588                pw.print(full ? "* " : "  ");
9589                pw.println(lastTask);
9590                if (full) {
9591                    lastTask.dump(pw, prefix + "  ");
9592                } else if (complete) {
9593                    // Complete + brief == give a summary.  Isn't that obvious?!?
9594                    if (lastTask.intent != null) {
9595                        pw.print(prefix); pw.print("  ");
9596                                pw.println(lastTask.intent.toInsecureStringWithClip());
9597                    }
9598                }
9599            }
9600            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9601            pw.print(" #"); pw.print(i); pw.print(": ");
9602            pw.println(r);
9603            if (full) {
9604                r.dump(pw, innerPrefix);
9605            } else if (complete) {
9606                // Complete + brief == give a summary.  Isn't that obvious?!?
9607                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9608                if (r.app != null) {
9609                    pw.print(innerPrefix); pw.println(r.app);
9610                }
9611            }
9612            if (client && r.app != null && r.app.thread != null) {
9613                // flush anything that is already in the PrintWriter since the thread is going
9614                // to write to the file descriptor directly
9615                pw.flush();
9616                try {
9617                    TransferPipe tp = new TransferPipe();
9618                    try {
9619                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9620                                r.appToken, innerPrefix, args);
9621                        // Short timeout, since blocking here can
9622                        // deadlock with the application.
9623                        tp.go(fd, 2000);
9624                    } finally {
9625                        tp.kill();
9626                    }
9627                } catch (IOException e) {
9628                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9629                } catch (RemoteException e) {
9630                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9631                }
9632                needNL = true;
9633            }
9634        }
9635    }
9636
9637    private static String buildOomTag(String prefix, String space, int val, int base) {
9638        if (val == base) {
9639            if (space == null) return prefix;
9640            return prefix + "  ";
9641        }
9642        return prefix + "+" + Integer.toString(val-base);
9643    }
9644
9645    private static final int dumpProcessList(PrintWriter pw,
9646            ActivityManagerService service, List list,
9647            String prefix, String normalLabel, String persistentLabel,
9648            String dumpPackage) {
9649        int numPers = 0;
9650        final int N = list.size()-1;
9651        for (int i=N; i>=0; i--) {
9652            ProcessRecord r = (ProcessRecord)list.get(i);
9653            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9654                continue;
9655            }
9656            pw.println(String.format("%s%s #%2d: %s",
9657                    prefix, (r.persistent ? persistentLabel : normalLabel),
9658                    i, r.toString()));
9659            if (r.persistent) {
9660                numPers++;
9661            }
9662        }
9663        return numPers;
9664    }
9665
9666    private static final boolean dumpProcessOomList(PrintWriter pw,
9667            ActivityManagerService service, List<ProcessRecord> origList,
9668            String prefix, String normalLabel, String persistentLabel,
9669            boolean inclDetails, String dumpPackage) {
9670
9671        ArrayList<Pair<ProcessRecord, Integer>> list
9672                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9673        for (int i=0; i<origList.size(); i++) {
9674            ProcessRecord r = origList.get(i);
9675            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9676                continue;
9677            }
9678            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9679        }
9680
9681        if (list.size() <= 0) {
9682            return false;
9683        }
9684
9685        Comparator<Pair<ProcessRecord, Integer>> comparator
9686                = new Comparator<Pair<ProcessRecord, Integer>>() {
9687            @Override
9688            public int compare(Pair<ProcessRecord, Integer> object1,
9689                    Pair<ProcessRecord, Integer> object2) {
9690                if (object1.first.setAdj != object2.first.setAdj) {
9691                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9692                }
9693                if (object1.second.intValue() != object2.second.intValue()) {
9694                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9695                }
9696                return 0;
9697            }
9698        };
9699
9700        Collections.sort(list, comparator);
9701
9702        final long curRealtime = SystemClock.elapsedRealtime();
9703        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9704        final long curUptime = SystemClock.uptimeMillis();
9705        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9706
9707        for (int i=list.size()-1; i>=0; i--) {
9708            ProcessRecord r = list.get(i).first;
9709            String oomAdj;
9710            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9711                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9712            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9713                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9714            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9715                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9716            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9717                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9718            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9719                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9720            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9721                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9722            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9723                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9724            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9725                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9726            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9727                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9728            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9729                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9730            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9731                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9732            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9733                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9734            } else {
9735                oomAdj = Integer.toString(r.setAdj);
9736            }
9737            String schedGroup;
9738            switch (r.setSchedGroup) {
9739                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9740                    schedGroup = "B";
9741                    break;
9742                case Process.THREAD_GROUP_DEFAULT:
9743                    schedGroup = "F";
9744                    break;
9745                default:
9746                    schedGroup = Integer.toString(r.setSchedGroup);
9747                    break;
9748            }
9749            String foreground;
9750            if (r.foregroundActivities) {
9751                foreground = "A";
9752            } else if (r.foregroundServices) {
9753                foreground = "S";
9754            } else {
9755                foreground = " ";
9756            }
9757            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9758                    prefix, (r.persistent ? persistentLabel : normalLabel),
9759                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9760                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9761            if (r.adjSource != null || r.adjTarget != null) {
9762                pw.print(prefix);
9763                pw.print("    ");
9764                if (r.adjTarget instanceof ComponentName) {
9765                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9766                } else if (r.adjTarget != null) {
9767                    pw.print(r.adjTarget.toString());
9768                } else {
9769                    pw.print("{null}");
9770                }
9771                pw.print("<=");
9772                if (r.adjSource instanceof ProcessRecord) {
9773                    pw.print("Proc{");
9774                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9775                    pw.println("}");
9776                } else if (r.adjSource != null) {
9777                    pw.println(r.adjSource.toString());
9778                } else {
9779                    pw.println("{null}");
9780                }
9781            }
9782            if (inclDetails) {
9783                pw.print(prefix);
9784                pw.print("    ");
9785                pw.print("oom: max="); pw.print(r.maxAdj);
9786                pw.print(" hidden="); pw.print(r.hiddenAdj);
9787                pw.print(" empty="); pw.print(r.emptyAdj);
9788                pw.print(" curRaw="); pw.print(r.curRawAdj);
9789                pw.print(" setRaw="); pw.print(r.setRawAdj);
9790                pw.print(" cur="); pw.print(r.curAdj);
9791                pw.print(" set="); pw.println(r.setAdj);
9792                pw.print(prefix);
9793                pw.print("    ");
9794                pw.print("keeping="); pw.print(r.keeping);
9795                pw.print(" hidden="); pw.print(r.hidden);
9796                pw.print(" empty="); pw.print(r.empty);
9797                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9798
9799                if (!r.keeping) {
9800                    if (r.lastWakeTime != 0) {
9801                        long wtime;
9802                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9803                        synchronized (stats) {
9804                            wtime = stats.getProcessWakeTime(r.info.uid,
9805                                    r.pid, curRealtime);
9806                        }
9807                        long timeUsed = wtime - r.lastWakeTime;
9808                        pw.print(prefix);
9809                        pw.print("    ");
9810                        pw.print("keep awake over ");
9811                        TimeUtils.formatDuration(realtimeSince, pw);
9812                        pw.print(" used ");
9813                        TimeUtils.formatDuration(timeUsed, pw);
9814                        pw.print(" (");
9815                        pw.print((timeUsed*100)/realtimeSince);
9816                        pw.println("%)");
9817                    }
9818                    if (r.lastCpuTime != 0) {
9819                        long timeUsed = r.curCpuTime - r.lastCpuTime;
9820                        pw.print(prefix);
9821                        pw.print("    ");
9822                        pw.print("run cpu over ");
9823                        TimeUtils.formatDuration(uptimeSince, pw);
9824                        pw.print(" used ");
9825                        TimeUtils.formatDuration(timeUsed, pw);
9826                        pw.print(" (");
9827                        pw.print((timeUsed*100)/uptimeSince);
9828                        pw.println("%)");
9829                    }
9830                }
9831            }
9832        }
9833        return true;
9834    }
9835
9836    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
9837        ArrayList<ProcessRecord> procs;
9838        synchronized (this) {
9839            if (args != null && args.length > start
9840                    && args[start].charAt(0) != '-') {
9841                procs = new ArrayList<ProcessRecord>();
9842                int pid = -1;
9843                try {
9844                    pid = Integer.parseInt(args[start]);
9845                } catch (NumberFormatException e) {
9846
9847                }
9848                for (int i=mLruProcesses.size()-1; i>=0; i--) {
9849                    ProcessRecord proc = mLruProcesses.get(i);
9850                    if (proc.pid == pid) {
9851                        procs.add(proc);
9852                    } else if (proc.processName.equals(args[start])) {
9853                        procs.add(proc);
9854                    }
9855                }
9856                if (procs.size() <= 0) {
9857                    pw.println("No process found for: " + args[start]);
9858                    return null;
9859                }
9860            } else {
9861                procs = new ArrayList<ProcessRecord>(mLruProcesses);
9862            }
9863        }
9864        return procs;
9865    }
9866
9867    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9868            PrintWriter pw, String[] args) {
9869        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9870        if (procs == null) {
9871            return;
9872        }
9873
9874        long uptime = SystemClock.uptimeMillis();
9875        long realtime = SystemClock.elapsedRealtime();
9876        pw.println("Applications Graphics Acceleration Info:");
9877        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9878
9879        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9880            ProcessRecord r = procs.get(i);
9881            if (r.thread != null) {
9882                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9883                pw.flush();
9884                try {
9885                    TransferPipe tp = new TransferPipe();
9886                    try {
9887                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9888                        tp.go(fd);
9889                    } finally {
9890                        tp.kill();
9891                    }
9892                } catch (IOException e) {
9893                    pw.println("Failure while dumping the app: " + r);
9894                    pw.flush();
9895                } catch (RemoteException e) {
9896                    pw.println("Got a RemoteException while dumping the app " + r);
9897                    pw.flush();
9898                }
9899            }
9900        }
9901    }
9902
9903    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
9904        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9905        if (procs == null) {
9906            return;
9907        }
9908
9909        pw.println("Applications Database Info:");
9910
9911        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9912            ProcessRecord r = procs.get(i);
9913            if (r.thread != null) {
9914                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
9915                pw.flush();
9916                try {
9917                    TransferPipe tp = new TransferPipe();
9918                    try {
9919                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
9920                        tp.go(fd);
9921                    } finally {
9922                        tp.kill();
9923                    }
9924                } catch (IOException e) {
9925                    pw.println("Failure while dumping the app: " + r);
9926                    pw.flush();
9927                } catch (RemoteException e) {
9928                    pw.println("Got a RemoteException while dumping the app " + r);
9929                    pw.flush();
9930                }
9931            }
9932        }
9933    }
9934
9935    final static class MemItem {
9936        final String label;
9937        final String shortLabel;
9938        final long pss;
9939        final int id;
9940        ArrayList<MemItem> subitems;
9941
9942        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
9943            label = _label;
9944            shortLabel = _shortLabel;
9945            pss = _pss;
9946            id = _id;
9947        }
9948    }
9949
9950    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9951            boolean sort) {
9952        if (sort) {
9953            Collections.sort(items, new Comparator<MemItem>() {
9954                @Override
9955                public int compare(MemItem lhs, MemItem rhs) {
9956                    if (lhs.pss < rhs.pss) {
9957                        return 1;
9958                    } else if (lhs.pss > rhs.pss) {
9959                        return -1;
9960                    }
9961                    return 0;
9962                }
9963            });
9964        }
9965
9966        for (int i=0; i<items.size(); i++) {
9967            MemItem mi = items.get(i);
9968            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
9969            if (mi.subitems != null) {
9970                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
9971            }
9972        }
9973    }
9974
9975    // These are in KB.
9976    static final long[] DUMP_MEM_BUCKETS = new long[] {
9977        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9978        120*1024, 160*1024, 200*1024,
9979        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9980        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9981    };
9982
9983    static final void appendMemBucket(StringBuilder out, long memKB, String label,
9984            boolean stackLike) {
9985        int start = label.lastIndexOf('.');
9986        if (start >= 0) start++;
9987        else start = 0;
9988        int end = label.length();
9989        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
9990            if (DUMP_MEM_BUCKETS[i] >= memKB) {
9991                long bucket = DUMP_MEM_BUCKETS[i]/1024;
9992                out.append(bucket);
9993                out.append(stackLike ? "MB." : "MB ");
9994                out.append(label, start, end);
9995                return;
9996            }
9997        }
9998        out.append(memKB/1024);
9999        out.append(stackLike ? "MB." : "MB ");
10000        out.append(label, start, end);
10001    }
10002
10003    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10004            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10005            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10006            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10007            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10008    };
10009    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10010            "System", "Persistent", "Foreground",
10011            "Visible", "Perceptible", "Heavy Weight",
10012            "Backup", "A Services", "Home", "Previous",
10013            "B Services", "Background"
10014    };
10015
10016    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10017            PrintWriter pw, String prefix, String[] args, boolean brief,
10018            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10019        boolean dumpAll = false;
10020        boolean oomOnly = false;
10021
10022        int opti = 0;
10023        while (opti < args.length) {
10024            String opt = args[opti];
10025            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10026                break;
10027            }
10028            opti++;
10029            if ("-a".equals(opt)) {
10030                dumpAll = true;
10031            } else if ("--oom".equals(opt)) {
10032                oomOnly = true;
10033            } else if ("-h".equals(opt)) {
10034                pw.println("meminfo dump options: [-a] [--oom] [process]");
10035                pw.println("  -a: include all available information for each process.");
10036                pw.println("  --oom: only show processes organized by oom adj.");
10037                pw.println("If [process] is specified it can be the name or ");
10038                pw.println("pid of a specific process to dump.");
10039                return;
10040            } else {
10041                pw.println("Unknown argument: " + opt + "; use -h for help");
10042            }
10043        }
10044
10045        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10046        if (procs == null) {
10047            return;
10048        }
10049
10050        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10051        long uptime = SystemClock.uptimeMillis();
10052        long realtime = SystemClock.elapsedRealtime();
10053
10054        if (procs.size() == 1 || isCheckinRequest) {
10055            dumpAll = true;
10056        }
10057
10058        if (isCheckinRequest) {
10059            // short checkin version
10060            pw.println(uptime + "," + realtime);
10061            pw.flush();
10062        } else {
10063            pw.println("Applications Memory Usage (kB):");
10064            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10065        }
10066
10067        String[] innerArgs = new String[args.length-opti];
10068        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10069
10070        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10071        long nativePss=0, dalvikPss=0, otherPss=0;
10072        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10073
10074        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10075        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10076                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10077
10078        long totalPss = 0;
10079
10080        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10081            ProcessRecord r = procs.get(i);
10082            if (r.thread != null) {
10083                if (!isCheckinRequest && dumpAll) {
10084                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10085                    pw.flush();
10086                }
10087                Debug.MemoryInfo mi = null;
10088                if (dumpAll) {
10089                    try {
10090                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10091                    } catch (RemoteException e) {
10092                        if (!isCheckinRequest) {
10093                            pw.println("Got RemoteException!");
10094                            pw.flush();
10095                        }
10096                    }
10097                } else {
10098                    mi = new Debug.MemoryInfo();
10099                    Debug.getMemoryInfo(r.pid, mi);
10100                }
10101
10102                if (!isCheckinRequest && mi != null) {
10103                    long myTotalPss = mi.getTotalPss();
10104                    totalPss += myTotalPss;
10105                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10106                            r.processName, myTotalPss, 0);
10107                    procMems.add(pssItem);
10108
10109                    nativePss += mi.nativePss;
10110                    dalvikPss += mi.dalvikPss;
10111                    otherPss += mi.otherPss;
10112                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10113                        long mem = mi.getOtherPss(j);
10114                        miscPss[j] += mem;
10115                        otherPss -= mem;
10116                    }
10117
10118                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10119                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10120                                || oomIndex == (oomPss.length-1)) {
10121                            oomPss[oomIndex] += myTotalPss;
10122                            if (oomProcs[oomIndex] == null) {
10123                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10124                            }
10125                            oomProcs[oomIndex].add(pssItem);
10126                            break;
10127                        }
10128                    }
10129                }
10130            }
10131        }
10132
10133        if (!isCheckinRequest && procs.size() > 1) {
10134            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10135
10136            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10137            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10138            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10139            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10140                String label = Debug.MemoryInfo.getOtherLabel(j);
10141                catMems.add(new MemItem(label, label, miscPss[j], j));
10142            }
10143
10144            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10145            for (int j=0; j<oomPss.length; j++) {
10146                if (oomPss[j] != 0) {
10147                    String label = DUMP_MEM_OOM_LABEL[j];
10148                    MemItem item = new MemItem(label, label, oomPss[j],
10149                            DUMP_MEM_OOM_ADJ[j]);
10150                    item.subitems = oomProcs[j];
10151                    oomMems.add(item);
10152                }
10153            }
10154
10155            if (outTag != null || outStack != null) {
10156                if (outTag != null) {
10157                    appendMemBucket(outTag, totalPss, "total", false);
10158                }
10159                if (outStack != null) {
10160                    appendMemBucket(outStack, totalPss, "total", true);
10161                }
10162                boolean firstLine = true;
10163                for (int i=0; i<oomMems.size(); i++) {
10164                    MemItem miCat = oomMems.get(i);
10165                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10166                        continue;
10167                    }
10168                    if (miCat.id < ProcessList.SERVICE_ADJ
10169                            || miCat.id == ProcessList.HOME_APP_ADJ
10170                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10171                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10172                            outTag.append(" / ");
10173                        }
10174                        if (outStack != null) {
10175                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10176                                if (firstLine) {
10177                                    outStack.append(":");
10178                                    firstLine = false;
10179                                }
10180                                outStack.append("\n\t at ");
10181                            } else {
10182                                outStack.append("$");
10183                            }
10184                        }
10185                        for (int j=0; j<miCat.subitems.size(); j++) {
10186                            MemItem mi = miCat.subitems.get(j);
10187                            if (j > 0) {
10188                                if (outTag != null) {
10189                                    outTag.append(" ");
10190                                }
10191                                if (outStack != null) {
10192                                    outStack.append("$");
10193                                }
10194                            }
10195                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10196                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10197                            }
10198                            if (outStack != null) {
10199                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10200                            }
10201                        }
10202                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10203                            outStack.append("(");
10204                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10205                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10206                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10207                                    outStack.append(":");
10208                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10209                                }
10210                            }
10211                            outStack.append(")");
10212                        }
10213                    }
10214                }
10215            }
10216
10217            if (!brief && !oomOnly) {
10218                pw.println();
10219                pw.println("Total PSS by process:");
10220                dumpMemItems(pw, "  ", procMems, true);
10221                pw.println();
10222            }
10223            pw.println("Total PSS by OOM adjustment:");
10224            dumpMemItems(pw, "  ", oomMems, false);
10225            if (!oomOnly) {
10226                PrintWriter out = categoryPw != null ? categoryPw : pw;
10227                out.println();
10228                out.println("Total PSS by category:");
10229                dumpMemItems(out, "  ", catMems, true);
10230            }
10231            pw.println();
10232            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10233            final int[] SINGLE_LONG_FORMAT = new int[] {
10234                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10235            };
10236            long[] longOut = new long[1];
10237            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10238                    SINGLE_LONG_FORMAT, null, longOut, null);
10239            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10240            longOut[0] = 0;
10241            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10242                    SINGLE_LONG_FORMAT, null, longOut, null);
10243            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10244            longOut[0] = 0;
10245            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10246                    SINGLE_LONG_FORMAT, null, longOut, null);
10247            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10248            longOut[0] = 0;
10249            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10250                    SINGLE_LONG_FORMAT, null, longOut, null);
10251            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10252            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10253                    pw.print(shared); pw.println(" kB");
10254            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10255                    pw.print(voltile); pw.println(" kB volatile");
10256        }
10257    }
10258
10259    /**
10260     * Searches array of arguments for the specified string
10261     * @param args array of argument strings
10262     * @param value value to search for
10263     * @return true if the value is contained in the array
10264     */
10265    private static boolean scanArgs(String[] args, String value) {
10266        if (args != null) {
10267            for (String arg : args) {
10268                if (value.equals(arg)) {
10269                    return true;
10270                }
10271            }
10272        }
10273        return false;
10274    }
10275
10276    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10277            ContentProviderRecord cpr, boolean always) {
10278        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10279
10280        if (!inLaunching || always) {
10281            synchronized (cpr) {
10282                cpr.launchingApp = null;
10283                cpr.notifyAll();
10284            }
10285            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10286            String names[] = cpr.info.authority.split(";");
10287            for (int j = 0; j < names.length; j++) {
10288                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10289            }
10290        }
10291
10292        for (int i=0; i<cpr.connections.size(); i++) {
10293            ContentProviderConnection conn = cpr.connections.get(i);
10294            if (conn.waiting) {
10295                // If this connection is waiting for the provider, then we don't
10296                // need to mess with its process unless we are always removing
10297                // or for some reason the provider is not currently launching.
10298                if (inLaunching && !always) {
10299                    continue;
10300                }
10301            }
10302            ProcessRecord capp = conn.client;
10303            conn.dead = true;
10304            if (conn.stableCount > 0) {
10305                if (!capp.persistent && capp.thread != null
10306                        && capp.pid != 0
10307                        && capp.pid != MY_PID) {
10308                    Slog.i(TAG, "Kill " + capp.processName
10309                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10310                            + " in dying process " + (proc != null ? proc.processName : "??"));
10311                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10312                            capp.processName, capp.setAdj, "dying provider "
10313                                    + cpr.name.toShortString());
10314                    Process.killProcessQuiet(capp.pid);
10315                }
10316            } else if (capp.thread != null && conn.provider.provider != null) {
10317                try {
10318                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10319                } catch (RemoteException e) {
10320                }
10321                // In the protocol here, we don't expect the client to correctly
10322                // clean up this connection, we'll just remove it.
10323                cpr.connections.remove(i);
10324                conn.client.conProviders.remove(conn);
10325            }
10326        }
10327
10328        if (inLaunching && always) {
10329            mLaunchingProviders.remove(cpr);
10330        }
10331        return inLaunching;
10332    }
10333
10334    /**
10335     * Main code for cleaning up a process when it has gone away.  This is
10336     * called both as a result of the process dying, or directly when stopping
10337     * a process when running in single process mode.
10338     */
10339    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10340            boolean restarting, boolean allowRestart, int index) {
10341        if (index >= 0) {
10342            mLruProcesses.remove(index);
10343        }
10344
10345        mProcessesToGc.remove(app);
10346
10347        // Dismiss any open dialogs.
10348        if (app.crashDialog != null) {
10349            app.crashDialog.dismiss();
10350            app.crashDialog = null;
10351        }
10352        if (app.anrDialog != null) {
10353            app.anrDialog.dismiss();
10354            app.anrDialog = null;
10355        }
10356        if (app.waitDialog != null) {
10357            app.waitDialog.dismiss();
10358            app.waitDialog = null;
10359        }
10360
10361        app.crashing = false;
10362        app.notResponding = false;
10363
10364        app.resetPackageList();
10365        app.unlinkDeathRecipient();
10366        app.thread = null;
10367        app.forcingToForeground = null;
10368        app.foregroundServices = false;
10369        app.foregroundActivities = false;
10370        app.hasShownUi = false;
10371        app.hasAboveClient = false;
10372
10373        mServices.killServicesLocked(app, allowRestart);
10374
10375        boolean restart = false;
10376
10377        // Remove published content providers.
10378        if (!app.pubProviders.isEmpty()) {
10379            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10380            while (it.hasNext()) {
10381                ContentProviderRecord cpr = it.next();
10382
10383                final boolean always = app.bad || !allowRestart;
10384                if (removeDyingProviderLocked(app, cpr, always) || always) {
10385                    // We left the provider in the launching list, need to
10386                    // restart it.
10387                    restart = true;
10388                }
10389
10390                cpr.provider = null;
10391                cpr.proc = null;
10392            }
10393            app.pubProviders.clear();
10394        }
10395
10396        // Take care of any launching providers waiting for this process.
10397        if (checkAppInLaunchingProvidersLocked(app, false)) {
10398            restart = true;
10399        }
10400
10401        // Unregister from connected content providers.
10402        if (!app.conProviders.isEmpty()) {
10403            for (int i=0; i<app.conProviders.size(); i++) {
10404                ContentProviderConnection conn = app.conProviders.get(i);
10405                conn.provider.connections.remove(conn);
10406            }
10407            app.conProviders.clear();
10408        }
10409
10410        // At this point there may be remaining entries in mLaunchingProviders
10411        // where we were the only one waiting, so they are no longer of use.
10412        // Look for these and clean up if found.
10413        // XXX Commented out for now.  Trying to figure out a way to reproduce
10414        // the actual situation to identify what is actually going on.
10415        if (false) {
10416            for (int i=0; i<mLaunchingProviders.size(); i++) {
10417                ContentProviderRecord cpr = (ContentProviderRecord)
10418                        mLaunchingProviders.get(i);
10419                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10420                    synchronized (cpr) {
10421                        cpr.launchingApp = null;
10422                        cpr.notifyAll();
10423                    }
10424                }
10425            }
10426        }
10427
10428        skipCurrentReceiverLocked(app);
10429
10430        // Unregister any receivers.
10431        if (app.receivers.size() > 0) {
10432            Iterator<ReceiverList> it = app.receivers.iterator();
10433            while (it.hasNext()) {
10434                removeReceiverLocked(it.next());
10435            }
10436            app.receivers.clear();
10437        }
10438
10439        // If the app is undergoing backup, tell the backup manager about it
10440        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10441            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10442            try {
10443                IBackupManager bm = IBackupManager.Stub.asInterface(
10444                        ServiceManager.getService(Context.BACKUP_SERVICE));
10445                bm.agentDisconnected(app.info.packageName);
10446            } catch (RemoteException e) {
10447                // can't happen; backup manager is local
10448            }
10449        }
10450
10451        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10452            ProcessChangeItem item = mPendingProcessChanges.get(i);
10453            if (item.pid == app.pid) {
10454                mPendingProcessChanges.remove(i);
10455                mAvailProcessChanges.add(item);
10456            }
10457        }
10458        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10459
10460        // If the caller is restarting this app, then leave it in its
10461        // current lists and let the caller take care of it.
10462        if (restarting) {
10463            return;
10464        }
10465
10466        if (!app.persistent || app.isolated) {
10467            if (DEBUG_PROCESSES) Slog.v(TAG,
10468                    "Removing non-persistent process during cleanup: " + app);
10469            mProcessNames.remove(app.processName, app.uid);
10470            mIsolatedProcesses.remove(app.uid);
10471            if (mHeavyWeightProcess == app) {
10472                mHeavyWeightProcess = null;
10473                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10474            }
10475        } else if (!app.removed) {
10476            // This app is persistent, so we need to keep its record around.
10477            // If it is not already on the pending app list, add it there
10478            // and start a new process for it.
10479            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10480                mPersistentStartingProcesses.add(app);
10481                restart = true;
10482            }
10483        }
10484        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10485                "Clean-up removing on hold: " + app);
10486        mProcessesOnHold.remove(app);
10487
10488        if (app == mHomeProcess) {
10489            mHomeProcess = null;
10490        }
10491        if (app == mPreviousProcess) {
10492            mPreviousProcess = null;
10493        }
10494
10495        if (restart && !app.isolated) {
10496            // We have components that still need to be running in the
10497            // process, so re-launch it.
10498            mProcessNames.put(app.processName, app.uid, app);
10499            startProcessLocked(app, "restart", app.processName);
10500        } else if (app.pid > 0 && app.pid != MY_PID) {
10501            // Goodbye!
10502            synchronized (mPidsSelfLocked) {
10503                mPidsSelfLocked.remove(app.pid);
10504                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10505            }
10506            app.setPid(0);
10507        }
10508    }
10509
10510    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10511        // Look through the content providers we are waiting to have launched,
10512        // and if any run in this process then either schedule a restart of
10513        // the process or kill the client waiting for it if this process has
10514        // gone bad.
10515        int NL = mLaunchingProviders.size();
10516        boolean restart = false;
10517        for (int i=0; i<NL; i++) {
10518            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10519            if (cpr.launchingApp == app) {
10520                if (!alwaysBad && !app.bad) {
10521                    restart = true;
10522                } else {
10523                    removeDyingProviderLocked(app, cpr, true);
10524                    NL = mLaunchingProviders.size();
10525                }
10526            }
10527        }
10528        return restart;
10529    }
10530
10531    // =========================================================
10532    // SERVICES
10533    // =========================================================
10534
10535    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10536            int flags) {
10537        enforceNotIsolatedCaller("getServices");
10538        synchronized (this) {
10539            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10540        }
10541    }
10542
10543    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10544        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10545        synchronized (this) {
10546            return mServices.getRunningServiceControlPanelLocked(name);
10547        }
10548    }
10549
10550    public ComponentName startService(IApplicationThread caller, Intent service,
10551            String resolvedType) {
10552        enforceNotIsolatedCaller("startService");
10553        // Refuse possible leaked file descriptors
10554        if (service != null && service.hasFileDescriptors() == true) {
10555            throw new IllegalArgumentException("File descriptors passed in Intent");
10556        }
10557
10558        if (DEBUG_SERVICE)
10559            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10560        synchronized(this) {
10561            final int callingPid = Binder.getCallingPid();
10562            final int callingUid = Binder.getCallingUid();
10563            final long origId = Binder.clearCallingIdentity();
10564            ComponentName res = mServices.startServiceLocked(caller, service,
10565                    resolvedType, callingPid, callingUid);
10566            Binder.restoreCallingIdentity(origId);
10567            return res;
10568        }
10569    }
10570
10571    ComponentName startServiceInPackage(int uid,
10572            Intent service, String resolvedType) {
10573        synchronized(this) {
10574            if (DEBUG_SERVICE)
10575                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10576            final long origId = Binder.clearCallingIdentity();
10577            ComponentName res = mServices.startServiceLocked(null, service,
10578                    resolvedType, -1, uid);
10579            Binder.restoreCallingIdentity(origId);
10580            return res;
10581        }
10582    }
10583
10584    public int stopService(IApplicationThread caller, Intent service,
10585            String resolvedType) {
10586        enforceNotIsolatedCaller("stopService");
10587        // Refuse possible leaked file descriptors
10588        if (service != null && service.hasFileDescriptors() == true) {
10589            throw new IllegalArgumentException("File descriptors passed in Intent");
10590        }
10591
10592        synchronized(this) {
10593            return mServices.stopServiceLocked(caller, service, resolvedType);
10594        }
10595    }
10596
10597    public IBinder peekService(Intent service, String resolvedType) {
10598        enforceNotIsolatedCaller("peekService");
10599        // Refuse possible leaked file descriptors
10600        if (service != null && service.hasFileDescriptors() == true) {
10601            throw new IllegalArgumentException("File descriptors passed in Intent");
10602        }
10603        synchronized(this) {
10604            return mServices.peekServiceLocked(service, resolvedType);
10605        }
10606    }
10607
10608    public boolean stopServiceToken(ComponentName className, IBinder token,
10609            int startId) {
10610        synchronized(this) {
10611            return mServices.stopServiceTokenLocked(className, token, startId);
10612        }
10613    }
10614
10615    public void setServiceForeground(ComponentName className, IBinder token,
10616            int id, Notification notification, boolean removeNotification) {
10617        synchronized(this) {
10618            mServices.setServiceForegroundLocked(className, token, id, notification,
10619                    removeNotification);
10620        }
10621    }
10622
10623    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10624            String className, int flags) {
10625        boolean result = false;
10626        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10627            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10628                if (ActivityManager.checkUidPermission(
10629                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10630                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10631                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10632                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10633                            + " requests FLAG_SINGLE_USER, but app does not hold "
10634                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10635                    Slog.w(TAG, msg);
10636                    throw new SecurityException(msg);
10637                }
10638                result = true;
10639            }
10640        } else if (componentProcessName == aInfo.packageName) {
10641            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10642        } else if ("system".equals(componentProcessName)) {
10643            result = true;
10644        }
10645        if (DEBUG_MU) {
10646            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10647                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10648        }
10649        return result;
10650    }
10651
10652    public int bindService(IApplicationThread caller, IBinder token,
10653            Intent service, String resolvedType,
10654            IServiceConnection connection, int flags, int userId) {
10655        enforceNotIsolatedCaller("bindService");
10656        // Refuse possible leaked file descriptors
10657        if (service != null && service.hasFileDescriptors() == true) {
10658            throw new IllegalArgumentException("File descriptors passed in Intent");
10659        }
10660
10661        checkValidCaller(Binder.getCallingUid(), userId);
10662
10663        synchronized(this) {
10664            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10665                    connection, flags, userId);
10666        }
10667    }
10668
10669    public boolean unbindService(IServiceConnection connection) {
10670        synchronized (this) {
10671            return mServices.unbindServiceLocked(connection);
10672        }
10673    }
10674
10675    public void publishService(IBinder token, Intent intent, IBinder service) {
10676        // Refuse possible leaked file descriptors
10677        if (intent != null && intent.hasFileDescriptors() == true) {
10678            throw new IllegalArgumentException("File descriptors passed in Intent");
10679        }
10680
10681        synchronized(this) {
10682            if (!(token instanceof ServiceRecord)) {
10683                throw new IllegalArgumentException("Invalid service token");
10684            }
10685            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
10686        }
10687    }
10688
10689    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10690        // Refuse possible leaked file descriptors
10691        if (intent != null && intent.hasFileDescriptors() == true) {
10692            throw new IllegalArgumentException("File descriptors passed in Intent");
10693        }
10694
10695        synchronized(this) {
10696            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
10697        }
10698    }
10699
10700    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10701        synchronized(this) {
10702            if (!(token instanceof ServiceRecord)) {
10703                throw new IllegalArgumentException("Invalid service token");
10704            }
10705            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
10706        }
10707    }
10708
10709    // =========================================================
10710    // BACKUP AND RESTORE
10711    // =========================================================
10712
10713    // Cause the target app to be launched if necessary and its backup agent
10714    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10715    // activity manager to announce its creation.
10716    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10717        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10718        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10719
10720        synchronized(this) {
10721            // !!! TODO: currently no check here that we're already bound
10722            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10723            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10724            synchronized (stats) {
10725                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10726            }
10727
10728            // Backup agent is now in use, its package can't be stopped.
10729            try {
10730                AppGlobals.getPackageManager().setPackageStoppedState(
10731                        app.packageName, false, UserHandle.getUserId(app.uid));
10732            } catch (RemoteException e) {
10733            } catch (IllegalArgumentException e) {
10734                Slog.w(TAG, "Failed trying to unstop package "
10735                        + app.packageName + ": " + e);
10736            }
10737
10738            BackupRecord r = new BackupRecord(ss, app, backupMode);
10739            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10740                    ? new ComponentName(app.packageName, app.backupAgentName)
10741                    : new ComponentName("android", "FullBackupAgent");
10742            // startProcessLocked() returns existing proc's record if it's already running
10743            ProcessRecord proc = startProcessLocked(app.processName, app,
10744                    false, 0, "backup", hostingName, false, false);
10745            if (proc == null) {
10746                Slog.e(TAG, "Unable to start backup agent process " + r);
10747                return false;
10748            }
10749
10750            r.app = proc;
10751            mBackupTarget = r;
10752            mBackupAppName = app.packageName;
10753
10754            // Try not to kill the process during backup
10755            updateOomAdjLocked(proc);
10756
10757            // If the process is already attached, schedule the creation of the backup agent now.
10758            // If it is not yet live, this will be done when it attaches to the framework.
10759            if (proc.thread != null) {
10760                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
10761                try {
10762                    proc.thread.scheduleCreateBackupAgent(app,
10763                            compatibilityInfoForPackageLocked(app), backupMode);
10764                } catch (RemoteException e) {
10765                    // Will time out on the backup manager side
10766                }
10767            } else {
10768                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
10769            }
10770            // Invariants: at this point, the target app process exists and the application
10771            // is either already running or in the process of coming up.  mBackupTarget and
10772            // mBackupAppName describe the app, so that when it binds back to the AM we
10773            // know that it's scheduled for a backup-agent operation.
10774        }
10775
10776        return true;
10777    }
10778
10779    // A backup agent has just come up
10780    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10781        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
10782                + " = " + agent);
10783
10784        synchronized(this) {
10785            if (!agentPackageName.equals(mBackupAppName)) {
10786                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10787                return;
10788            }
10789        }
10790
10791        long oldIdent = Binder.clearCallingIdentity();
10792        try {
10793            IBackupManager bm = IBackupManager.Stub.asInterface(
10794                    ServiceManager.getService(Context.BACKUP_SERVICE));
10795            bm.agentConnected(agentPackageName, agent);
10796        } catch (RemoteException e) {
10797            // can't happen; the backup manager service is local
10798        } catch (Exception e) {
10799            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10800            e.printStackTrace();
10801        } finally {
10802            Binder.restoreCallingIdentity(oldIdent);
10803        }
10804    }
10805
10806    // done with this agent
10807    public void unbindBackupAgent(ApplicationInfo appInfo) {
10808        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
10809        if (appInfo == null) {
10810            Slog.w(TAG, "unbind backup agent for null app");
10811            return;
10812        }
10813
10814        synchronized(this) {
10815            if (mBackupAppName == null) {
10816                Slog.w(TAG, "Unbinding backup agent with no active backup");
10817                return;
10818            }
10819
10820            if (!mBackupAppName.equals(appInfo.packageName)) {
10821                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
10822                return;
10823            }
10824
10825            ProcessRecord proc = mBackupTarget.app;
10826            mBackupTarget = null;
10827            mBackupAppName = null;
10828
10829            // Not backing this app up any more; reset its OOM adjustment
10830            updateOomAdjLocked(proc);
10831
10832            // If the app crashed during backup, 'thread' will be null here
10833            if (proc.thread != null) {
10834                try {
10835                    proc.thread.scheduleDestroyBackupAgent(appInfo,
10836                            compatibilityInfoForPackageLocked(appInfo));
10837                } catch (Exception e) {
10838                    Slog.e(TAG, "Exception when unbinding backup agent:");
10839                    e.printStackTrace();
10840                }
10841            }
10842        }
10843    }
10844    // =========================================================
10845    // BROADCASTS
10846    // =========================================================
10847
10848    private final List getStickiesLocked(String action, IntentFilter filter,
10849            List cur) {
10850        final ContentResolver resolver = mContext.getContentResolver();
10851        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10852        if (list == null) {
10853            return cur;
10854        }
10855        int N = list.size();
10856        for (int i=0; i<N; i++) {
10857            Intent intent = list.get(i);
10858            if (filter.match(resolver, intent, true, TAG) >= 0) {
10859                if (cur == null) {
10860                    cur = new ArrayList<Intent>();
10861                }
10862                cur.add(intent);
10863            }
10864        }
10865        return cur;
10866    }
10867
10868    boolean isPendingBroadcastProcessLocked(int pid) {
10869        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
10870                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
10871    }
10872
10873    void skipPendingBroadcastLocked(int pid) {
10874            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
10875            for (BroadcastQueue queue : mBroadcastQueues) {
10876                queue.skipPendingBroadcastLocked(pid);
10877            }
10878    }
10879
10880    // The app just attached; send any pending broadcasts that it should receive
10881    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
10882        boolean didSomething = false;
10883        for (BroadcastQueue queue : mBroadcastQueues) {
10884            didSomething |= queue.sendPendingBroadcastsLocked(app);
10885        }
10886        return didSomething;
10887    }
10888
10889    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
10890            IIntentReceiver receiver, IntentFilter filter, String permission) {
10891        enforceNotIsolatedCaller("registerReceiver");
10892        int callingUid;
10893        synchronized(this) {
10894            ProcessRecord callerApp = null;
10895            if (caller != null) {
10896                callerApp = getRecordForAppLocked(caller);
10897                if (callerApp == null) {
10898                    throw new SecurityException(
10899                            "Unable to find app for caller " + caller
10900                            + " (pid=" + Binder.getCallingPid()
10901                            + ") when registering receiver " + receiver);
10902                }
10903                if (callerApp.info.uid != Process.SYSTEM_UID &&
10904                        !callerApp.pkgList.contains(callerPackage)) {
10905                    throw new SecurityException("Given caller package " + callerPackage
10906                            + " is not running in process " + callerApp);
10907                }
10908                callingUid = callerApp.info.uid;
10909            } else {
10910                callerPackage = null;
10911                callingUid = Binder.getCallingUid();
10912            }
10913
10914            List allSticky = null;
10915
10916            // Look for any matching sticky broadcasts...
10917            Iterator actions = filter.actionsIterator();
10918            if (actions != null) {
10919                while (actions.hasNext()) {
10920                    String action = (String)actions.next();
10921                    allSticky = getStickiesLocked(action, filter, allSticky);
10922                }
10923            } else {
10924                allSticky = getStickiesLocked(null, filter, allSticky);
10925            }
10926
10927            // The first sticky in the list is returned directly back to
10928            // the client.
10929            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10930
10931            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
10932                    + ": " + sticky);
10933
10934            if (receiver == null) {
10935                return sticky;
10936            }
10937
10938            ReceiverList rl
10939                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10940            if (rl == null) {
10941                rl = new ReceiverList(this, callerApp,
10942                        Binder.getCallingPid(),
10943                        Binder.getCallingUid(), receiver);
10944                if (rl.app != null) {
10945                    rl.app.receivers.add(rl);
10946                } else {
10947                    try {
10948                        receiver.asBinder().linkToDeath(rl, 0);
10949                    } catch (RemoteException e) {
10950                        return sticky;
10951                    }
10952                    rl.linkedToDeath = true;
10953                }
10954                mRegisteredReceivers.put(receiver.asBinder(), rl);
10955            }
10956            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
10957                    permission, callingUid);
10958            rl.add(bf);
10959            if (!bf.debugCheck()) {
10960                Slog.w(TAG, "==> For Dynamic broadast");
10961            }
10962            mReceiverResolver.addFilter(bf);
10963
10964            // Enqueue broadcasts for all existing stickies that match
10965            // this filter.
10966            if (allSticky != null) {
10967                ArrayList receivers = new ArrayList();
10968                receivers.add(bf);
10969
10970                int N = allSticky.size();
10971                for (int i=0; i<N; i++) {
10972                    Intent intent = (Intent)allSticky.get(i);
10973                    BroadcastQueue queue = broadcastQueueForIntent(intent);
10974                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
10975                            null, -1, -1, null, receivers, null, 0, null, null,
10976                            false, true, true, false);
10977                    queue.enqueueParallelBroadcastLocked(r);
10978                    queue.scheduleBroadcastsLocked();
10979                }
10980            }
10981
10982            return sticky;
10983        }
10984    }
10985
10986    public void unregisterReceiver(IIntentReceiver receiver) {
10987        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
10988
10989        final long origId = Binder.clearCallingIdentity();
10990        try {
10991            boolean doTrim = false;
10992
10993            synchronized(this) {
10994                ReceiverList rl
10995                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10996                if (rl != null) {
10997                    if (rl.curBroadcast != null) {
10998                        BroadcastRecord r = rl.curBroadcast;
10999                        final boolean doNext = finishReceiverLocked(
11000                                receiver.asBinder(), r.resultCode, r.resultData,
11001                                r.resultExtras, r.resultAbort, true);
11002                        if (doNext) {
11003                            doTrim = true;
11004                            r.queue.processNextBroadcast(false);
11005                        }
11006                    }
11007
11008                    if (rl.app != null) {
11009                        rl.app.receivers.remove(rl);
11010                    }
11011                    removeReceiverLocked(rl);
11012                    if (rl.linkedToDeath) {
11013                        rl.linkedToDeath = false;
11014                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11015                    }
11016                }
11017            }
11018
11019            // If we actually concluded any broadcasts, we might now be able
11020            // to trim the recipients' apps from our working set
11021            if (doTrim) {
11022                trimApplications();
11023                return;
11024            }
11025
11026        } finally {
11027            Binder.restoreCallingIdentity(origId);
11028        }
11029    }
11030
11031    void removeReceiverLocked(ReceiverList rl) {
11032        mRegisteredReceivers.remove(rl.receiver.asBinder());
11033        int N = rl.size();
11034        for (int i=0; i<N; i++) {
11035            mReceiverResolver.removeFilter(rl.get(i));
11036        }
11037    }
11038
11039    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11040        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11041            ProcessRecord r = mLruProcesses.get(i);
11042            if (r.thread != null) {
11043                try {
11044                    r.thread.dispatchPackageBroadcast(cmd, packages);
11045                } catch (RemoteException ex) {
11046                }
11047            }
11048        }
11049    }
11050
11051    private final int broadcastIntentLocked(ProcessRecord callerApp,
11052            String callerPackage, Intent intent, String resolvedType,
11053            IIntentReceiver resultTo, int resultCode, String resultData,
11054            Bundle map, String requiredPermission,
11055            boolean ordered, boolean sticky, int callingPid, int callingUid,
11056            int userId) {
11057        intent = new Intent(intent);
11058
11059        // By default broadcasts do not go to stopped apps.
11060        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11061
11062        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11063            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11064            + " ordered=" + ordered + " userid=" + userId);
11065        if ((resultTo != null) && !ordered) {
11066            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11067        }
11068
11069        boolean onlySendToCaller = false;
11070
11071        // If the caller is trying to send this broadcast to a different
11072        // user, verify that is allowed.
11073        if (UserHandle.getUserId(callingUid) != userId) {
11074            if (checkComponentPermission(
11075                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
11076                    callingPid, callingUid, -1, true)
11077                    != PackageManager.PERMISSION_GRANTED) {
11078                if (checkComponentPermission(
11079                        android.Manifest.permission.INTERACT_ACROSS_USERS,
11080                        callingPid, callingUid, -1, true)
11081                        == PackageManager.PERMISSION_GRANTED) {
11082                    onlySendToCaller = true;
11083                } else {
11084                    String msg = "Permission Denial: " + intent.getAction()
11085                            + " broadcast from " + callerPackage
11086                            + " asks to send as user " + userId
11087                            + " but is calling from user " + UserHandle.getUserId(callingUid)
11088                            + "; this requires "
11089                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
11090                    Slog.w(TAG, msg);
11091                    throw new SecurityException(msg);
11092                }
11093            }
11094        }
11095
11096        // Handle special intents: if this broadcast is from the package
11097        // manager about a package being removed, we need to remove all of
11098        // its activities from the history stack.
11099        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11100                intent.getAction());
11101        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11102                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11103                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11104                || uidRemoved) {
11105            if (checkComponentPermission(
11106                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11107                    callingPid, callingUid, -1, true)
11108                    == PackageManager.PERMISSION_GRANTED) {
11109                if (uidRemoved) {
11110                    final Bundle intentExtras = intent.getExtras();
11111                    final int uid = intentExtras != null
11112                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11113                    if (uid >= 0) {
11114                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11115                        synchronized (bs) {
11116                            bs.removeUidStatsLocked(uid);
11117                        }
11118                    }
11119                } else {
11120                    // If resources are unvailble just force stop all
11121                    // those packages and flush the attribute cache as well.
11122                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11123                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11124                        if (list != null && (list.length > 0)) {
11125                            for (String pkg : list) {
11126                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11127                            }
11128                            sendPackageBroadcastLocked(
11129                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
11130                        }
11131                    } else {
11132                        Uri data = intent.getData();
11133                        String ssp;
11134                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11135                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11136                                forceStopPackageLocked(ssp,
11137                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11138                                        false, userId);
11139                            }
11140                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11141                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11142                                        new String[] {ssp});
11143                            }
11144                        }
11145                    }
11146                }
11147            } else {
11148                String msg = "Permission Denial: " + intent.getAction()
11149                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11150                        + ", uid=" + callingUid + ")"
11151                        + " requires "
11152                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11153                Slog.w(TAG, msg);
11154                throw new SecurityException(msg);
11155            }
11156
11157        // Special case for adding a package: by default turn on compatibility
11158        // mode.
11159        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11160            Uri data = intent.getData();
11161            String ssp;
11162            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11163                mCompatModePackages.handlePackageAddedLocked(ssp,
11164                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11165            }
11166        }
11167
11168        /*
11169         * If this is the time zone changed action, queue up a message that will reset the timezone
11170         * of all currently running processes. This message will get queued up before the broadcast
11171         * happens.
11172         */
11173        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11174            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11175        }
11176
11177        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11178            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11179        }
11180
11181        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11182            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11183            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11184        }
11185
11186        /*
11187         * Prevent non-system code (defined here to be non-persistent
11188         * processes) from sending protected broadcasts.
11189         */
11190        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11191            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11192            callingUid == 0) {
11193            // Always okay.
11194        } else if (callerApp == null || !callerApp.persistent) {
11195            try {
11196                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11197                        intent.getAction())) {
11198                    String msg = "Permission Denial: not allowed to send broadcast "
11199                            + intent.getAction() + " from pid="
11200                            + callingPid + ", uid=" + callingUid;
11201                    Slog.w(TAG, msg);
11202                    throw new SecurityException(msg);
11203                }
11204            } catch (RemoteException e) {
11205                Slog.w(TAG, "Remote exception", e);
11206                return ActivityManager.BROADCAST_SUCCESS;
11207            }
11208        }
11209
11210        // Add to the sticky list if requested.
11211        if (sticky) {
11212            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11213                    callingPid, callingUid)
11214                    != PackageManager.PERMISSION_GRANTED) {
11215                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11216                        + callingPid + ", uid=" + callingUid
11217                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11218                Slog.w(TAG, msg);
11219                throw new SecurityException(msg);
11220            }
11221            if (requiredPermission != null) {
11222                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11223                        + " and enforce permission " + requiredPermission);
11224                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11225            }
11226            if (intent.getComponent() != null) {
11227                throw new SecurityException(
11228                        "Sticky broadcasts can't target a specific component");
11229            }
11230            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11231            if (list == null) {
11232                list = new ArrayList<Intent>();
11233                mStickyBroadcasts.put(intent.getAction(), list);
11234            }
11235            int N = list.size();
11236            int i;
11237            for (i=0; i<N; i++) {
11238                if (intent.filterEquals(list.get(i))) {
11239                    // This sticky already exists, replace it.
11240                    list.set(i, new Intent(intent));
11241                    break;
11242                }
11243            }
11244            if (i >= N) {
11245                list.add(new Intent(intent));
11246            }
11247        }
11248
11249        // Figure out who all will receive this broadcast.
11250        List receivers = null;
11251        List<BroadcastFilter> registeredReceivers = null;
11252        try {
11253            // Need to resolve the intent to interested receivers...
11254            if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11255                     == 0) {
11256                receivers = AppGlobals.getPackageManager().queryIntentReceivers(
11257                        intent, resolvedType, STOCK_PM_FLAGS, userId);
11258            }
11259            if (intent.getComponent() == null) {
11260                registeredReceivers = mReceiverResolver.queryIntent(intent,
11261                        resolvedType, false, userId);
11262            }
11263        } catch (RemoteException ex) {
11264            // pm is in same process, this will never happen.
11265        }
11266
11267        final boolean replacePending =
11268                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11269
11270        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11271                + " replacePending=" + replacePending);
11272
11273        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11274        if (!ordered && NR > 0) {
11275            // If we are not serializing this broadcast, then send the
11276            // registered receivers separately so they don't wait for the
11277            // components to be launched.
11278            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11279            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11280                    callerPackage, callingPid, callingUid, requiredPermission,
11281                    registeredReceivers, resultTo, resultCode, resultData, map,
11282                    ordered, sticky, false, onlySendToCaller);
11283            if (DEBUG_BROADCAST) Slog.v(
11284                    TAG, "Enqueueing parallel broadcast " + r);
11285            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11286            if (!replaced) {
11287                queue.enqueueParallelBroadcastLocked(r);
11288                queue.scheduleBroadcastsLocked();
11289            }
11290            registeredReceivers = null;
11291            NR = 0;
11292        }
11293
11294        // Merge into one list.
11295        int ir = 0;
11296        if (receivers != null) {
11297            // A special case for PACKAGE_ADDED: do not allow the package
11298            // being added to see this broadcast.  This prevents them from
11299            // using this as a back door to get run as soon as they are
11300            // installed.  Maybe in the future we want to have a special install
11301            // broadcast or such for apps, but we'd like to deliberately make
11302            // this decision.
11303            String skipPackages[] = null;
11304            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11305                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11306                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11307                Uri data = intent.getData();
11308                if (data != null) {
11309                    String pkgName = data.getSchemeSpecificPart();
11310                    if (pkgName != null) {
11311                        skipPackages = new String[] { pkgName };
11312                    }
11313                }
11314            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11315                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11316            }
11317            if (skipPackages != null && (skipPackages.length > 0)) {
11318                for (String skipPackage : skipPackages) {
11319                    if (skipPackage != null) {
11320                        int NT = receivers.size();
11321                        for (int it=0; it<NT; it++) {
11322                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11323                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11324                                receivers.remove(it);
11325                                it--;
11326                                NT--;
11327                            }
11328                        }
11329                    }
11330                }
11331            }
11332
11333            int NT = receivers != null ? receivers.size() : 0;
11334            int it = 0;
11335            ResolveInfo curt = null;
11336            BroadcastFilter curr = null;
11337            while (it < NT && ir < NR) {
11338                if (curt == null) {
11339                    curt = (ResolveInfo)receivers.get(it);
11340                }
11341                if (curr == null) {
11342                    curr = registeredReceivers.get(ir);
11343                }
11344                if (curr.getPriority() >= curt.priority) {
11345                    // Insert this broadcast record into the final list.
11346                    receivers.add(it, curr);
11347                    ir++;
11348                    curr = null;
11349                    it++;
11350                    NT++;
11351                } else {
11352                    // Skip to the next ResolveInfo in the final list.
11353                    it++;
11354                    curt = null;
11355                }
11356            }
11357        }
11358        while (ir < NR) {
11359            if (receivers == null) {
11360                receivers = new ArrayList();
11361            }
11362            receivers.add(registeredReceivers.get(ir));
11363            ir++;
11364        }
11365
11366        if ((receivers != null && receivers.size() > 0)
11367                || resultTo != null) {
11368            BroadcastQueue queue = broadcastQueueForIntent(intent);
11369            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11370                    callerPackage, callingPid, callingUid, requiredPermission,
11371                    receivers, resultTo, resultCode, resultData, map, ordered,
11372                    sticky, false, onlySendToCaller);
11373            if (DEBUG_BROADCAST) Slog.v(
11374                    TAG, "Enqueueing ordered broadcast " + r
11375                    + ": prev had " + queue.mOrderedBroadcasts.size());
11376            if (DEBUG_BROADCAST) {
11377                int seq = r.intent.getIntExtra("seq", -1);
11378                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11379            }
11380            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11381            if (!replaced) {
11382                queue.enqueueOrderedBroadcastLocked(r);
11383                queue.scheduleBroadcastsLocked();
11384            }
11385        }
11386
11387        return ActivityManager.BROADCAST_SUCCESS;
11388    }
11389
11390    final Intent verifyBroadcastLocked(Intent intent) {
11391        // Refuse possible leaked file descriptors
11392        if (intent != null && intent.hasFileDescriptors() == true) {
11393            throw new IllegalArgumentException("File descriptors passed in Intent");
11394        }
11395
11396        int flags = intent.getFlags();
11397
11398        if (!mProcessesReady) {
11399            // if the caller really truly claims to know what they're doing, go
11400            // ahead and allow the broadcast without launching any receivers
11401            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11402                intent = new Intent(intent);
11403                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11404            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11405                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11406                        + " before boot completion");
11407                throw new IllegalStateException("Cannot broadcast before boot completed");
11408            }
11409        }
11410
11411        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11412            throw new IllegalArgumentException(
11413                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11414        }
11415
11416        return intent;
11417    }
11418
11419    public final int broadcastIntent(IApplicationThread caller,
11420            Intent intent, String resolvedType, IIntentReceiver resultTo,
11421            int resultCode, String resultData, Bundle map,
11422            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11423        enforceNotIsolatedCaller("broadcastIntent");
11424        synchronized(this) {
11425            intent = verifyBroadcastLocked(intent);
11426
11427            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11428            final int callingPid = Binder.getCallingPid();
11429            final int callingUid = Binder.getCallingUid();
11430            final long origId = Binder.clearCallingIdentity();
11431            int res = broadcastIntentLocked(callerApp,
11432                    callerApp != null ? callerApp.info.packageName : null,
11433                    intent, resolvedType, resultTo,
11434                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11435                    callingPid, callingUid, userId);
11436            Binder.restoreCallingIdentity(origId);
11437            return res;
11438        }
11439    }
11440
11441    int broadcastIntentInPackage(String packageName, int uid,
11442            Intent intent, String resolvedType, IIntentReceiver resultTo,
11443            int resultCode, String resultData, Bundle map,
11444            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11445        synchronized(this) {
11446            intent = verifyBroadcastLocked(intent);
11447
11448            final long origId = Binder.clearCallingIdentity();
11449            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11450                    resultTo, resultCode, resultData, map, requiredPermission,
11451                    serialized, sticky, -1, uid, userId);
11452            Binder.restoreCallingIdentity(origId);
11453            return res;
11454        }
11455    }
11456
11457    // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
11458    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11459        // Refuse possible leaked file descriptors
11460        if (intent != null && intent.hasFileDescriptors() == true) {
11461            throw new IllegalArgumentException("File descriptors passed in Intent");
11462        }
11463
11464        synchronized(this) {
11465            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11466                    != PackageManager.PERMISSION_GRANTED) {
11467                String msg = "Permission Denial: unbroadcastIntent() from pid="
11468                        + Binder.getCallingPid()
11469                        + ", uid=" + Binder.getCallingUid()
11470                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11471                Slog.w(TAG, msg);
11472                throw new SecurityException(msg);
11473            }
11474            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11475            if (list != null) {
11476                int N = list.size();
11477                int i;
11478                for (i=0; i<N; i++) {
11479                    if (intent.filterEquals(list.get(i))) {
11480                        list.remove(i);
11481                        break;
11482                    }
11483                }
11484            }
11485        }
11486    }
11487
11488    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11489            String resultData, Bundle resultExtras, boolean resultAbort,
11490            boolean explicit) {
11491        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11492        if (r == null) {
11493            Slog.w(TAG, "finishReceiver called but not found on queue");
11494            return false;
11495        }
11496
11497        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11498                explicit);
11499    }
11500
11501    public void finishReceiver(IBinder who, int resultCode, String resultData,
11502            Bundle resultExtras, boolean resultAbort) {
11503        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11504
11505        // Refuse possible leaked file descriptors
11506        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11507            throw new IllegalArgumentException("File descriptors passed in Bundle");
11508        }
11509
11510        final long origId = Binder.clearCallingIdentity();
11511        try {
11512            boolean doNext = false;
11513            BroadcastRecord r = null;
11514
11515            synchronized(this) {
11516                r = broadcastRecordForReceiverLocked(who);
11517                if (r != null) {
11518                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11519                        resultData, resultExtras, resultAbort, true);
11520                }
11521            }
11522
11523            if (doNext) {
11524                r.queue.processNextBroadcast(false);
11525            }
11526            trimApplications();
11527        } finally {
11528            Binder.restoreCallingIdentity(origId);
11529        }
11530    }
11531
11532    // =========================================================
11533    // INSTRUMENTATION
11534    // =========================================================
11535
11536    public boolean startInstrumentation(ComponentName className,
11537            String profileFile, int flags, Bundle arguments,
11538            IInstrumentationWatcher watcher) {
11539        enforceNotIsolatedCaller("startInstrumentation");
11540        // Refuse possible leaked file descriptors
11541        if (arguments != null && arguments.hasFileDescriptors()) {
11542            throw new IllegalArgumentException("File descriptors passed in Bundle");
11543        }
11544
11545        synchronized(this) {
11546            InstrumentationInfo ii = null;
11547            ApplicationInfo ai = null;
11548            try {
11549                ii = mContext.getPackageManager().getInstrumentationInfo(
11550                    className, STOCK_PM_FLAGS);
11551                ai = mContext.getPackageManager().getApplicationInfo(
11552                        ii.targetPackage, STOCK_PM_FLAGS);
11553            } catch (PackageManager.NameNotFoundException e) {
11554            }
11555            if (ii == null) {
11556                reportStartInstrumentationFailure(watcher, className,
11557                        "Unable to find instrumentation info for: " + className);
11558                return false;
11559            }
11560            if (ai == null) {
11561                reportStartInstrumentationFailure(watcher, className,
11562                        "Unable to find instrumentation target package: " + ii.targetPackage);
11563                return false;
11564            }
11565
11566            int match = mContext.getPackageManager().checkSignatures(
11567                    ii.targetPackage, ii.packageName);
11568            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11569                String msg = "Permission Denial: starting instrumentation "
11570                        + className + " from pid="
11571                        + Binder.getCallingPid()
11572                        + ", uid=" + Binder.getCallingPid()
11573                        + " not allowed because package " + ii.packageName
11574                        + " does not have a signature matching the target "
11575                        + ii.targetPackage;
11576                reportStartInstrumentationFailure(watcher, className, msg);
11577                throw new SecurityException(msg);
11578            }
11579
11580            int userId = UserHandle.getCallingUserId();
11581            final long origId = Binder.clearCallingIdentity();
11582            // Instrumentation can kill and relaunch even persistent processes
11583            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
11584            ProcessRecord app = addAppLocked(ai, false);
11585            app.instrumentationClass = className;
11586            app.instrumentationInfo = ai;
11587            app.instrumentationProfileFile = profileFile;
11588            app.instrumentationArguments = arguments;
11589            app.instrumentationWatcher = watcher;
11590            app.instrumentationResultClass = className;
11591            Binder.restoreCallingIdentity(origId);
11592        }
11593
11594        return true;
11595    }
11596
11597    /**
11598     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11599     * error to the logs, but if somebody is watching, send the report there too.  This enables
11600     * the "am" command to report errors with more information.
11601     *
11602     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11603     * @param cn The component name of the instrumentation.
11604     * @param report The error report.
11605     */
11606    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11607            ComponentName cn, String report) {
11608        Slog.w(TAG, report);
11609        try {
11610            if (watcher != null) {
11611                Bundle results = new Bundle();
11612                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11613                results.putString("Error", report);
11614                watcher.instrumentationStatus(cn, -1, results);
11615            }
11616        } catch (RemoteException e) {
11617            Slog.w(TAG, e);
11618        }
11619    }
11620
11621    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11622        if (app.instrumentationWatcher != null) {
11623            try {
11624                // NOTE:  IInstrumentationWatcher *must* be oneway here
11625                app.instrumentationWatcher.instrumentationFinished(
11626                    app.instrumentationClass,
11627                    resultCode,
11628                    results);
11629            } catch (RemoteException e) {
11630            }
11631        }
11632        app.instrumentationWatcher = null;
11633        app.instrumentationClass = null;
11634        app.instrumentationInfo = null;
11635        app.instrumentationProfileFile = null;
11636        app.instrumentationArguments = null;
11637
11638        forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId);
11639    }
11640
11641    public void finishInstrumentation(IApplicationThread target,
11642            int resultCode, Bundle results) {
11643        int userId = UserHandle.getCallingUserId();
11644        // Refuse possible leaked file descriptors
11645        if (results != null && results.hasFileDescriptors()) {
11646            throw new IllegalArgumentException("File descriptors passed in Intent");
11647        }
11648
11649        synchronized(this) {
11650            ProcessRecord app = getRecordForAppLocked(target);
11651            if (app == null) {
11652                Slog.w(TAG, "finishInstrumentation: no app for " + target);
11653                return;
11654            }
11655            final long origId = Binder.clearCallingIdentity();
11656            finishInstrumentationLocked(app, resultCode, results);
11657            Binder.restoreCallingIdentity(origId);
11658        }
11659    }
11660
11661    // =========================================================
11662    // CONFIGURATION
11663    // =========================================================
11664
11665    public ConfigurationInfo getDeviceConfigurationInfo() {
11666        ConfigurationInfo config = new ConfigurationInfo();
11667        synchronized (this) {
11668            config.reqTouchScreen = mConfiguration.touchscreen;
11669            config.reqKeyboardType = mConfiguration.keyboard;
11670            config.reqNavigation = mConfiguration.navigation;
11671            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11672                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
11673                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11674            }
11675            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11676                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
11677                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11678            }
11679            config.reqGlEsVersion = GL_ES_VERSION;
11680        }
11681        return config;
11682    }
11683
11684    public Configuration getConfiguration() {
11685        Configuration ci;
11686        synchronized(this) {
11687            ci = new Configuration(mConfiguration);
11688        }
11689        return ci;
11690    }
11691
11692    public void updatePersistentConfiguration(Configuration values) {
11693        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11694                "updateConfiguration()");
11695        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
11696                "updateConfiguration()");
11697        if (values == null) {
11698            throw new NullPointerException("Configuration must not be null");
11699        }
11700
11701        synchronized(this) {
11702            final long origId = Binder.clearCallingIdentity();
11703            updateConfigurationLocked(values, null, true, false);
11704            Binder.restoreCallingIdentity(origId);
11705        }
11706    }
11707
11708    public void updateConfiguration(Configuration values) {
11709        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11710                "updateConfiguration()");
11711
11712        synchronized(this) {
11713            if (values == null && mWindowManager != null) {
11714                // sentinel: fetch the current configuration from the window manager
11715                values = mWindowManager.computeNewConfiguration();
11716            }
11717
11718            if (mWindowManager != null) {
11719                mProcessList.applyDisplaySize(mWindowManager);
11720            }
11721
11722            final long origId = Binder.clearCallingIdentity();
11723            if (values != null) {
11724                Settings.System.clearConfiguration(values);
11725            }
11726            updateConfigurationLocked(values, null, false, false);
11727            Binder.restoreCallingIdentity(origId);
11728        }
11729    }
11730
11731    /**
11732     * Do either or both things: (1) change the current configuration, and (2)
11733     * make sure the given activity is running with the (now) current
11734     * configuration.  Returns true if the activity has been left running, or
11735     * false if <var>starting</var> is being destroyed to match the new
11736     * configuration.
11737     * @param persistent TODO
11738     */
11739    boolean updateConfigurationLocked(Configuration values,
11740            ActivityRecord starting, boolean persistent, boolean initLocale) {
11741        // do nothing if we are headless
11742        if (mHeadless) return true;
11743
11744        int changes = 0;
11745
11746        boolean kept = true;
11747
11748        if (values != null) {
11749            Configuration newConfig = new Configuration(mConfiguration);
11750            changes = newConfig.updateFrom(values);
11751            if (changes != 0) {
11752                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
11753                    Slog.i(TAG, "Updating configuration to: " + values);
11754                }
11755
11756                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
11757
11758                if (values.locale != null && !initLocale) {
11759                    saveLocaleLocked(values.locale,
11760                                     !values.locale.equals(mConfiguration.locale),
11761                                     values.userSetLocale);
11762                }
11763
11764                mConfigurationSeq++;
11765                if (mConfigurationSeq <= 0) {
11766                    mConfigurationSeq = 1;
11767                }
11768                newConfig.seq = mConfigurationSeq;
11769                mConfiguration = newConfig;
11770                Slog.i(TAG, "Config changed: " + newConfig);
11771
11772                final Configuration configCopy = new Configuration(mConfiguration);
11773
11774                // TODO: If our config changes, should we auto dismiss any currently
11775                // showing dialogs?
11776                mShowDialogs = shouldShowDialogs(newConfig);
11777
11778                AttributeCache ac = AttributeCache.instance();
11779                if (ac != null) {
11780                    ac.updateConfiguration(configCopy);
11781                }
11782
11783                // Make sure all resources in our process are updated
11784                // right now, so that anyone who is going to retrieve
11785                // resource values after we return will be sure to get
11786                // the new ones.  This is especially important during
11787                // boot, where the first config change needs to guarantee
11788                // all resources have that config before following boot
11789                // code is executed.
11790                mSystemThread.applyConfigurationToResources(configCopy);
11791
11792                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
11793                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11794                    msg.obj = new Configuration(configCopy);
11795                    mHandler.sendMessage(msg);
11796                }
11797
11798                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11799                    ProcessRecord app = mLruProcesses.get(i);
11800                    try {
11801                        if (app.thread != null) {
11802                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
11803                                    + app.processName + " new config " + mConfiguration);
11804                            app.thread.scheduleConfigurationChanged(configCopy);
11805                        }
11806                    } catch (Exception e) {
11807                    }
11808                }
11809                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
11810                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11811                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
11812                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11813                        null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11814                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
11815                    broadcastIntentLocked(null, null,
11816                            new Intent(Intent.ACTION_LOCALE_CHANGED),
11817                            null, null, 0, null, null,
11818                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11819                }
11820            }
11821        }
11822
11823        if (changes != 0 && starting == null) {
11824            // If the configuration changed, and the caller is not already
11825            // in the process of starting an activity, then find the top
11826            // activity to check if its configuration needs to change.
11827            starting = mMainStack.topRunningActivityLocked(null);
11828        }
11829
11830        if (starting != null) {
11831            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
11832            // And we need to make sure at this point that all other activities
11833            // are made visible with the correct configuration.
11834            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
11835        }
11836
11837        if (values != null && mWindowManager != null) {
11838            mWindowManager.setNewConfiguration(mConfiguration);
11839        }
11840
11841        return kept;
11842    }
11843
11844    /**
11845     * Decide based on the configuration whether we should shouw the ANR,
11846     * crash, etc dialogs.  The idea is that if there is no affordnace to
11847     * press the on-screen buttons, we shouldn't show the dialog.
11848     *
11849     * A thought: SystemUI might also want to get told about this, the Power
11850     * dialog / global actions also might want different behaviors.
11851     */
11852    private static final boolean shouldShowDialogs(Configuration config) {
11853        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
11854                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
11855    }
11856
11857    /**
11858     * Save the locale.  You must be inside a synchronized (this) block.
11859     */
11860    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
11861        if(isDiff) {
11862            SystemProperties.set("user.language", l.getLanguage());
11863            SystemProperties.set("user.region", l.getCountry());
11864        }
11865
11866        if(isPersist) {
11867            SystemProperties.set("persist.sys.language", l.getLanguage());
11868            SystemProperties.set("persist.sys.country", l.getCountry());
11869            SystemProperties.set("persist.sys.localevar", l.getVariant());
11870        }
11871    }
11872
11873    @Override
11874    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
11875        ActivityRecord srec = ActivityRecord.forToken(token);
11876        return srec != null && srec.task.affinity != null &&
11877                srec.task.affinity.equals(destAffinity);
11878    }
11879
11880    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
11881            Intent resultData) {
11882        ComponentName dest = destIntent.getComponent();
11883
11884        synchronized (this) {
11885            ActivityRecord srec = ActivityRecord.forToken(token);
11886            if (srec == null) {
11887                return false;
11888            }
11889            ArrayList<ActivityRecord> history = srec.stack.mHistory;
11890            final int start = history.indexOf(srec);
11891            if (start < 0) {
11892                // Current activity is not in history stack; do nothing.
11893                return false;
11894            }
11895            int finishTo = start - 1;
11896            ActivityRecord parent = null;
11897            boolean foundParentInTask = false;
11898            if (dest != null) {
11899                TaskRecord tr = srec.task;
11900                for (int i = start - 1; i >= 0; i--) {
11901                    ActivityRecord r = history.get(i);
11902                    if (tr != r.task) {
11903                        // Couldn't find parent in the same task; stop at the one above this.
11904                        // (Root of current task; in-app "home" behavior)
11905                        // Always at least finish the current activity.
11906                        finishTo = Math.min(start - 1, i + 1);
11907                        parent = history.get(finishTo);
11908                        break;
11909                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
11910                            r.info.name.equals(dest.getClassName())) {
11911                        finishTo = i;
11912                        parent = r;
11913                        foundParentInTask = true;
11914                        break;
11915                    }
11916                }
11917            }
11918
11919            if (mController != null) {
11920                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
11921                if (next != null) {
11922                    // ask watcher if this is allowed
11923                    boolean resumeOK = true;
11924                    try {
11925                        resumeOK = mController.activityResuming(next.packageName);
11926                    } catch (RemoteException e) {
11927                        mController = null;
11928                    }
11929
11930                    if (!resumeOK) {
11931                        return false;
11932                    }
11933                }
11934            }
11935            final long origId = Binder.clearCallingIdentity();
11936            for (int i = start; i > finishTo; i--) {
11937                ActivityRecord r = history.get(i);
11938                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
11939                        "navigate-up");
11940                // Only return the supplied result for the first activity finished
11941                resultCode = Activity.RESULT_CANCELED;
11942                resultData = null;
11943            }
11944
11945            if (parent != null && foundParentInTask) {
11946                final int parentLaunchMode = parent.info.launchMode;
11947                final int destIntentFlags = destIntent.getFlags();
11948                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
11949                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
11950                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
11951                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
11952                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
11953                } else {
11954                    try {
11955                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
11956                                destIntent.getComponent(), 0, UserHandle.getCallingUserId());
11957                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
11958                                null, aInfo, parent.appToken, null,
11959                                0, -1, parent.launchedFromUid, 0, null, true, null);
11960                        foundParentInTask = res == ActivityManager.START_SUCCESS;
11961                    } catch (RemoteException e) {
11962                        foundParentInTask = false;
11963                    }
11964                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
11965                            resultData, "navigate-up");
11966                }
11967            }
11968            Binder.restoreCallingIdentity(origId);
11969            return foundParentInTask;
11970        }
11971    }
11972
11973    public int getLaunchedFromUid(IBinder activityToken) {
11974        ActivityRecord srec = ActivityRecord.forToken(activityToken);
11975        if (srec == null) {
11976            return -1;
11977        }
11978        return srec.launchedFromUid;
11979    }
11980
11981    // =========================================================
11982    // LIFETIME MANAGEMENT
11983    // =========================================================
11984
11985    // Returns which broadcast queue the app is the current [or imminent] receiver
11986    // on, or 'null' if the app is not an active broadcast recipient.
11987    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
11988        BroadcastRecord r = app.curReceiver;
11989        if (r != null) {
11990            return r.queue;
11991        }
11992
11993        // It's not the current receiver, but it might be starting up to become one
11994        synchronized (this) {
11995            for (BroadcastQueue queue : mBroadcastQueues) {
11996                r = queue.mPendingBroadcast;
11997                if (r != null && r.curApp == app) {
11998                    // found it; report which queue it's in
11999                    return queue;
12000                }
12001            }
12002        }
12003
12004        return null;
12005    }
12006
12007    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12008            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12009        if (mAdjSeq == app.adjSeq) {
12010            // This adjustment has already been computed.  If we are calling
12011            // from the top, we may have already computed our adjustment with
12012            // an earlier hidden adjustment that isn't really for us... if
12013            // so, use the new hidden adjustment.
12014            if (!recursed && app.hidden) {
12015                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12016                        app.hasActivities ? hiddenAdj : emptyAdj;
12017            }
12018            return app.curRawAdj;
12019        }
12020
12021        if (app.thread == null) {
12022            app.adjSeq = mAdjSeq;
12023            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12024            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12025        }
12026
12027        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12028        app.adjSource = null;
12029        app.adjTarget = null;
12030        app.empty = false;
12031        app.hidden = false;
12032
12033        final int activitiesSize = app.activities.size();
12034
12035        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12036            // The max adjustment doesn't allow this app to be anything
12037            // below foreground, so it is not worth doing work for it.
12038            app.adjType = "fixed";
12039            app.adjSeq = mAdjSeq;
12040            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12041            app.hasActivities = false;
12042            app.foregroundActivities = false;
12043            app.keeping = true;
12044            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12045            // System process can do UI, and when they do we want to have
12046            // them trim their memory after the user leaves the UI.  To
12047            // facilitate this, here we need to determine whether or not it
12048            // is currently showing UI.
12049            app.systemNoUi = true;
12050            if (app == TOP_APP) {
12051                app.systemNoUi = false;
12052                app.hasActivities = true;
12053            } else if (activitiesSize > 0) {
12054                for (int j = 0; j < activitiesSize; j++) {
12055                    final ActivityRecord r = app.activities.get(j);
12056                    if (r.visible) {
12057                        app.systemNoUi = false;
12058                    }
12059                    if (r.app == app) {
12060                        app.hasActivities = true;
12061                    }
12062                }
12063            }
12064            return (app.curAdj=app.maxAdj);
12065        }
12066
12067        app.keeping = false;
12068        app.systemNoUi = false;
12069        app.hasActivities = false;
12070
12071        // Determine the importance of the process, starting with most
12072        // important to least, and assign an appropriate OOM adjustment.
12073        int adj;
12074        int schedGroup;
12075        boolean foregroundActivities = false;
12076        boolean interesting = false;
12077        BroadcastQueue queue;
12078        if (app == TOP_APP) {
12079            // The last app on the list is the foreground app.
12080            adj = ProcessList.FOREGROUND_APP_ADJ;
12081            schedGroup = Process.THREAD_GROUP_DEFAULT;
12082            app.adjType = "top-activity";
12083            foregroundActivities = true;
12084            interesting = true;
12085            app.hasActivities = true;
12086        } else if (app.instrumentationClass != null) {
12087            // Don't want to kill running instrumentation.
12088            adj = ProcessList.FOREGROUND_APP_ADJ;
12089            schedGroup = Process.THREAD_GROUP_DEFAULT;
12090            app.adjType = "instrumentation";
12091            interesting = true;
12092        } else if ((queue = isReceivingBroadcast(app)) != null) {
12093            // An app that is currently receiving a broadcast also
12094            // counts as being in the foreground for OOM killer purposes.
12095            // It's placed in a sched group based on the nature of the
12096            // broadcast as reflected by which queue it's active in.
12097            adj = ProcessList.FOREGROUND_APP_ADJ;
12098            schedGroup = (queue == mFgBroadcastQueue)
12099                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12100            app.adjType = "broadcast";
12101        } else if (app.executingServices.size() > 0) {
12102            // An app that is currently executing a service callback also
12103            // counts as being in the foreground.
12104            adj = ProcessList.FOREGROUND_APP_ADJ;
12105            schedGroup = Process.THREAD_GROUP_DEFAULT;
12106            app.adjType = "exec-service";
12107        } else {
12108            // Assume process is hidden (has activities); we will correct
12109            // later if this is not the case.
12110            adj = hiddenAdj;
12111            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12112            app.hidden = true;
12113            app.adjType = "bg-activities";
12114        }
12115
12116        boolean hasStoppingActivities = false;
12117
12118        // Examine all activities if not already foreground.
12119        if (!foregroundActivities && activitiesSize > 0) {
12120            for (int j = 0; j < activitiesSize; j++) {
12121                final ActivityRecord r = app.activities.get(j);
12122                if (r.visible) {
12123                    // App has a visible activity; only upgrade adjustment.
12124                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12125                        adj = ProcessList.VISIBLE_APP_ADJ;
12126                        app.adjType = "visible";
12127                    }
12128                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12129                    app.hidden = false;
12130                    app.hasActivities = true;
12131                    foregroundActivities = true;
12132                    break;
12133                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12134                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12135                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12136                        app.adjType = "pausing";
12137                    }
12138                    app.hidden = false;
12139                    foregroundActivities = true;
12140                } else if (r.state == ActivityState.STOPPING) {
12141                    // We will apply the actual adjustment later, because
12142                    // we want to allow this process to immediately go through
12143                    // any memory trimming that is in effect.
12144                    app.hidden = false;
12145                    foregroundActivities = true;
12146                    hasStoppingActivities = true;
12147                }
12148                if (r.app == app) {
12149                    app.hasActivities = true;
12150                }
12151            }
12152        }
12153
12154        if (adj == hiddenAdj && !app.hasActivities) {
12155            // Whoops, this process is completely empty as far as we know
12156            // at this point.
12157            adj = emptyAdj;
12158            app.empty = true;
12159            app.adjType = "bg-empty";
12160        }
12161
12162        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12163            if (app.foregroundServices) {
12164                // The user is aware of this app, so make it visible.
12165                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12166                app.hidden = false;
12167                app.adjType = "foreground-service";
12168                schedGroup = Process.THREAD_GROUP_DEFAULT;
12169            } else if (app.forcingToForeground != null) {
12170                // The user is aware of this app, so make it visible.
12171                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12172                app.hidden = false;
12173                app.adjType = "force-foreground";
12174                app.adjSource = app.forcingToForeground;
12175                schedGroup = Process.THREAD_GROUP_DEFAULT;
12176            }
12177        }
12178
12179        if (app.foregroundServices) {
12180            interesting = true;
12181        }
12182
12183        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12184            // We don't want to kill the current heavy-weight process.
12185            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12186            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12187            app.hidden = false;
12188            app.adjType = "heavy";
12189        }
12190
12191        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12192            // This process is hosting what we currently consider to be the
12193            // home app, so we don't want to let it go into the background.
12194            adj = ProcessList.HOME_APP_ADJ;
12195            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12196            app.hidden = false;
12197            app.adjType = "home";
12198        }
12199
12200        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12201                && app.activities.size() > 0) {
12202            // This was the previous process that showed UI to the user.
12203            // We want to try to keep it around more aggressively, to give
12204            // a good experience around switching between two apps.
12205            adj = ProcessList.PREVIOUS_APP_ADJ;
12206            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12207            app.hidden = false;
12208            app.adjType = "previous";
12209        }
12210
12211        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12212                + " reason=" + app.adjType);
12213
12214        // By default, we use the computed adjustment.  It may be changed if
12215        // there are applications dependent on our services or providers, but
12216        // this gives us a baseline and makes sure we don't get into an
12217        // infinite recursion.
12218        app.adjSeq = mAdjSeq;
12219        app.curRawAdj = app.nonStoppingAdj = adj;
12220
12221        if (mBackupTarget != null && app == mBackupTarget.app) {
12222            // If possible we want to avoid killing apps while they're being backed up
12223            if (adj > ProcessList.BACKUP_APP_ADJ) {
12224                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12225                adj = ProcessList.BACKUP_APP_ADJ;
12226                app.adjType = "backup";
12227                app.hidden = false;
12228            }
12229        }
12230
12231        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12232                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12233            final long now = SystemClock.uptimeMillis();
12234            // This process is more important if the top activity is
12235            // bound to the service.
12236            Iterator<ServiceRecord> jt = app.services.iterator();
12237            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12238                ServiceRecord s = jt.next();
12239                if (s.startRequested) {
12240                    if (app.hasShownUi && app != mHomeProcess) {
12241                        // If this process has shown some UI, let it immediately
12242                        // go to the LRU list because it may be pretty heavy with
12243                        // UI stuff.  We'll tag it with a label just to help
12244                        // debug and understand what is going on.
12245                        if (adj > ProcessList.SERVICE_ADJ) {
12246                            app.adjType = "started-bg-ui-services";
12247                        }
12248                    } else {
12249                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12250                            // This service has seen some activity within
12251                            // recent memory, so we will keep its process ahead
12252                            // of the background processes.
12253                            if (adj > ProcessList.SERVICE_ADJ) {
12254                                adj = ProcessList.SERVICE_ADJ;
12255                                app.adjType = "started-services";
12256                                app.hidden = false;
12257                            }
12258                        }
12259                        // If we have let the service slide into the background
12260                        // state, still have some text describing what it is doing
12261                        // even though the service no longer has an impact.
12262                        if (adj > ProcessList.SERVICE_ADJ) {
12263                            app.adjType = "started-bg-services";
12264                        }
12265                    }
12266                    // Don't kill this process because it is doing work; it
12267                    // has said it is doing work.
12268                    app.keeping = true;
12269                }
12270                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12271                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12272                    Iterator<ArrayList<ConnectionRecord>> kt
12273                            = s.connections.values().iterator();
12274                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12275                        ArrayList<ConnectionRecord> clist = kt.next();
12276                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12277                            // XXX should compute this based on the max of
12278                            // all connected clients.
12279                            ConnectionRecord cr = clist.get(i);
12280                            if (cr.binding.client == app) {
12281                                // Binding to ourself is not interesting.
12282                                continue;
12283                            }
12284                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12285                                ProcessRecord client = cr.binding.client;
12286                                int clientAdj = adj;
12287                                int myHiddenAdj = hiddenAdj;
12288                                if (myHiddenAdj > client.hiddenAdj) {
12289                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12290                                        myHiddenAdj = client.hiddenAdj;
12291                                    } else {
12292                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12293                                    }
12294                                }
12295                                int myEmptyAdj = emptyAdj;
12296                                if (myEmptyAdj > client.emptyAdj) {
12297                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12298                                        myEmptyAdj = client.emptyAdj;
12299                                    } else {
12300                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12301                                    }
12302                                }
12303                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12304                                        myEmptyAdj, TOP_APP, true, doingAll);
12305                                String adjType = null;
12306                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12307                                    // Not doing bind OOM management, so treat
12308                                    // this guy more like a started service.
12309                                    if (app.hasShownUi && app != mHomeProcess) {
12310                                        // If this process has shown some UI, let it immediately
12311                                        // go to the LRU list because it may be pretty heavy with
12312                                        // UI stuff.  We'll tag it with a label just to help
12313                                        // debug and understand what is going on.
12314                                        if (adj > clientAdj) {
12315                                            adjType = "bound-bg-ui-services";
12316                                        }
12317                                        app.hidden = false;
12318                                        clientAdj = adj;
12319                                    } else {
12320                                        if (now >= (s.lastActivity
12321                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12322                                            // This service has not seen activity within
12323                                            // recent memory, so allow it to drop to the
12324                                            // LRU list if there is no other reason to keep
12325                                            // it around.  We'll also tag it with a label just
12326                                            // to help debug and undertand what is going on.
12327                                            if (adj > clientAdj) {
12328                                                adjType = "bound-bg-services";
12329                                            }
12330                                            clientAdj = adj;
12331                                        }
12332                                    }
12333                                }
12334                                if (adj > clientAdj) {
12335                                    // If this process has recently shown UI, and
12336                                    // the process that is binding to it is less
12337                                    // important than being visible, then we don't
12338                                    // care about the binding as much as we care
12339                                    // about letting this process get into the LRU
12340                                    // list to be killed and restarted if needed for
12341                                    // memory.
12342                                    if (app.hasShownUi && app != mHomeProcess
12343                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12344                                        adjType = "bound-bg-ui-services";
12345                                    } else {
12346                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12347                                                |Context.BIND_IMPORTANT)) != 0) {
12348                                            adj = clientAdj;
12349                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12350                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12351                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12352                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12353                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12354                                            adj = clientAdj;
12355                                        } else {
12356                                            app.pendingUiClean = true;
12357                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12358                                                adj = ProcessList.VISIBLE_APP_ADJ;
12359                                            }
12360                                        }
12361                                        if (!client.hidden) {
12362                                            app.hidden = false;
12363                                        }
12364                                        if (client.keeping) {
12365                                            app.keeping = true;
12366                                        }
12367                                        adjType = "service";
12368                                    }
12369                                }
12370                                if (adjType != null) {
12371                                    app.adjType = adjType;
12372                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12373                                            .REASON_SERVICE_IN_USE;
12374                                    app.adjSource = cr.binding.client;
12375                                    app.adjSourceOom = clientAdj;
12376                                    app.adjTarget = s.name;
12377                                }
12378                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12379                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12380                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12381                                    }
12382                                }
12383                            }
12384                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12385                                ActivityRecord a = cr.activity;
12386                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12387                                        (a.visible || a.state == ActivityState.RESUMED
12388                                         || a.state == ActivityState.PAUSING)) {
12389                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12390                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12391                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12392                                    }
12393                                    app.hidden = false;
12394                                    app.adjType = "service";
12395                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12396                                            .REASON_SERVICE_IN_USE;
12397                                    app.adjSource = a;
12398                                    app.adjSourceOom = adj;
12399                                    app.adjTarget = s.name;
12400                                }
12401                            }
12402                        }
12403                    }
12404                }
12405            }
12406
12407            // Finally, if this process has active services running in it, we
12408            // would like to avoid killing it unless it would prevent the current
12409            // application from running.  By default we put the process in
12410            // with the rest of the background processes; as we scan through
12411            // its services we may bump it up from there.
12412            if (adj > hiddenAdj) {
12413                adj = hiddenAdj;
12414                app.hidden = false;
12415                app.adjType = "bg-services";
12416            }
12417        }
12418
12419        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12420                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12421            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12422            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12423                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12424                ContentProviderRecord cpr = jt.next();
12425                for (int i = cpr.connections.size()-1;
12426                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12427                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12428                        i--) {
12429                    ContentProviderConnection conn = cpr.connections.get(i);
12430                    ProcessRecord client = conn.client;
12431                    if (client == app) {
12432                        // Being our own client is not interesting.
12433                        continue;
12434                    }
12435                    int myHiddenAdj = hiddenAdj;
12436                    if (myHiddenAdj > client.hiddenAdj) {
12437                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12438                            myHiddenAdj = client.hiddenAdj;
12439                        } else {
12440                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12441                        }
12442                    }
12443                    int myEmptyAdj = emptyAdj;
12444                    if (myEmptyAdj > client.emptyAdj) {
12445                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12446                            myEmptyAdj = client.emptyAdj;
12447                        } else {
12448                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12449                        }
12450                    }
12451                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12452                            myEmptyAdj, TOP_APP, true, doingAll);
12453                    if (adj > clientAdj) {
12454                        if (app.hasShownUi && app != mHomeProcess
12455                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12456                            app.adjType = "bg-ui-provider";
12457                        } else {
12458                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12459                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12460                            app.adjType = "provider";
12461                        }
12462                        if (!client.hidden) {
12463                            app.hidden = false;
12464                        }
12465                        if (client.keeping) {
12466                            app.keeping = true;
12467                        }
12468                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12469                                .REASON_PROVIDER_IN_USE;
12470                        app.adjSource = client;
12471                        app.adjSourceOom = clientAdj;
12472                        app.adjTarget = cpr.name;
12473                    }
12474                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12475                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12476                    }
12477                }
12478                // If the provider has external (non-framework) process
12479                // dependencies, ensure that its adjustment is at least
12480                // FOREGROUND_APP_ADJ.
12481                if (cpr.hasExternalProcessHandles()) {
12482                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12483                        adj = ProcessList.FOREGROUND_APP_ADJ;
12484                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12485                        app.hidden = false;
12486                        app.keeping = true;
12487                        app.adjType = "provider";
12488                        app.adjTarget = cpr.name;
12489                    }
12490                }
12491            }
12492        }
12493
12494        if (adj == ProcessList.SERVICE_ADJ) {
12495            if (doingAll) {
12496                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12497                mNewNumServiceProcs++;
12498            }
12499            if (app.serviceb) {
12500                adj = ProcessList.SERVICE_B_ADJ;
12501            }
12502        } else {
12503            app.serviceb = false;
12504        }
12505
12506        app.nonStoppingAdj = adj;
12507
12508        if (hasStoppingActivities) {
12509            // Only upgrade adjustment.
12510            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12511                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12512                app.adjType = "stopping";
12513            }
12514        }
12515
12516        app.curRawAdj = adj;
12517
12518        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12519        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12520        if (adj > app.maxAdj) {
12521            adj = app.maxAdj;
12522            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12523                schedGroup = Process.THREAD_GROUP_DEFAULT;
12524            }
12525        }
12526        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12527            app.keeping = true;
12528        }
12529
12530        if (app.hasAboveClient) {
12531            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12532            // then we need to drop its adjustment to be lower than the service's
12533            // in order to honor the request.  We want to drop it by one adjustment
12534            // level...  but there is special meaning applied to various levels so
12535            // we will skip some of them.
12536            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12537                // System process will not get dropped, ever
12538            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12539                adj = ProcessList.VISIBLE_APP_ADJ;
12540            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12541                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12542            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12543                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12544            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12545                adj++;
12546            }
12547        }
12548
12549        int importance = app.memImportance;
12550        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12551            app.curAdj = adj;
12552            app.curSchedGroup = schedGroup;
12553            if (!interesting) {
12554                // For this reporting, if there is not something explicitly
12555                // interesting in this process then we will push it to the
12556                // background importance.
12557                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12558            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12559                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12560            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12561                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12562            } else if (adj >= ProcessList.HOME_APP_ADJ) {
12563                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12564            } else if (adj >= ProcessList.SERVICE_ADJ) {
12565                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12566            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12567                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12568            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12569                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12570            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12571                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12572            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12573                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12574            } else {
12575                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12576            }
12577        }
12578
12579        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12580        if (foregroundActivities != app.foregroundActivities) {
12581            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12582        }
12583        if (changes != 0) {
12584            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12585            app.memImportance = importance;
12586            app.foregroundActivities = foregroundActivities;
12587            int i = mPendingProcessChanges.size()-1;
12588            ProcessChangeItem item = null;
12589            while (i >= 0) {
12590                item = mPendingProcessChanges.get(i);
12591                if (item.pid == app.pid) {
12592                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12593                    break;
12594                }
12595                i--;
12596            }
12597            if (i < 0) {
12598                // No existing item in pending changes; need a new one.
12599                final int NA = mAvailProcessChanges.size();
12600                if (NA > 0) {
12601                    item = mAvailProcessChanges.remove(NA-1);
12602                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12603                } else {
12604                    item = new ProcessChangeItem();
12605                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
12606                }
12607                item.changes = 0;
12608                item.pid = app.pid;
12609                item.uid = app.info.uid;
12610                if (mPendingProcessChanges.size() == 0) {
12611                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
12612                            "*** Enqueueing dispatch processes changed!");
12613                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
12614                }
12615                mPendingProcessChanges.add(item);
12616            }
12617            item.changes |= changes;
12618            item.importance = importance;
12619            item.foregroundActivities = foregroundActivities;
12620            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
12621                    + Integer.toHexString(System.identityHashCode(item))
12622                    + " " + app.toShortString() + ": changes=" + item.changes
12623                    + " importance=" + item.importance
12624                    + " foreground=" + item.foregroundActivities
12625                    + " type=" + app.adjType + " source=" + app.adjSource
12626                    + " target=" + app.adjTarget);
12627        }
12628
12629        return app.curRawAdj;
12630    }
12631
12632    /**
12633     * Ask a given process to GC right now.
12634     */
12635    final void performAppGcLocked(ProcessRecord app) {
12636        try {
12637            app.lastRequestedGc = SystemClock.uptimeMillis();
12638            if (app.thread != null) {
12639                if (app.reportLowMemory) {
12640                    app.reportLowMemory = false;
12641                    app.thread.scheduleLowMemory();
12642                } else {
12643                    app.thread.processInBackground();
12644                }
12645            }
12646        } catch (Exception e) {
12647            // whatever.
12648        }
12649    }
12650
12651    /**
12652     * Returns true if things are idle enough to perform GCs.
12653     */
12654    private final boolean canGcNowLocked() {
12655        boolean processingBroadcasts = false;
12656        for (BroadcastQueue q : mBroadcastQueues) {
12657            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
12658                processingBroadcasts = true;
12659            }
12660        }
12661        return !processingBroadcasts
12662                && (mSleeping || (mMainStack.mResumedActivity != null &&
12663                        mMainStack.mResumedActivity.idle));
12664    }
12665
12666    /**
12667     * Perform GCs on all processes that are waiting for it, but only
12668     * if things are idle.
12669     */
12670    final void performAppGcsLocked() {
12671        final int N = mProcessesToGc.size();
12672        if (N <= 0) {
12673            return;
12674        }
12675        if (canGcNowLocked()) {
12676            while (mProcessesToGc.size() > 0) {
12677                ProcessRecord proc = mProcessesToGc.remove(0);
12678                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
12679                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12680                            <= SystemClock.uptimeMillis()) {
12681                        // To avoid spamming the system, we will GC processes one
12682                        // at a time, waiting a few seconds between each.
12683                        performAppGcLocked(proc);
12684                        scheduleAppGcsLocked();
12685                        return;
12686                    } else {
12687                        // It hasn't been long enough since we last GCed this
12688                        // process...  put it in the list to wait for its time.
12689                        addProcessToGcListLocked(proc);
12690                        break;
12691                    }
12692                }
12693            }
12694
12695            scheduleAppGcsLocked();
12696        }
12697    }
12698
12699    /**
12700     * If all looks good, perform GCs on all processes waiting for them.
12701     */
12702    final void performAppGcsIfAppropriateLocked() {
12703        if (canGcNowLocked()) {
12704            performAppGcsLocked();
12705            return;
12706        }
12707        // Still not idle, wait some more.
12708        scheduleAppGcsLocked();
12709    }
12710
12711    /**
12712     * Schedule the execution of all pending app GCs.
12713     */
12714    final void scheduleAppGcsLocked() {
12715        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
12716
12717        if (mProcessesToGc.size() > 0) {
12718            // Schedule a GC for the time to the next process.
12719            ProcessRecord proc = mProcessesToGc.get(0);
12720            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12721
12722            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
12723            long now = SystemClock.uptimeMillis();
12724            if (when < (now+GC_TIMEOUT)) {
12725                when = now + GC_TIMEOUT;
12726            }
12727            mHandler.sendMessageAtTime(msg, when);
12728        }
12729    }
12730
12731    /**
12732     * Add a process to the array of processes waiting to be GCed.  Keeps the
12733     * list in sorted order by the last GC time.  The process can't already be
12734     * on the list.
12735     */
12736    final void addProcessToGcListLocked(ProcessRecord proc) {
12737        boolean added = false;
12738        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12739            if (mProcessesToGc.get(i).lastRequestedGc <
12740                    proc.lastRequestedGc) {
12741                added = true;
12742                mProcessesToGc.add(i+1, proc);
12743                break;
12744            }
12745        }
12746        if (!added) {
12747            mProcessesToGc.add(0, proc);
12748        }
12749    }
12750
12751    /**
12752     * Set up to ask a process to GC itself.  This will either do it
12753     * immediately, or put it on the list of processes to gc the next
12754     * time things are idle.
12755     */
12756    final void scheduleAppGcLocked(ProcessRecord app) {
12757        long now = SystemClock.uptimeMillis();
12758        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
12759            return;
12760        }
12761        if (!mProcessesToGc.contains(app)) {
12762            addProcessToGcListLocked(app);
12763            scheduleAppGcsLocked();
12764        }
12765    }
12766
12767    final void checkExcessivePowerUsageLocked(boolean doKills) {
12768        updateCpuStatsNow();
12769
12770        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12771        boolean doWakeKills = doKills;
12772        boolean doCpuKills = doKills;
12773        if (mLastPowerCheckRealtime == 0) {
12774            doWakeKills = false;
12775        }
12776        if (mLastPowerCheckUptime == 0) {
12777            doCpuKills = false;
12778        }
12779        if (stats.isScreenOn()) {
12780            doWakeKills = false;
12781        }
12782        final long curRealtime = SystemClock.elapsedRealtime();
12783        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12784        final long curUptime = SystemClock.uptimeMillis();
12785        final long uptimeSince = curUptime - mLastPowerCheckUptime;
12786        mLastPowerCheckRealtime = curRealtime;
12787        mLastPowerCheckUptime = curUptime;
12788        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12789            doWakeKills = false;
12790        }
12791        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12792            doCpuKills = false;
12793        }
12794        int i = mLruProcesses.size();
12795        while (i > 0) {
12796            i--;
12797            ProcessRecord app = mLruProcesses.get(i);
12798            if (!app.keeping) {
12799                long wtime;
12800                synchronized (stats) {
12801                    wtime = stats.getProcessWakeTime(app.info.uid,
12802                            app.pid, curRealtime);
12803                }
12804                long wtimeUsed = wtime - app.lastWakeTime;
12805                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12806                if (DEBUG_POWER) {
12807                    StringBuilder sb = new StringBuilder(128);
12808                    sb.append("Wake for ");
12809                    app.toShortString(sb);
12810                    sb.append(": over ");
12811                    TimeUtils.formatDuration(realtimeSince, sb);
12812                    sb.append(" used ");
12813                    TimeUtils.formatDuration(wtimeUsed, sb);
12814                    sb.append(" (");
12815                    sb.append((wtimeUsed*100)/realtimeSince);
12816                    sb.append("%)");
12817                    Slog.i(TAG, sb.toString());
12818                    sb.setLength(0);
12819                    sb.append("CPU for ");
12820                    app.toShortString(sb);
12821                    sb.append(": over ");
12822                    TimeUtils.formatDuration(uptimeSince, sb);
12823                    sb.append(" used ");
12824                    TimeUtils.formatDuration(cputimeUsed, sb);
12825                    sb.append(" (");
12826                    sb.append((cputimeUsed*100)/uptimeSince);
12827                    sb.append("%)");
12828                    Slog.i(TAG, sb.toString());
12829                }
12830                // If a process has held a wake lock for more
12831                // than 50% of the time during this period,
12832                // that sounds bad.  Kill!
12833                if (doWakeKills && realtimeSince > 0
12834                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
12835                    synchronized (stats) {
12836                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12837                                realtimeSince, wtimeUsed);
12838                    }
12839                    Slog.w(TAG, "Excessive wake lock in " + app.processName
12840                            + " (pid " + app.pid + "): held " + wtimeUsed
12841                            + " during " + realtimeSince);
12842                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12843                            app.processName, app.setAdj, "excessive wake lock");
12844                    Process.killProcessQuiet(app.pid);
12845                } else if (doCpuKills && uptimeSince > 0
12846                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
12847                    synchronized (stats) {
12848                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12849                                uptimeSince, cputimeUsed);
12850                    }
12851                    Slog.w(TAG, "Excessive CPU in " + app.processName
12852                            + " (pid " + app.pid + "): used " + cputimeUsed
12853                            + " during " + uptimeSince);
12854                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12855                            app.processName, app.setAdj, "excessive cpu");
12856                    Process.killProcessQuiet(app.pid);
12857                } else {
12858                    app.lastWakeTime = wtime;
12859                    app.lastCpuTime = app.curCpuTime;
12860                }
12861            }
12862        }
12863    }
12864
12865    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
12866            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
12867        app.hiddenAdj = hiddenAdj;
12868        app.emptyAdj = emptyAdj;
12869
12870        if (app.thread == null) {
12871            return false;
12872        }
12873
12874        final boolean wasKeeping = app.keeping;
12875
12876        boolean success = true;
12877
12878        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
12879
12880        if (app.curRawAdj != app.setRawAdj) {
12881            if (wasKeeping && !app.keeping) {
12882                // This app is no longer something we want to keep.  Note
12883                // its current wake lock time to later know to kill it if
12884                // it is not behaving well.
12885                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12886                synchronized (stats) {
12887                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12888                            app.pid, SystemClock.elapsedRealtime());
12889                }
12890                app.lastCpuTime = app.curCpuTime;
12891            }
12892
12893            app.setRawAdj = app.curRawAdj;
12894        }
12895
12896        if (app.curAdj != app.setAdj) {
12897            if (Process.setOomAdj(app.pid, app.curAdj)) {
12898                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
12899                    TAG, "Set " + app.pid + " " + app.processName +
12900                    " adj " + app.curAdj + ": " + app.adjType);
12901                app.setAdj = app.curAdj;
12902            } else {
12903                success = false;
12904                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
12905            }
12906        }
12907        if (app.setSchedGroup != app.curSchedGroup) {
12908            app.setSchedGroup = app.curSchedGroup;
12909            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
12910                    "Setting process group of " + app.processName
12911                    + " to " + app.curSchedGroup);
12912            if (app.waitingToKill != null &&
12913                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
12914                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
12915                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12916                        app.processName, app.setAdj, app.waitingToKill);
12917                app.killedBackground = true;
12918                Process.killProcessQuiet(app.pid);
12919                success = false;
12920            } else {
12921                if (true) {
12922                    long oldId = Binder.clearCallingIdentity();
12923                    try {
12924                        Process.setProcessGroup(app.pid, app.curSchedGroup);
12925                    } catch (Exception e) {
12926                        Slog.w(TAG, "Failed setting process group of " + app.pid
12927                                + " to " + app.curSchedGroup);
12928                        e.printStackTrace();
12929                    } finally {
12930                        Binder.restoreCallingIdentity(oldId);
12931                    }
12932                } else {
12933                    if (app.thread != null) {
12934                        try {
12935                            app.thread.setSchedulingGroup(app.curSchedGroup);
12936                        } catch (RemoteException e) {
12937                        }
12938                    }
12939                }
12940            }
12941        }
12942        return success;
12943    }
12944
12945    private final ActivityRecord resumedAppLocked() {
12946        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
12947        if (resumedActivity == null || resumedActivity.app == null) {
12948            resumedActivity = mMainStack.mPausingActivity;
12949            if (resumedActivity == null || resumedActivity.app == null) {
12950                resumedActivity = mMainStack.topRunningActivityLocked(null);
12951            }
12952        }
12953        return resumedActivity;
12954    }
12955
12956    final boolean updateOomAdjLocked(ProcessRecord app) {
12957        final ActivityRecord TOP_ACT = resumedAppLocked();
12958        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12959        int curAdj = app.curAdj;
12960        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12961            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12962
12963        mAdjSeq++;
12964
12965        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
12966                TOP_APP, false);
12967        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12968            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12969        if (nowHidden != wasHidden) {
12970            // Changed to/from hidden state, so apps after it in the LRU
12971            // list may also be changed.
12972            updateOomAdjLocked();
12973        }
12974        return success;
12975    }
12976
12977    final void updateOomAdjLocked() {
12978        final ActivityRecord TOP_ACT = resumedAppLocked();
12979        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12980
12981        if (false) {
12982            RuntimeException e = new RuntimeException();
12983            e.fillInStackTrace();
12984            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
12985        }
12986
12987        mAdjSeq++;
12988        mNewNumServiceProcs = 0;
12989
12990        // Let's determine how many processes we have running vs.
12991        // how many slots we have for background processes; we may want
12992        // to put multiple processes in a slot of there are enough of
12993        // them.
12994        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
12995                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
12996        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
12997        if (emptyFactor < 1) emptyFactor = 1;
12998        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
12999        if (hiddenFactor < 1) hiddenFactor = 1;
13000        int stepHidden = 0;
13001        int stepEmpty = 0;
13002        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13003        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13004        int numHidden = 0;
13005        int numEmpty = 0;
13006        int numTrimming = 0;
13007
13008        mNumNonHiddenProcs = 0;
13009        mNumHiddenProcs = 0;
13010
13011        // First update the OOM adjustment for each of the
13012        // application processes based on their current state.
13013        int i = mLruProcesses.size();
13014        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13015        int nextHiddenAdj = curHiddenAdj+1;
13016        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13017        int nextEmptyAdj = curEmptyAdj+2;
13018        while (i > 0) {
13019            i--;
13020            ProcessRecord app = mLruProcesses.get(i);
13021            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13022            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
13023            if (!app.killedBackground) {
13024                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13025                    // This process was assigned as a hidden process...  step the
13026                    // hidden level.
13027                    mNumHiddenProcs++;
13028                    if (curHiddenAdj != nextHiddenAdj) {
13029                        stepHidden++;
13030                        if (stepHidden >= hiddenFactor) {
13031                            stepHidden = 0;
13032                            curHiddenAdj = nextHiddenAdj;
13033                            nextHiddenAdj += 2;
13034                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13035                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13036                            }
13037                        }
13038                    }
13039                    numHidden++;
13040                    if (numHidden > hiddenProcessLimit) {
13041                        Slog.i(TAG, "No longer want " + app.processName
13042                                + " (pid " + app.pid + "): hidden #" + numHidden);
13043                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13044                                app.processName, app.setAdj, "too many background");
13045                        app.killedBackground = true;
13046                        Process.killProcessQuiet(app.pid);
13047                    }
13048                } else {
13049                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13050                        // This process was assigned as an empty process...  step the
13051                        // empty level.
13052                        if (curEmptyAdj != nextEmptyAdj) {
13053                            stepEmpty++;
13054                            if (stepEmpty >= emptyFactor) {
13055                                stepEmpty = 0;
13056                                curEmptyAdj = nextEmptyAdj;
13057                                nextEmptyAdj += 2;
13058                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13059                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13060                                }
13061                            }
13062                        }
13063                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13064                        mNumNonHiddenProcs++;
13065                    }
13066                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13067                        numEmpty++;
13068                        if (numEmpty > emptyProcessLimit) {
13069                            Slog.i(TAG, "No longer want " + app.processName
13070                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13071                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13072                                    app.processName, app.setAdj, "too many background");
13073                            app.killedBackground = true;
13074                            Process.killProcessQuiet(app.pid);
13075                        }
13076                    }
13077                }
13078                if (app.isolated && app.services.size() <= 0) {
13079                    // If this is an isolated process, and there are no
13080                    // services running in it, then the process is no longer
13081                    // needed.  We agressively kill these because we can by
13082                    // definition not re-use the same process again, and it is
13083                    // good to avoid having whatever code was running in them
13084                    // left sitting around after no longer needed.
13085                    Slog.i(TAG, "Isolated process " + app.processName
13086                            + " (pid " + app.pid + ") no longer needed");
13087                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13088                            app.processName, app.setAdj, "isolated not needed");
13089                    app.killedBackground = true;
13090                    Process.killProcessQuiet(app.pid);
13091                }
13092                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13093                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13094                        && !app.killedBackground) {
13095                    numTrimming++;
13096                }
13097            }
13098        }
13099
13100        mNumServiceProcs = mNewNumServiceProcs;
13101
13102        // Now determine the memory trimming level of background processes.
13103        // Unfortunately we need to start at the back of the list to do this
13104        // properly.  We only do this if the number of background apps we
13105        // are managing to keep around is less than half the maximum we desire;
13106        // if we are keeping a good number around, we'll let them use whatever
13107        // memory they want.
13108        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13109                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13110            final int numHiddenAndEmpty = numHidden + numEmpty;
13111            final int N = mLruProcesses.size();
13112            int factor = numTrimming/3;
13113            int minFactor = 2;
13114            if (mHomeProcess != null) minFactor++;
13115            if (mPreviousProcess != null) minFactor++;
13116            if (factor < minFactor) factor = minFactor;
13117            int step = 0;
13118            int fgTrimLevel;
13119            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13120                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13121            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13122                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13123            } else {
13124                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13125            }
13126            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13127            for (i=0; i<N; i++) {
13128                ProcessRecord app = mLruProcesses.get(i);
13129                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13130                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13131                        && !app.killedBackground) {
13132                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13133                        try {
13134                            app.thread.scheduleTrimMemory(curLevel);
13135                        } catch (RemoteException e) {
13136                        }
13137                        if (false) {
13138                            // For now we won't do this; our memory trimming seems
13139                            // to be good enough at this point that destroying
13140                            // activities causes more harm than good.
13141                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13142                                    && app != mHomeProcess && app != mPreviousProcess) {
13143                                // Need to do this on its own message because the stack may not
13144                                // be in a consistent state at this point.
13145                                // For these apps we will also finish their activities
13146                                // to help them free memory.
13147                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13148                            }
13149                        }
13150                    }
13151                    app.trimMemoryLevel = curLevel;
13152                    step++;
13153                    if (step >= factor) {
13154                        step = 0;
13155                        switch (curLevel) {
13156                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13157                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13158                                break;
13159                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13160                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13161                                break;
13162                        }
13163                    }
13164                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13165                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13166                            && app.thread != null) {
13167                        try {
13168                            app.thread.scheduleTrimMemory(
13169                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13170                        } catch (RemoteException e) {
13171                        }
13172                    }
13173                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13174                } else {
13175                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13176                            && app.pendingUiClean) {
13177                        // If this application is now in the background and it
13178                        // had done UI, then give it the special trim level to
13179                        // have it free UI resources.
13180                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13181                        if (app.trimMemoryLevel < level && app.thread != null) {
13182                            try {
13183                                app.thread.scheduleTrimMemory(level);
13184                            } catch (RemoteException e) {
13185                            }
13186                        }
13187                        app.pendingUiClean = false;
13188                    }
13189                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13190                        try {
13191                            app.thread.scheduleTrimMemory(fgTrimLevel);
13192                        } catch (RemoteException e) {
13193                        }
13194                    }
13195                    app.trimMemoryLevel = fgTrimLevel;
13196                }
13197            }
13198        } else {
13199            final int N = mLruProcesses.size();
13200            for (i=0; i<N; i++) {
13201                ProcessRecord app = mLruProcesses.get(i);
13202                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13203                        && app.pendingUiClean) {
13204                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13205                            && app.thread != null) {
13206                        try {
13207                            app.thread.scheduleTrimMemory(
13208                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13209                        } catch (RemoteException e) {
13210                        }
13211                    }
13212                    app.pendingUiClean = false;
13213                }
13214                app.trimMemoryLevel = 0;
13215            }
13216        }
13217
13218        if (mAlwaysFinishActivities) {
13219            // Need to do this on its own message because the stack may not
13220            // be in a consistent state at this point.
13221            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13222        }
13223    }
13224
13225    final void trimApplications() {
13226        synchronized (this) {
13227            int i;
13228
13229            // First remove any unused application processes whose package
13230            // has been removed.
13231            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13232                final ProcessRecord app = mRemovedProcesses.get(i);
13233                if (app.activities.size() == 0
13234                        && app.curReceiver == null && app.services.size() == 0) {
13235                    Slog.i(
13236                        TAG, "Exiting empty application process "
13237                        + app.processName + " ("
13238                        + (app.thread != null ? app.thread.asBinder() : null)
13239                        + ")\n");
13240                    if (app.pid > 0 && app.pid != MY_PID) {
13241                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13242                                app.processName, app.setAdj, "empty");
13243                        Process.killProcessQuiet(app.pid);
13244                    } else {
13245                        try {
13246                            app.thread.scheduleExit();
13247                        } catch (Exception e) {
13248                            // Ignore exceptions.
13249                        }
13250                    }
13251                    cleanUpApplicationRecordLocked(app, false, true, -1);
13252                    mRemovedProcesses.remove(i);
13253
13254                    if (app.persistent) {
13255                        if (app.persistent) {
13256                            addAppLocked(app.info, false);
13257                        }
13258                    }
13259                }
13260            }
13261
13262            // Now update the oom adj for all processes.
13263            updateOomAdjLocked();
13264        }
13265    }
13266
13267    /** This method sends the specified signal to each of the persistent apps */
13268    public void signalPersistentProcesses(int sig) throws RemoteException {
13269        if (sig != Process.SIGNAL_USR1) {
13270            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13271        }
13272
13273        synchronized (this) {
13274            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13275                    != PackageManager.PERMISSION_GRANTED) {
13276                throw new SecurityException("Requires permission "
13277                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13278            }
13279
13280            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13281                ProcessRecord r = mLruProcesses.get(i);
13282                if (r.thread != null && r.persistent) {
13283                    Process.sendSignal(r.pid, sig);
13284                }
13285            }
13286        }
13287    }
13288
13289    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13290        if (proc == null || proc == mProfileProc) {
13291            proc = mProfileProc;
13292            path = mProfileFile;
13293            profileType = mProfileType;
13294            clearProfilerLocked();
13295        }
13296        if (proc == null) {
13297            return;
13298        }
13299        try {
13300            proc.thread.profilerControl(false, path, null, profileType);
13301        } catch (RemoteException e) {
13302            throw new IllegalStateException("Process disappeared");
13303        }
13304    }
13305
13306    private void clearProfilerLocked() {
13307        if (mProfileFd != null) {
13308            try {
13309                mProfileFd.close();
13310            } catch (IOException e) {
13311            }
13312        }
13313        mProfileApp = null;
13314        mProfileProc = null;
13315        mProfileFile = null;
13316        mProfileType = 0;
13317        mAutoStopProfiler = false;
13318    }
13319
13320    public boolean profileControl(String process, boolean start,
13321            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13322
13323        try {
13324            synchronized (this) {
13325                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13326                // its own permission.
13327                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13328                        != PackageManager.PERMISSION_GRANTED) {
13329                    throw new SecurityException("Requires permission "
13330                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13331                }
13332
13333                if (start && fd == null) {
13334                    throw new IllegalArgumentException("null fd");
13335                }
13336
13337                ProcessRecord proc = null;
13338                if (process != null) {
13339                    try {
13340                        int pid = Integer.parseInt(process);
13341                        synchronized (mPidsSelfLocked) {
13342                            proc = mPidsSelfLocked.get(pid);
13343                        }
13344                    } catch (NumberFormatException e) {
13345                    }
13346
13347                    if (proc == null) {
13348                        HashMap<String, SparseArray<ProcessRecord>> all
13349                                = mProcessNames.getMap();
13350                        SparseArray<ProcessRecord> procs = all.get(process);
13351                        if (procs != null && procs.size() > 0) {
13352                            proc = procs.valueAt(0);
13353                        }
13354                    }
13355                }
13356
13357                if (start && (proc == null || proc.thread == null)) {
13358                    throw new IllegalArgumentException("Unknown process: " + process);
13359                }
13360
13361                if (start) {
13362                    stopProfilerLocked(null, null, 0);
13363                    setProfileApp(proc.info, proc.processName, path, fd, false);
13364                    mProfileProc = proc;
13365                    mProfileType = profileType;
13366                    try {
13367                        fd = fd.dup();
13368                    } catch (IOException e) {
13369                        fd = null;
13370                    }
13371                    proc.thread.profilerControl(start, path, fd, profileType);
13372                    fd = null;
13373                    mProfileFd = null;
13374                } else {
13375                    stopProfilerLocked(proc, path, profileType);
13376                    if (fd != null) {
13377                        try {
13378                            fd.close();
13379                        } catch (IOException e) {
13380                        }
13381                    }
13382                }
13383
13384                return true;
13385            }
13386        } catch (RemoteException e) {
13387            throw new IllegalStateException("Process disappeared");
13388        } finally {
13389            if (fd != null) {
13390                try {
13391                    fd.close();
13392                } catch (IOException e) {
13393                }
13394            }
13395        }
13396    }
13397
13398    public boolean dumpHeap(String process, boolean managed,
13399            String path, ParcelFileDescriptor fd) throws RemoteException {
13400
13401        try {
13402            synchronized (this) {
13403                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13404                // its own permission (same as profileControl).
13405                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13406                        != PackageManager.PERMISSION_GRANTED) {
13407                    throw new SecurityException("Requires permission "
13408                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13409                }
13410
13411                if (fd == null) {
13412                    throw new IllegalArgumentException("null fd");
13413                }
13414
13415                ProcessRecord proc = null;
13416                try {
13417                    int pid = Integer.parseInt(process);
13418                    synchronized (mPidsSelfLocked) {
13419                        proc = mPidsSelfLocked.get(pid);
13420                    }
13421                } catch (NumberFormatException e) {
13422                }
13423
13424                if (proc == null) {
13425                    HashMap<String, SparseArray<ProcessRecord>> all
13426                            = mProcessNames.getMap();
13427                    SparseArray<ProcessRecord> procs = all.get(process);
13428                    if (procs != null && procs.size() > 0) {
13429                        proc = procs.valueAt(0);
13430                    }
13431                }
13432
13433                if (proc == null || proc.thread == null) {
13434                    throw new IllegalArgumentException("Unknown process: " + process);
13435                }
13436
13437                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13438                if (!isDebuggable) {
13439                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13440                        throw new SecurityException("Process not debuggable: " + proc);
13441                    }
13442                }
13443
13444                proc.thread.dumpHeap(managed, path, fd);
13445                fd = null;
13446                return true;
13447            }
13448        } catch (RemoteException e) {
13449            throw new IllegalStateException("Process disappeared");
13450        } finally {
13451            if (fd != null) {
13452                try {
13453                    fd.close();
13454                } catch (IOException e) {
13455                }
13456            }
13457        }
13458    }
13459
13460    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13461    public void monitor() {
13462        synchronized (this) { }
13463    }
13464
13465    void onCoreSettingsChange(Bundle settings) {
13466        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13467            ProcessRecord processRecord = mLruProcesses.get(i);
13468            try {
13469                if (processRecord.thread != null) {
13470                    processRecord.thread.setCoreSettings(settings);
13471                }
13472            } catch (RemoteException re) {
13473                /* ignore */
13474            }
13475        }
13476    }
13477
13478    // Multi-user methods
13479
13480    public boolean switchUser(int userId) {
13481        final int callingUid = Binder.getCallingUid();
13482        if (callingUid != 0 && callingUid != Process.myUid()) {
13483            Slog.e(TAG, "Trying to switch user from unauthorized app");
13484            return false;
13485        }
13486        if (mCurrentUserId == userId)
13487            return true;
13488
13489        synchronized (this) {
13490            // Check if user is already logged in, otherwise check if user exists first before
13491            // adding to the list of logged in users.
13492            if (mLoggedInUsers.indexOfKey(userId) < 0) {
13493                if (!userExists(userId)) {
13494                    return false;
13495                }
13496                mLoggedInUsers.append(userId, userId);
13497            }
13498
13499            mCurrentUserId = userId;
13500            boolean haveActivities = mMainStack.switchUser(userId);
13501            if (!haveActivities) {
13502                startHomeActivityLocked(userId);
13503            }
13504
13505        }
13506
13507        // Inform of user switch
13508        Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13509        addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13510        mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_USERS);
13511
13512        return true;
13513    }
13514
13515    @Override
13516    public UserInfo getCurrentUser() throws RemoteException {
13517        final int callingUid = Binder.getCallingUid();
13518        if (callingUid != 0 && callingUid != Process.myUid()) {
13519            Slog.e(TAG, "Trying to get user from unauthorized app");
13520            return null;
13521        }
13522        return getUserManager().getUserInfo(mCurrentUserId);
13523    }
13524
13525    private void onUserRemoved(Intent intent) {
13526        int extraUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
13527        if (extraUserId < 1) return;
13528
13529        // Kill all the processes for the user
13530        ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>();
13531        synchronized (this) {
13532            HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap();
13533            for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
13534                SparseArray<ProcessRecord> uids = uidMap.getValue();
13535                for (int i = 0; i < uids.size(); i++) {
13536                    if (UserHandle.getUserId(uids.keyAt(i)) == extraUserId) {
13537                        pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
13538                    }
13539                }
13540            }
13541
13542            for (Pair<String,Integer> pkgAndUid : pkgAndUids) {
13543                forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second,
13544                        false, false, true, true, extraUserId);
13545            }
13546        }
13547    }
13548
13549    private boolean userExists(int userId) {
13550        UserInfo user = getUserManager().getUserInfo(userId);
13551        return user != null;
13552    }
13553
13554    UserManager getUserManager() {
13555        if (mUserManager == null) {
13556            mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
13557        }
13558        return mUserManager;
13559    }
13560
13561    private void checkValidCaller(int uid, int userId) {
13562        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
13563
13564        throw new SecurityException("Caller uid=" + uid
13565                + " is not privileged to communicate with user=" + userId);
13566    }
13567
13568    private int applyUserId(int uid, int userId) {
13569        return UserHandle.getUid(userId, uid);
13570    }
13571
13572    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
13573        if (info == null) return null;
13574        ApplicationInfo newInfo = new ApplicationInfo(info);
13575        newInfo.uid = applyUserId(info.uid, userId);
13576        newInfo.dataDir = USER_DATA_DIR + userId + "/"
13577                + info.packageName;
13578        return newInfo;
13579    }
13580
13581    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
13582        if (aInfo == null
13583                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
13584            return aInfo;
13585        }
13586
13587        ActivityInfo info = new ActivityInfo(aInfo);
13588        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
13589        return info;
13590    }
13591}
13592