ActivityManagerService.java revision 2bca868361b41ff6a8228824cbecadc4c5deb44e
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                } catch (PackageManager.NameNotFoundException e) {
1986                    Slog.w(TAG, "Unable to retrieve gids", e);
1987                }
1988
1989                if (Environment.isExternalStorageEmulated()) {
1990                    mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
1991                }
1992            }
1993            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1994                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1995                        && mTopComponent != null
1996                        && app.processName.equals(mTopComponent.getPackageName())) {
1997                    uid = 0;
1998                }
1999                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2000                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2001                    uid = 0;
2002                }
2003            }
2004            int debugFlags = 0;
2005            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2006                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2007                // Also turn on CheckJNI for debuggable apps. It's quite
2008                // awkward to turn on otherwise.
2009                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2010            }
2011            // Run the app in safe mode if its manifest requests so or the
2012            // system is booted in safe mode.
2013            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2014                Zygote.systemInSafeMode == true) {
2015                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2016            }
2017            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2018                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2019            }
2020            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2021                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2022            }
2023            if ("1".equals(SystemProperties.get("debug.assert"))) {
2024                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2025            }
2026
2027            // Start the process.  It will either succeed and return a result containing
2028            // the PID of the new process, or else throw a RuntimeException.
2029            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2030                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2031                    app.info.targetSdkVersion, null, null);
2032
2033            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2034            synchronized (bs) {
2035                if (bs.isOnBattery()) {
2036                    app.batteryStats.incStartsLocked();
2037                }
2038            }
2039
2040            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2041                    app.processName, hostingType,
2042                    hostingNameStr != null ? hostingNameStr : "");
2043
2044            if (app.persistent) {
2045                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2046            }
2047
2048            StringBuilder buf = mStringBuilder;
2049            buf.setLength(0);
2050            buf.append("Start proc ");
2051            buf.append(app.processName);
2052            buf.append(" for ");
2053            buf.append(hostingType);
2054            if (hostingNameStr != null) {
2055                buf.append(" ");
2056                buf.append(hostingNameStr);
2057            }
2058            buf.append(": pid=");
2059            buf.append(startResult.pid);
2060            buf.append(" uid=");
2061            buf.append(uid);
2062            buf.append(" gids={");
2063            if (gids != null) {
2064                for (int gi=0; gi<gids.length; gi++) {
2065                    if (gi != 0) buf.append(", ");
2066                    buf.append(gids[gi]);
2067
2068                }
2069            }
2070            buf.append("}");
2071            Slog.i(TAG, buf.toString());
2072            app.setPid(startResult.pid);
2073            app.usingWrapper = startResult.usingWrapper;
2074            app.removed = false;
2075            synchronized (mPidsSelfLocked) {
2076                this.mPidsSelfLocked.put(startResult.pid, app);
2077                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2078                msg.obj = app;
2079                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2080                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2081            }
2082        } catch (RuntimeException e) {
2083            // XXX do better error recovery.
2084            app.setPid(0);
2085            Slog.e(TAG, "Failure starting process " + app.processName, e);
2086        }
2087    }
2088
2089    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2090        if (resumed) {
2091            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2092        } else {
2093            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2094        }
2095    }
2096
2097    boolean startHomeActivityLocked(int userId) {
2098        if (mHeadless) {
2099            // Added because none of the other calls to ensureBootCompleted seem to fire
2100            // when running headless.
2101            ensureBootCompleted();
2102            return false;
2103        }
2104
2105        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2106                && mTopAction == null) {
2107            // We are running in factory test mode, but unable to find
2108            // the factory test app, so just sit around displaying the
2109            // error message and don't try to start anything.
2110            return false;
2111        }
2112        Intent intent = new Intent(
2113            mTopAction,
2114            mTopData != null ? Uri.parse(mTopData) : null);
2115        intent.setComponent(mTopComponent);
2116        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2117            intent.addCategory(Intent.CATEGORY_HOME);
2118        }
2119        ActivityInfo aInfo =
2120            intent.resolveActivityInfo(mContext.getPackageManager(),
2121                    STOCK_PM_FLAGS);
2122        if (aInfo != null) {
2123            intent.setComponent(new ComponentName(
2124                    aInfo.applicationInfo.packageName, aInfo.name));
2125            // Don't do this if the home app is currently being
2126            // instrumented.
2127            aInfo = new ActivityInfo(aInfo);
2128            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2129            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2130                    aInfo.applicationInfo.uid);
2131            if (app == null || app.instrumentationClass == null) {
2132                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2133                mMainStack.startActivityLocked(null, intent, null, aInfo,
2134                        null, null, 0, 0, 0, 0, null, false, null);
2135            }
2136        }
2137
2138        return true;
2139    }
2140
2141    /**
2142     * Starts the "new version setup screen" if appropriate.
2143     */
2144    void startSetupActivityLocked() {
2145        // Only do this once per boot.
2146        if (mCheckedForSetup) {
2147            return;
2148        }
2149
2150        // We will show this screen if the current one is a different
2151        // version than the last one shown, and we are not running in
2152        // low-level factory test mode.
2153        final ContentResolver resolver = mContext.getContentResolver();
2154        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2155                Settings.Secure.getInt(resolver,
2156                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2157            mCheckedForSetup = true;
2158
2159            // See if we should be showing the platform update setup UI.
2160            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2161            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2162                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2163
2164            // We don't allow third party apps to replace this.
2165            ResolveInfo ri = null;
2166            for (int i=0; ris != null && i<ris.size(); i++) {
2167                if ((ris.get(i).activityInfo.applicationInfo.flags
2168                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2169                    ri = ris.get(i);
2170                    break;
2171                }
2172            }
2173
2174            if (ri != null) {
2175                String vers = ri.activityInfo.metaData != null
2176                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2177                        : null;
2178                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2179                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2180                            Intent.METADATA_SETUP_VERSION);
2181                }
2182                String lastVers = Settings.Secure.getString(
2183                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2184                if (vers != null && !vers.equals(lastVers)) {
2185                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2186                    intent.setComponent(new ComponentName(
2187                            ri.activityInfo.packageName, ri.activityInfo.name));
2188                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2189                            null, null, 0, 0, 0, 0, null, false, null);
2190                }
2191            }
2192        }
2193    }
2194
2195    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2196        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2197    }
2198
2199    void enforceNotIsolatedCaller(String caller) {
2200        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2201            throw new SecurityException("Isolated process not allowed to call " + caller);
2202        }
2203    }
2204
2205    public int getFrontActivityScreenCompatMode() {
2206        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2207        synchronized (this) {
2208            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2209        }
2210    }
2211
2212    public void setFrontActivityScreenCompatMode(int mode) {
2213        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2214                "setFrontActivityScreenCompatMode");
2215        synchronized (this) {
2216            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2217        }
2218    }
2219
2220    public int getPackageScreenCompatMode(String packageName) {
2221        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2222        synchronized (this) {
2223            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2224        }
2225    }
2226
2227    public void setPackageScreenCompatMode(String packageName, int mode) {
2228        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2229                "setPackageScreenCompatMode");
2230        synchronized (this) {
2231            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2232        }
2233    }
2234
2235    public boolean getPackageAskScreenCompat(String packageName) {
2236        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2237        synchronized (this) {
2238            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2239        }
2240    }
2241
2242    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2243        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2244                "setPackageAskScreenCompat");
2245        synchronized (this) {
2246            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2247        }
2248    }
2249
2250    void reportResumedActivityLocked(ActivityRecord r) {
2251        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2252        updateUsageStats(r, true);
2253    }
2254
2255    private void dispatchProcessesChanged() {
2256        int N;
2257        synchronized (this) {
2258            N = mPendingProcessChanges.size();
2259            if (mActiveProcessChanges.length < N) {
2260                mActiveProcessChanges = new ProcessChangeItem[N];
2261            }
2262            mPendingProcessChanges.toArray(mActiveProcessChanges);
2263            mAvailProcessChanges.addAll(mPendingProcessChanges);
2264            mPendingProcessChanges.clear();
2265            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2266        }
2267        int i = mProcessObservers.beginBroadcast();
2268        while (i > 0) {
2269            i--;
2270            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2271            if (observer != null) {
2272                try {
2273                    for (int j=0; j<N; j++) {
2274                        ProcessChangeItem item = mActiveProcessChanges[j];
2275                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2276                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2277                                    + item.pid + " uid=" + item.uid + ": "
2278                                    + item.foregroundActivities);
2279                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2280                                    item.foregroundActivities);
2281                        }
2282                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2283                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2284                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2285                            observer.onImportanceChanged(item.pid, item.uid,
2286                                    item.importance);
2287                        }
2288                    }
2289                } catch (RemoteException e) {
2290                }
2291            }
2292        }
2293        mProcessObservers.finishBroadcast();
2294    }
2295
2296    private void dispatchProcessDied(int pid, int uid) {
2297        int i = mProcessObservers.beginBroadcast();
2298        while (i > 0) {
2299            i--;
2300            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2301            if (observer != null) {
2302                try {
2303                    observer.onProcessDied(pid, uid);
2304                } catch (RemoteException e) {
2305                }
2306            }
2307        }
2308        mProcessObservers.finishBroadcast();
2309    }
2310
2311    final void doPendingActivityLaunchesLocked(boolean doResume) {
2312        final int N = mPendingActivityLaunches.size();
2313        if (N <= 0) {
2314            return;
2315        }
2316        for (int i=0; i<N; i++) {
2317            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2318            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2319                    pal.startFlags, doResume && i == (N-1), null);
2320        }
2321        mPendingActivityLaunches.clear();
2322    }
2323
2324    public final int startActivity(IApplicationThread caller,
2325            Intent intent, String resolvedType, IBinder resultTo,
2326            String resultWho, int requestCode, int startFlags,
2327            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2328        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2329                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2330    }
2331
2332    public final int startActivityAsUser(IApplicationThread caller,
2333            Intent intent, String resolvedType, IBinder resultTo,
2334            String resultWho, int requestCode, int startFlags,
2335            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2336        enforceNotIsolatedCaller("startActivity");
2337        if (userId != UserHandle.getCallingUserId()) {
2338            // Requesting a different user, make sure that they have the permission
2339            if (checkComponentPermission(
2340                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2341                    Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
2342                    == PackageManager.PERMISSION_GRANTED) {
2343                // Translate to the current user id, if caller wasn't aware
2344                if (userId == UserHandle.USER_CURRENT) {
2345                    userId = mCurrentUserId;
2346                }
2347            } else {
2348                String msg = "Permission Denial: "
2349                        + "Request to startActivity as user " + userId
2350                        + " but is calling from user " + UserHandle.getCallingUserId()
2351                        + "; this requires "
2352                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
2353                Slog.w(TAG, msg);
2354                throw new SecurityException(msg);
2355            }
2356        } else {
2357            if (intent.getCategories() != null
2358                    && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2359                // Requesting home, set the identity to the current user
2360                // HACK!
2361                userId = mCurrentUserId;
2362            } else {
2363                // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
2364                // the current user's userId
2365                if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
2366                    userId = 0;
2367                } else {
2368                    userId = Binder.getOrigCallingUser();
2369                }
2370            }
2371        }
2372        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2373                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2374                null, null, options, userId);
2375    }
2376
2377    public final WaitResult startActivityAndWait(IApplicationThread caller,
2378            Intent intent, String resolvedType, IBinder resultTo,
2379            String resultWho, int requestCode, int startFlags, String profileFile,
2380            ParcelFileDescriptor profileFd, Bundle options) {
2381        enforceNotIsolatedCaller("startActivityAndWait");
2382        WaitResult res = new WaitResult();
2383        int userId = Binder.getOrigCallingUser();
2384        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2385                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2386                res, null, options, userId);
2387        return res;
2388    }
2389
2390    public final int startActivityWithConfig(IApplicationThread caller,
2391            Intent intent, String resolvedType, IBinder resultTo,
2392            String resultWho, int requestCode, int startFlags, Configuration config,
2393            Bundle options) {
2394        enforceNotIsolatedCaller("startActivityWithConfig");
2395        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2396                resultTo, resultWho, requestCode, startFlags,
2397                null, null, null, config, options, Binder.getOrigCallingUser());
2398        return ret;
2399    }
2400
2401    public int startActivityIntentSender(IApplicationThread caller,
2402            IntentSender intent, Intent fillInIntent, String resolvedType,
2403            IBinder resultTo, String resultWho, int requestCode,
2404            int flagsMask, int flagsValues, Bundle options) {
2405        enforceNotIsolatedCaller("startActivityIntentSender");
2406        // Refuse possible leaked file descriptors
2407        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2408            throw new IllegalArgumentException("File descriptors passed in Intent");
2409        }
2410
2411        IIntentSender sender = intent.getTarget();
2412        if (!(sender instanceof PendingIntentRecord)) {
2413            throw new IllegalArgumentException("Bad PendingIntent object");
2414        }
2415
2416        PendingIntentRecord pir = (PendingIntentRecord)sender;
2417
2418        synchronized (this) {
2419            // If this is coming from the currently resumed activity, it is
2420            // effectively saying that app switches are allowed at this point.
2421            if (mMainStack.mResumedActivity != null
2422                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2423                            Binder.getCallingUid()) {
2424                mAppSwitchesAllowedTime = 0;
2425            }
2426        }
2427        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2428                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2429        return ret;
2430    }
2431
2432    public boolean startNextMatchingActivity(IBinder callingActivity,
2433            Intent intent, Bundle options) {
2434        // Refuse possible leaked file descriptors
2435        if (intent != null && intent.hasFileDescriptors() == true) {
2436            throw new IllegalArgumentException("File descriptors passed in Intent");
2437        }
2438
2439        synchronized (this) {
2440            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2441            if (r == null) {
2442                ActivityOptions.abort(options);
2443                return false;
2444            }
2445            if (r.app == null || r.app.thread == null) {
2446                // The caller is not running...  d'oh!
2447                ActivityOptions.abort(options);
2448                return false;
2449            }
2450            intent = new Intent(intent);
2451            // The caller is not allowed to change the data.
2452            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2453            // And we are resetting to find the next component...
2454            intent.setComponent(null);
2455
2456            ActivityInfo aInfo = null;
2457            try {
2458                List<ResolveInfo> resolves =
2459                    AppGlobals.getPackageManager().queryIntentActivities(
2460                            intent, r.resolvedType,
2461                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2462                            UserHandle.getCallingUserId());
2463
2464                // Look for the original activity in the list...
2465                final int N = resolves != null ? resolves.size() : 0;
2466                for (int i=0; i<N; i++) {
2467                    ResolveInfo rInfo = resolves.get(i);
2468                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2469                            && rInfo.activityInfo.name.equals(r.info.name)) {
2470                        // We found the current one...  the next matching is
2471                        // after it.
2472                        i++;
2473                        if (i<N) {
2474                            aInfo = resolves.get(i).activityInfo;
2475                        }
2476                        break;
2477                    }
2478                }
2479            } catch (RemoteException e) {
2480            }
2481
2482            if (aInfo == null) {
2483                // Nobody who is next!
2484                ActivityOptions.abort(options);
2485                return false;
2486            }
2487
2488            intent.setComponent(new ComponentName(
2489                    aInfo.applicationInfo.packageName, aInfo.name));
2490            intent.setFlags(intent.getFlags()&~(
2491                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2492                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2493                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2494                    Intent.FLAG_ACTIVITY_NEW_TASK));
2495
2496            // Okay now we need to start the new activity, replacing the
2497            // currently running activity.  This is a little tricky because
2498            // we want to start the new one as if the current one is finished,
2499            // but not finish the current one first so that there is no flicker.
2500            // And thus...
2501            final boolean wasFinishing = r.finishing;
2502            r.finishing = true;
2503
2504            // Propagate reply information over to the new activity.
2505            final ActivityRecord resultTo = r.resultTo;
2506            final String resultWho = r.resultWho;
2507            final int requestCode = r.requestCode;
2508            r.resultTo = null;
2509            if (resultTo != null) {
2510                resultTo.removeResultsLocked(r, resultWho, requestCode);
2511            }
2512
2513            final long origId = Binder.clearCallingIdentity();
2514            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2515                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2516                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2517                    options, false, null);
2518            Binder.restoreCallingIdentity(origId);
2519
2520            r.finishing = wasFinishing;
2521            if (res != ActivityManager.START_SUCCESS) {
2522                return false;
2523            }
2524            return true;
2525        }
2526    }
2527
2528    public final int startActivityInPackage(int uid,
2529            Intent intent, String resolvedType, IBinder resultTo,
2530            String resultWho, int requestCode, int startFlags, Bundle options) {
2531
2532        // This is so super not safe, that only the system (or okay root)
2533        // can do it.
2534        final int callingUid = Binder.getCallingUid();
2535        if (callingUid != 0 && callingUid != Process.myUid()) {
2536            throw new SecurityException(
2537                    "startActivityInPackage only available to the system");
2538        }
2539
2540        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2541                resultTo, resultWho, requestCode, startFlags,
2542                null, null, null, null, options, UserHandle.getUserId(uid));
2543        return ret;
2544    }
2545
2546    public final int startActivities(IApplicationThread caller,
2547            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2548        enforceNotIsolatedCaller("startActivities");
2549        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2550                options, Binder.getOrigCallingUser());
2551        return ret;
2552    }
2553
2554    public final int startActivitiesInPackage(int uid,
2555            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2556            Bundle options) {
2557
2558        // This is so super not safe, that only the system (or okay root)
2559        // can do it.
2560        final int callingUid = Binder.getCallingUid();
2561        if (callingUid != 0 && callingUid != Process.myUid()) {
2562            throw new SecurityException(
2563                    "startActivityInPackage only available to the system");
2564        }
2565        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2566                options, UserHandle.getUserId(uid));
2567        return ret;
2568    }
2569
2570    final void addRecentTaskLocked(TaskRecord task) {
2571        int N = mRecentTasks.size();
2572        // Quick case: check if the top-most recent task is the same.
2573        if (N > 0 && mRecentTasks.get(0) == task) {
2574            return;
2575        }
2576        // Remove any existing entries that are the same kind of task.
2577        for (int i=0; i<N; i++) {
2578            TaskRecord tr = mRecentTasks.get(i);
2579            if (task.userId == tr.userId
2580                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2581                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2582                mRecentTasks.remove(i);
2583                i--;
2584                N--;
2585                if (task.intent == null) {
2586                    // If the new recent task we are adding is not fully
2587                    // specified, then replace it with the existing recent task.
2588                    task = tr;
2589                }
2590            }
2591        }
2592        if (N >= MAX_RECENT_TASKS) {
2593            mRecentTasks.remove(N-1);
2594        }
2595        mRecentTasks.add(0, task);
2596    }
2597
2598    public void setRequestedOrientation(IBinder token,
2599            int requestedOrientation) {
2600        synchronized (this) {
2601            ActivityRecord r = mMainStack.isInStackLocked(token);
2602            if (r == null) {
2603                return;
2604            }
2605            final long origId = Binder.clearCallingIdentity();
2606            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2607            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2608                    mConfiguration,
2609                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2610            if (config != null) {
2611                r.frozenBeforeDestroy = true;
2612                if (!updateConfigurationLocked(config, r, false, false)) {
2613                    mMainStack.resumeTopActivityLocked(null);
2614                }
2615            }
2616            Binder.restoreCallingIdentity(origId);
2617        }
2618    }
2619
2620    public int getRequestedOrientation(IBinder token) {
2621        synchronized (this) {
2622            ActivityRecord r = mMainStack.isInStackLocked(token);
2623            if (r == null) {
2624                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2625            }
2626            return mWindowManager.getAppOrientation(r.appToken);
2627        }
2628    }
2629
2630    /**
2631     * This is the internal entry point for handling Activity.finish().
2632     *
2633     * @param token The Binder token referencing the Activity we want to finish.
2634     * @param resultCode Result code, if any, from this Activity.
2635     * @param resultData Result data (Intent), if any, from this Activity.
2636     *
2637     * @return Returns true if the activity successfully finished, or false if it is still running.
2638     */
2639    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2640        // Refuse possible leaked file descriptors
2641        if (resultData != null && resultData.hasFileDescriptors() == true) {
2642            throw new IllegalArgumentException("File descriptors passed in Intent");
2643        }
2644
2645        synchronized(this) {
2646            if (mController != null) {
2647                // Find the first activity that is not finishing.
2648                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2649                if (next != null) {
2650                    // ask watcher if this is allowed
2651                    boolean resumeOK = true;
2652                    try {
2653                        resumeOK = mController.activityResuming(next.packageName);
2654                    } catch (RemoteException e) {
2655                        mController = null;
2656                    }
2657
2658                    if (!resumeOK) {
2659                        return false;
2660                    }
2661                }
2662            }
2663            final long origId = Binder.clearCallingIdentity();
2664            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2665                    resultData, "app-request");
2666            Binder.restoreCallingIdentity(origId);
2667            return res;
2668        }
2669    }
2670
2671    public final void finishHeavyWeightApp() {
2672        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2673                != PackageManager.PERMISSION_GRANTED) {
2674            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2675                    + Binder.getCallingPid()
2676                    + ", uid=" + Binder.getCallingUid()
2677                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2678            Slog.w(TAG, msg);
2679            throw new SecurityException(msg);
2680        }
2681
2682        synchronized(this) {
2683            if (mHeavyWeightProcess == null) {
2684                return;
2685            }
2686
2687            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2688                    mHeavyWeightProcess.activities);
2689            for (int i=0; i<activities.size(); i++) {
2690                ActivityRecord r = activities.get(i);
2691                if (!r.finishing) {
2692                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2693                    if (index >= 0) {
2694                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2695                                null, "finish-heavy");
2696                    }
2697                }
2698            }
2699
2700            mHeavyWeightProcess = null;
2701            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2702        }
2703    }
2704
2705    public void crashApplication(int uid, int initialPid, String packageName,
2706            String message) {
2707        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2708                != PackageManager.PERMISSION_GRANTED) {
2709            String msg = "Permission Denial: crashApplication() from pid="
2710                    + Binder.getCallingPid()
2711                    + ", uid=" + Binder.getCallingUid()
2712                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2713            Slog.w(TAG, msg);
2714            throw new SecurityException(msg);
2715        }
2716
2717        synchronized(this) {
2718            ProcessRecord proc = null;
2719
2720            // Figure out which process to kill.  We don't trust that initialPid
2721            // still has any relation to current pids, so must scan through the
2722            // list.
2723            synchronized (mPidsSelfLocked) {
2724                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2725                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2726                    if (p.uid != uid) {
2727                        continue;
2728                    }
2729                    if (p.pid == initialPid) {
2730                        proc = p;
2731                        break;
2732                    }
2733                    for (String str : p.pkgList) {
2734                        if (str.equals(packageName)) {
2735                            proc = p;
2736                        }
2737                    }
2738                }
2739            }
2740
2741            if (proc == null) {
2742                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2743                        + " initialPid=" + initialPid
2744                        + " packageName=" + packageName);
2745                return;
2746            }
2747
2748            if (proc.thread != null) {
2749                if (proc.pid == Process.myPid()) {
2750                    Log.w(TAG, "crashApplication: trying to crash self!");
2751                    return;
2752                }
2753                long ident = Binder.clearCallingIdentity();
2754                try {
2755                    proc.thread.scheduleCrash(message);
2756                } catch (RemoteException e) {
2757                }
2758                Binder.restoreCallingIdentity(ident);
2759            }
2760        }
2761    }
2762
2763    public final void finishSubActivity(IBinder token, String resultWho,
2764            int requestCode) {
2765        synchronized(this) {
2766            final long origId = Binder.clearCallingIdentity();
2767            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2768            Binder.restoreCallingIdentity(origId);
2769        }
2770    }
2771
2772    public boolean finishActivityAffinity(IBinder token) {
2773        synchronized(this) {
2774            final long origId = Binder.clearCallingIdentity();
2775            boolean res = mMainStack.finishActivityAffinityLocked(token);
2776            Binder.restoreCallingIdentity(origId);
2777            return res;
2778        }
2779    }
2780
2781    public boolean willActivityBeVisible(IBinder token) {
2782        synchronized(this) {
2783            int i;
2784            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2785                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2786                if (r.appToken == token) {
2787                    return true;
2788                }
2789                if (r.fullscreen && !r.finishing) {
2790                    return false;
2791                }
2792            }
2793            return true;
2794        }
2795    }
2796
2797    public void overridePendingTransition(IBinder token, String packageName,
2798            int enterAnim, int exitAnim) {
2799        synchronized(this) {
2800            ActivityRecord self = mMainStack.isInStackLocked(token);
2801            if (self == null) {
2802                return;
2803            }
2804
2805            final long origId = Binder.clearCallingIdentity();
2806
2807            if (self.state == ActivityState.RESUMED
2808                    || self.state == ActivityState.PAUSING) {
2809                mWindowManager.overridePendingAppTransition(packageName,
2810                        enterAnim, exitAnim, null);
2811            }
2812
2813            Binder.restoreCallingIdentity(origId);
2814        }
2815    }
2816
2817    /**
2818     * Main function for removing an existing process from the activity manager
2819     * as a result of that process going away.  Clears out all connections
2820     * to the process.
2821     */
2822    private final void handleAppDiedLocked(ProcessRecord app,
2823            boolean restarting, boolean allowRestart) {
2824        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2825        if (!restarting) {
2826            mLruProcesses.remove(app);
2827        }
2828
2829        if (mProfileProc == app) {
2830            clearProfilerLocked();
2831        }
2832
2833        // Just in case...
2834        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2835            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2836            mMainStack.mPausingActivity = null;
2837        }
2838        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2839            mMainStack.mLastPausedActivity = null;
2840        }
2841
2842        // Remove this application's activities from active lists.
2843        mMainStack.removeHistoryRecordsForAppLocked(app);
2844
2845        boolean atTop = true;
2846        boolean hasVisibleActivities = false;
2847
2848        // Clean out the history list.
2849        int i = mMainStack.mHistory.size();
2850        if (localLOGV) Slog.v(
2851            TAG, "Removing app " + app + " from history with " + i + " entries");
2852        while (i > 0) {
2853            i--;
2854            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2855            if (localLOGV) Slog.v(
2856                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2857            if (r.app == app) {
2858                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2859                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2860                        RuntimeException here = new RuntimeException("here");
2861                        here.fillInStackTrace();
2862                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2863                                + ": haveState=" + r.haveState
2864                                + " stateNotNeeded=" + r.stateNotNeeded
2865                                + " finishing=" + r.finishing
2866                                + " state=" + r.state, here);
2867                    }
2868                    if (!r.finishing) {
2869                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2870                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2871                                System.identityHashCode(r),
2872                                r.task.taskId, r.shortComponentName,
2873                                "proc died without state saved");
2874                    }
2875                    mMainStack.removeActivityFromHistoryLocked(r);
2876
2877                } else {
2878                    // We have the current state for this activity, so
2879                    // it can be restarted later when needed.
2880                    if (localLOGV) Slog.v(
2881                        TAG, "Keeping entry, setting app to null");
2882                    if (r.visible) {
2883                        hasVisibleActivities = true;
2884                    }
2885                    r.app = null;
2886                    r.nowVisible = false;
2887                    if (!r.haveState) {
2888                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2889                                "App died, clearing saved state of " + r);
2890                        r.icicle = null;
2891                    }
2892                }
2893
2894                r.stack.cleanUpActivityLocked(r, true, true);
2895            }
2896            atTop = false;
2897        }
2898
2899        app.activities.clear();
2900
2901        if (app.instrumentationClass != null) {
2902            Slog.w(TAG, "Crash of app " + app.processName
2903                  + " running instrumentation " + app.instrumentationClass);
2904            Bundle info = new Bundle();
2905            info.putString("shortMsg", "Process crashed.");
2906            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2907        }
2908
2909        if (!restarting) {
2910            if (!mMainStack.resumeTopActivityLocked(null)) {
2911                // If there was nothing to resume, and we are not already
2912                // restarting this process, but there is a visible activity that
2913                // is hosted by the process...  then make sure all visible
2914                // activities are running, taking care of restarting this
2915                // process.
2916                if (hasVisibleActivities) {
2917                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2918                }
2919            }
2920        }
2921    }
2922
2923    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2924        IBinder threadBinder = thread.asBinder();
2925        // Find the application record.
2926        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2927            ProcessRecord rec = mLruProcesses.get(i);
2928            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2929                return i;
2930            }
2931        }
2932        return -1;
2933    }
2934
2935    final ProcessRecord getRecordForAppLocked(
2936            IApplicationThread thread) {
2937        if (thread == null) {
2938            return null;
2939        }
2940
2941        int appIndex = getLRURecordIndexForAppLocked(thread);
2942        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2943    }
2944
2945    final void appDiedLocked(ProcessRecord app, int pid,
2946            IApplicationThread thread) {
2947
2948        mProcDeaths[0]++;
2949
2950        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2951        synchronized (stats) {
2952            stats.noteProcessDiedLocked(app.info.uid, pid);
2953        }
2954
2955        // Clean up already done if the process has been re-started.
2956        if (app.pid == pid && app.thread != null &&
2957                app.thread.asBinder() == thread.asBinder()) {
2958            if (!app.killedBackground) {
2959                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2960                        + ") has died.");
2961            }
2962            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2963            if (localLOGV) Slog.v(
2964                TAG, "Dying app: " + app + ", pid: " + pid
2965                + ", thread: " + thread.asBinder());
2966            boolean doLowMem = app.instrumentationClass == null;
2967            handleAppDiedLocked(app, false, true);
2968
2969            if (doLowMem) {
2970                // If there are no longer any background processes running,
2971                // and the app that died was not running instrumentation,
2972                // then tell everyone we are now low on memory.
2973                boolean haveBg = false;
2974                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2975                    ProcessRecord rec = mLruProcesses.get(i);
2976                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2977                        haveBg = true;
2978                        break;
2979                    }
2980                }
2981
2982                if (!haveBg) {
2983                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2984                    long now = SystemClock.uptimeMillis();
2985                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2986                        ProcessRecord rec = mLruProcesses.get(i);
2987                        if (rec != app && rec.thread != null &&
2988                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2989                            // The low memory report is overriding any current
2990                            // state for a GC request.  Make sure to do
2991                            // heavy/important/visible/foreground processes first.
2992                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
2993                                rec.lastRequestedGc = 0;
2994                            } else {
2995                                rec.lastRequestedGc = rec.lastLowMemory;
2996                            }
2997                            rec.reportLowMemory = true;
2998                            rec.lastLowMemory = now;
2999                            mProcessesToGc.remove(rec);
3000                            addProcessToGcListLocked(rec);
3001                        }
3002                    }
3003                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3004                    scheduleAppGcsLocked();
3005                }
3006            }
3007        } else if (app.pid != pid) {
3008            // A new process has already been started.
3009            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3010                    + ") has died and restarted (pid " + app.pid + ").");
3011            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3012        } else if (DEBUG_PROCESSES) {
3013            Slog.d(TAG, "Received spurious death notification for thread "
3014                    + thread.asBinder());
3015        }
3016    }
3017
3018    /**
3019     * If a stack trace dump file is configured, dump process stack traces.
3020     * @param clearTraces causes the dump file to be erased prior to the new
3021     *    traces being written, if true; when false, the new traces will be
3022     *    appended to any existing file content.
3023     * @param firstPids of dalvik VM processes to dump stack traces for first
3024     * @param lastPids of dalvik VM processes to dump stack traces for last
3025     * @param nativeProcs optional list of native process names to dump stack crawls
3026     * @return file containing stack traces, or null if no dump file is configured
3027     */
3028    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3029            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3030        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3031        if (tracesPath == null || tracesPath.length() == 0) {
3032            return null;
3033        }
3034
3035        File tracesFile = new File(tracesPath);
3036        try {
3037            File tracesDir = tracesFile.getParentFile();
3038            if (!tracesDir.exists()) tracesFile.mkdirs();
3039            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3040
3041            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3042            tracesFile.createNewFile();
3043            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3044        } catch (IOException e) {
3045            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3046            return null;
3047        }
3048
3049        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3050        return tracesFile;
3051    }
3052
3053    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3054            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3055        // Use a FileObserver to detect when traces finish writing.
3056        // The order of traces is considered important to maintain for legibility.
3057        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3058            public synchronized void onEvent(int event, String path) { notify(); }
3059        };
3060
3061        try {
3062            observer.startWatching();
3063
3064            // First collect all of the stacks of the most important pids.
3065            if (firstPids != null) {
3066                try {
3067                    int num = firstPids.size();
3068                    for (int i = 0; i < num; i++) {
3069                        synchronized (observer) {
3070                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3071                            observer.wait(200);  // Wait for write-close, give up after 200msec
3072                        }
3073                    }
3074                } catch (InterruptedException e) {
3075                    Log.wtf(TAG, e);
3076                }
3077            }
3078
3079            // Next measure CPU usage.
3080            if (processStats != null) {
3081                processStats.init();
3082                System.gc();
3083                processStats.update();
3084                try {
3085                    synchronized (processStats) {
3086                        processStats.wait(500); // measure over 1/2 second.
3087                    }
3088                } catch (InterruptedException e) {
3089                }
3090                processStats.update();
3091
3092                // We'll take the stack crawls of just the top apps using CPU.
3093                final int N = processStats.countWorkingStats();
3094                int numProcs = 0;
3095                for (int i=0; i<N && numProcs<5; i++) {
3096                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3097                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3098                        numProcs++;
3099                        try {
3100                            synchronized (observer) {
3101                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3102                                observer.wait(200);  // Wait for write-close, give up after 200msec
3103                            }
3104                        } catch (InterruptedException e) {
3105                            Log.wtf(TAG, e);
3106                        }
3107
3108                    }
3109                }
3110            }
3111
3112        } finally {
3113            observer.stopWatching();
3114        }
3115
3116        if (nativeProcs != null) {
3117            int[] pids = Process.getPidsForCommands(nativeProcs);
3118            if (pids != null) {
3119                for (int pid : pids) {
3120                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3121                }
3122            }
3123        }
3124    }
3125
3126    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3127        if (true || IS_USER_BUILD) {
3128            return;
3129        }
3130        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3131        if (tracesPath == null || tracesPath.length() == 0) {
3132            return;
3133        }
3134
3135        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3136        StrictMode.allowThreadDiskWrites();
3137        try {
3138            final File tracesFile = new File(tracesPath);
3139            final File tracesDir = tracesFile.getParentFile();
3140            final File tracesTmp = new File(tracesDir, "__tmp__");
3141            try {
3142                if (!tracesDir.exists()) tracesFile.mkdirs();
3143                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3144
3145                if (tracesFile.exists()) {
3146                    tracesTmp.delete();
3147                    tracesFile.renameTo(tracesTmp);
3148                }
3149                StringBuilder sb = new StringBuilder();
3150                Time tobj = new Time();
3151                tobj.set(System.currentTimeMillis());
3152                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3153                sb.append(": ");
3154                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3155                sb.append(" since ");
3156                sb.append(msg);
3157                FileOutputStream fos = new FileOutputStream(tracesFile);
3158                fos.write(sb.toString().getBytes());
3159                if (app == null) {
3160                    fos.write("\n*** No application process!".getBytes());
3161                }
3162                fos.close();
3163                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3164            } catch (IOException e) {
3165                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3166                return;
3167            }
3168
3169            if (app != null) {
3170                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3171                firstPids.add(app.pid);
3172                dumpStackTraces(tracesPath, firstPids, null, null, null);
3173            }
3174
3175            File lastTracesFile = null;
3176            File curTracesFile = null;
3177            for (int i=9; i>=0; i--) {
3178                String name = String.format("slow%02d.txt", i);
3179                curTracesFile = new File(tracesDir, name);
3180                if (curTracesFile.exists()) {
3181                    if (lastTracesFile != null) {
3182                        curTracesFile.renameTo(lastTracesFile);
3183                    } else {
3184                        curTracesFile.delete();
3185                    }
3186                }
3187                lastTracesFile = curTracesFile;
3188            }
3189            tracesFile.renameTo(curTracesFile);
3190            if (tracesTmp.exists()) {
3191                tracesTmp.renameTo(tracesFile);
3192            }
3193        } finally {
3194            StrictMode.setThreadPolicy(oldPolicy);
3195        }
3196    }
3197
3198    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3199            ActivityRecord parent, final String annotation) {
3200        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3201        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3202
3203        if (mController != null) {
3204            try {
3205                // 0 == continue, -1 = kill process immediately
3206                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3207                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3208            } catch (RemoteException e) {
3209                mController = null;
3210            }
3211        }
3212
3213        long anrTime = SystemClock.uptimeMillis();
3214        if (MONITOR_CPU_USAGE) {
3215            updateCpuStatsNow();
3216        }
3217
3218        synchronized (this) {
3219            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3220            if (mShuttingDown) {
3221                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3222                return;
3223            } else if (app.notResponding) {
3224                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3225                return;
3226            } else if (app.crashing) {
3227                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3228                return;
3229            }
3230
3231            // In case we come through here for the same app before completing
3232            // this one, mark as anring now so we will bail out.
3233            app.notResponding = true;
3234
3235            // Log the ANR to the event log.
3236            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3237                    annotation);
3238
3239            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3240            firstPids.add(app.pid);
3241
3242            int parentPid = app.pid;
3243            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3244            if (parentPid != app.pid) firstPids.add(parentPid);
3245
3246            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3247
3248            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3249                ProcessRecord r = mLruProcesses.get(i);
3250                if (r != null && r.thread != null) {
3251                    int pid = r.pid;
3252                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3253                        if (r.persistent) {
3254                            firstPids.add(pid);
3255                        } else {
3256                            lastPids.put(pid, Boolean.TRUE);
3257                        }
3258                    }
3259                }
3260            }
3261        }
3262
3263        // Log the ANR to the main log.
3264        StringBuilder info = new StringBuilder();
3265        info.setLength(0);
3266        info.append("ANR in ").append(app.processName);
3267        if (activity != null && activity.shortComponentName != null) {
3268            info.append(" (").append(activity.shortComponentName).append(")");
3269        }
3270        info.append("\n");
3271        if (annotation != null) {
3272            info.append("Reason: ").append(annotation).append("\n");
3273        }
3274        if (parent != null && parent != activity) {
3275            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3276        }
3277
3278        final ProcessStats processStats = new ProcessStats(true);
3279
3280        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3281
3282        String cpuInfo = null;
3283        if (MONITOR_CPU_USAGE) {
3284            updateCpuStatsNow();
3285            synchronized (mProcessStatsThread) {
3286                cpuInfo = mProcessStats.printCurrentState(anrTime);
3287            }
3288            info.append(processStats.printCurrentLoad());
3289            info.append(cpuInfo);
3290        }
3291
3292        info.append(processStats.printCurrentState(anrTime));
3293
3294        Slog.e(TAG, info.toString());
3295        if (tracesFile == null) {
3296            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3297            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3298        }
3299
3300        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3301                cpuInfo, tracesFile, null);
3302
3303        if (mController != null) {
3304            try {
3305                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3306                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3307                if (res != 0) {
3308                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3309                    return;
3310                }
3311            } catch (RemoteException e) {
3312                mController = null;
3313            }
3314        }
3315
3316        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3317        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3318                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3319
3320        synchronized (this) {
3321            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3322                Slog.w(TAG, "Killing " + app + ": background ANR");
3323                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3324                        app.processName, app.setAdj, "background ANR");
3325                Process.killProcessQuiet(app.pid);
3326                return;
3327            }
3328
3329            // Set the app's notResponding state, and look up the errorReportReceiver
3330            makeAppNotRespondingLocked(app,
3331                    activity != null ? activity.shortComponentName : null,
3332                    annotation != null ? "ANR " + annotation : "ANR",
3333                    info.toString());
3334
3335            // Bring up the infamous App Not Responding dialog
3336            Message msg = Message.obtain();
3337            HashMap map = new HashMap();
3338            msg.what = SHOW_NOT_RESPONDING_MSG;
3339            msg.obj = map;
3340            map.put("app", app);
3341            if (activity != null) {
3342                map.put("activity", activity);
3343            }
3344
3345            mHandler.sendMessage(msg);
3346        }
3347    }
3348
3349    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3350        if (!mLaunchWarningShown) {
3351            mLaunchWarningShown = true;
3352            mHandler.post(new Runnable() {
3353                @Override
3354                public void run() {
3355                    synchronized (ActivityManagerService.this) {
3356                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3357                        d.show();
3358                        mHandler.postDelayed(new Runnable() {
3359                            @Override
3360                            public void run() {
3361                                synchronized (ActivityManagerService.this) {
3362                                    d.dismiss();
3363                                    mLaunchWarningShown = false;
3364                                }
3365                            }
3366                        }, 4000);
3367                    }
3368                }
3369            });
3370        }
3371    }
3372
3373    public boolean clearApplicationUserData(final String packageName,
3374            final IPackageDataObserver observer, final int userId) {
3375        enforceNotIsolatedCaller("clearApplicationUserData");
3376        int uid = Binder.getCallingUid();
3377        int pid = Binder.getCallingPid();
3378        long callingId = Binder.clearCallingIdentity();
3379        try {
3380            IPackageManager pm = AppGlobals.getPackageManager();
3381            int pkgUid = -1;
3382            synchronized(this) {
3383                try {
3384                    pkgUid = pm.getPackageUid(packageName, userId);
3385                } catch (RemoteException e) {
3386                }
3387                if (pkgUid == -1) {
3388                    Slog.w(TAG, "Invalid packageName:" + packageName);
3389                    return false;
3390                }
3391                if (uid == pkgUid || checkComponentPermission(
3392                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3393                        pid, uid, -1, true)
3394                        == PackageManager.PERMISSION_GRANTED) {
3395                    forceStopPackageLocked(packageName, pkgUid);
3396                } else {
3397                    throw new SecurityException(pid+" does not have permission:"+
3398                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3399                                    "for process:"+packageName);
3400                }
3401            }
3402
3403            try {
3404                //clear application user data
3405                pm.clearApplicationUserData(packageName, observer, userId);
3406                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3407                        Uri.fromParts("package", packageName, null));
3408                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3409                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3410                        null, null, 0, null, null, null, false, false, userId);
3411            } catch (RemoteException e) {
3412            }
3413        } finally {
3414            Binder.restoreCallingIdentity(callingId);
3415        }
3416        return true;
3417    }
3418
3419    public void killBackgroundProcesses(final String packageName) {
3420        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3421                != PackageManager.PERMISSION_GRANTED &&
3422                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3423                        != PackageManager.PERMISSION_GRANTED) {
3424            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3425                    + Binder.getCallingPid()
3426                    + ", uid=" + Binder.getCallingUid()
3427                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3428            Slog.w(TAG, msg);
3429            throw new SecurityException(msg);
3430        }
3431
3432        int userId = UserHandle.getCallingUserId();
3433        long callingId = Binder.clearCallingIdentity();
3434        try {
3435            IPackageManager pm = AppGlobals.getPackageManager();
3436            int pkgUid = -1;
3437            synchronized(this) {
3438                try {
3439                    pkgUid = pm.getPackageUid(packageName, userId);
3440                } catch (RemoteException e) {
3441                }
3442                if (pkgUid == -1) {
3443                    Slog.w(TAG, "Invalid packageName: " + packageName);
3444                    return;
3445                }
3446                killPackageProcessesLocked(packageName, pkgUid,
3447                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3448            }
3449        } finally {
3450            Binder.restoreCallingIdentity(callingId);
3451        }
3452    }
3453
3454    public void killAllBackgroundProcesses() {
3455        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3456                != PackageManager.PERMISSION_GRANTED) {
3457            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3458                    + Binder.getCallingPid()
3459                    + ", uid=" + Binder.getCallingUid()
3460                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3461            Slog.w(TAG, msg);
3462            throw new SecurityException(msg);
3463        }
3464
3465        long callingId = Binder.clearCallingIdentity();
3466        try {
3467            synchronized(this) {
3468                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3469                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3470                    final int NA = apps.size();
3471                    for (int ia=0; ia<NA; ia++) {
3472                        ProcessRecord app = apps.valueAt(ia);
3473                        if (app.persistent) {
3474                            // we don't kill persistent processes
3475                            continue;
3476                        }
3477                        if (app.removed) {
3478                            procs.add(app);
3479                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3480                            app.removed = true;
3481                            procs.add(app);
3482                        }
3483                    }
3484                }
3485
3486                int N = procs.size();
3487                for (int i=0; i<N; i++) {
3488                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3489                }
3490            }
3491        } finally {
3492            Binder.restoreCallingIdentity(callingId);
3493        }
3494    }
3495
3496    public void forceStopPackage(final String packageName) {
3497        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3498                != PackageManager.PERMISSION_GRANTED) {
3499            String msg = "Permission Denial: forceStopPackage() from pid="
3500                    + Binder.getCallingPid()
3501                    + ", uid=" + Binder.getCallingUid()
3502                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3503            Slog.w(TAG, msg);
3504            throw new SecurityException(msg);
3505        }
3506        final int userId = UserHandle.getCallingUserId();
3507        long callingId = Binder.clearCallingIdentity();
3508        try {
3509            IPackageManager pm = AppGlobals.getPackageManager();
3510            int pkgUid = -1;
3511            synchronized(this) {
3512                try {
3513                    pkgUid = pm.getPackageUid(packageName, userId);
3514                } catch (RemoteException e) {
3515                }
3516                if (pkgUid == -1) {
3517                    Slog.w(TAG, "Invalid packageName: " + packageName);
3518                    return;
3519                }
3520                forceStopPackageLocked(packageName, pkgUid);
3521                try {
3522                    pm.setPackageStoppedState(packageName, true, userId);
3523                } catch (RemoteException e) {
3524                } catch (IllegalArgumentException e) {
3525                    Slog.w(TAG, "Failed trying to unstop package "
3526                            + packageName + ": " + e);
3527                }
3528            }
3529        } finally {
3530            Binder.restoreCallingIdentity(callingId);
3531        }
3532    }
3533
3534    /*
3535     * The pkg name and uid have to be specified.
3536     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3537     */
3538    public void killApplicationWithUid(String pkg, int uid) {
3539        if (pkg == null) {
3540            return;
3541        }
3542        // Make sure the uid is valid.
3543        if (uid < 0) {
3544            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3545            return;
3546        }
3547        int callerUid = Binder.getCallingUid();
3548        // Only the system server can kill an application
3549        if (callerUid == Process.SYSTEM_UID) {
3550            // Post an aysnc message to kill the application
3551            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3552            msg.arg1 = uid;
3553            msg.arg2 = 0;
3554            msg.obj = pkg;
3555            mHandler.sendMessage(msg);
3556        } else {
3557            throw new SecurityException(callerUid + " cannot kill pkg: " +
3558                    pkg);
3559        }
3560    }
3561
3562    public void closeSystemDialogs(String reason) {
3563        enforceNotIsolatedCaller("closeSystemDialogs");
3564
3565        final int uid = Binder.getCallingUid();
3566        final long origId = Binder.clearCallingIdentity();
3567        synchronized (this) {
3568            closeSystemDialogsLocked(uid, reason);
3569        }
3570        Binder.restoreCallingIdentity(origId);
3571    }
3572
3573    void closeSystemDialogsLocked(int callingUid, String reason) {
3574        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3575        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3576        if (reason != null) {
3577            intent.putExtra("reason", reason);
3578        }
3579        mWindowManager.closeSystemDialogs(reason);
3580
3581        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3582            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3583            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3584                r.stack.finishActivityLocked(r, i,
3585                        Activity.RESULT_CANCELED, null, "close-sys");
3586            }
3587        }
3588
3589        broadcastIntentLocked(null, null, intent, null,
3590                null, 0, null, null, null, false, false, -1,
3591                callingUid, 0 /* TODO: Verify */);
3592    }
3593
3594    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3595            throws RemoteException {
3596        enforceNotIsolatedCaller("getProcessMemoryInfo");
3597        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3598        for (int i=pids.length-1; i>=0; i--) {
3599            infos[i] = new Debug.MemoryInfo();
3600            Debug.getMemoryInfo(pids[i], infos[i]);
3601        }
3602        return infos;
3603    }
3604
3605    public long[] getProcessPss(int[] pids) throws RemoteException {
3606        enforceNotIsolatedCaller("getProcessPss");
3607        long[] pss = new long[pids.length];
3608        for (int i=pids.length-1; i>=0; i--) {
3609            pss[i] = Debug.getPss(pids[i]);
3610        }
3611        return pss;
3612    }
3613
3614    public void killApplicationProcess(String processName, int uid) {
3615        if (processName == null) {
3616            return;
3617        }
3618
3619        int callerUid = Binder.getCallingUid();
3620        // Only the system server can kill an application
3621        if (callerUid == Process.SYSTEM_UID) {
3622            synchronized (this) {
3623                ProcessRecord app = getProcessRecordLocked(processName, uid);
3624                if (app != null && app.thread != null) {
3625                    try {
3626                        app.thread.scheduleSuicide();
3627                    } catch (RemoteException e) {
3628                        // If the other end already died, then our work here is done.
3629                    }
3630                } else {
3631                    Slog.w(TAG, "Process/uid not found attempting kill of "
3632                            + processName + " / " + uid);
3633                }
3634            }
3635        } else {
3636            throw new SecurityException(callerUid + " cannot kill app process: " +
3637                    processName);
3638        }
3639    }
3640
3641    private void forceStopPackageLocked(final String packageName, int uid) {
3642        forceStopPackageLocked(packageName, uid, false, false, true, false, UserHandle.getUserId(uid));
3643        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3644                Uri.fromParts("package", packageName, null));
3645        if (!mProcessesReady) {
3646            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3647        }
3648        intent.putExtra(Intent.EXTRA_UID, uid);
3649        broadcastIntentLocked(null, null, intent,
3650                null, null, 0, null, null, null,
3651                false, false,
3652                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3653    }
3654
3655    private final boolean killPackageProcessesLocked(String packageName, int uid,
3656            int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3657            boolean evenPersistent, String reason) {
3658        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3659
3660        // Remove all processes this package may have touched: all with the
3661        // same UID (except for the system or root user), and all whose name
3662        // matches the package name.
3663        final String procNamePrefix = packageName + ":";
3664        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3665            final int NA = apps.size();
3666            for (int ia=0; ia<NA; ia++) {
3667                ProcessRecord app = apps.valueAt(ia);
3668                if (app.persistent && !evenPersistent) {
3669                    // we don't kill persistent processes
3670                    continue;
3671                }
3672                if (app.removed) {
3673                    if (doit) {
3674                        procs.add(app);
3675                    }
3676                // If uid is specified and the uid and process name match
3677                // Or, the uid is not specified and the process name matches
3678                } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3679                            || ((app.processName.equals(packageName)
3680                                 || app.processName.startsWith(procNamePrefix))
3681                                && uid < 0))) {
3682                    if (app.setAdj >= minOomAdj) {
3683                        if (!doit) {
3684                            return true;
3685                        }
3686                        app.removed = true;
3687                        procs.add(app);
3688                    }
3689                }
3690            }
3691        }
3692
3693        int N = procs.size();
3694        for (int i=0; i<N; i++) {
3695            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3696        }
3697        return N > 0;
3698    }
3699
3700    private final boolean forceStopPackageLocked(String name, int uid,
3701            boolean callerWillRestart, boolean purgeCache, boolean doit,
3702            boolean evenPersistent, int userId) {
3703        int i;
3704        int N;
3705
3706        if (uid < 0) {
3707            try {
3708                uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
3709            } catch (RemoteException e) {
3710            }
3711        }
3712
3713        if (doit) {
3714            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3715
3716            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3717            while (badApps.hasNext()) {
3718                SparseArray<Long> ba = badApps.next();
3719                if (ba.get(uid) != null) {
3720                    badApps.remove();
3721                }
3722            }
3723        }
3724
3725        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3726                callerWillRestart, false, doit, evenPersistent, "force stop");
3727
3728        TaskRecord lastTask = null;
3729        for (i=0; i<mMainStack.mHistory.size(); i++) {
3730            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3731            final boolean samePackage = r.packageName.equals(name);
3732            if (r.userId == userId
3733                    && (samePackage || r.task == lastTask)
3734                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3735                if (!doit) {
3736                    if (r.finishing) {
3737                        // If this activity is just finishing, then it is not
3738                        // interesting as far as something to stop.
3739                        continue;
3740                    }
3741                    return true;
3742                }
3743                didSomething = true;
3744                Slog.i(TAG, "  Force finishing activity " + r);
3745                if (samePackage) {
3746                    if (r.app != null) {
3747                        r.app.removed = true;
3748                    }
3749                    r.app = null;
3750                }
3751                lastTask = r.task;
3752                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3753                        null, "force-stop", true)) {
3754                    i--;
3755                }
3756            }
3757        }
3758
3759        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3760            if (!doit) {
3761                return true;
3762            }
3763            didSomething = true;
3764        }
3765
3766        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3767        for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
3768            if (provider.info.packageName.equals(name)
3769                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3770                if (!doit) {
3771                    return true;
3772                }
3773                didSomething = true;
3774                providers.add(provider);
3775            }
3776        }
3777
3778        N = providers.size();
3779        for (i=0; i<N; i++) {
3780            removeDyingProviderLocked(null, providers.get(i), true);
3781        }
3782
3783        if (doit) {
3784            if (purgeCache) {
3785                AttributeCache ac = AttributeCache.instance();
3786                if (ac != null) {
3787                    ac.removePackage(name);
3788                }
3789            }
3790            if (mBooted) {
3791                mMainStack.resumeTopActivityLocked(null);
3792                mMainStack.scheduleIdleLocked();
3793            }
3794        }
3795
3796        return didSomething;
3797    }
3798
3799    private final boolean removeProcessLocked(ProcessRecord app,
3800            boolean callerWillRestart, boolean allowRestart, String reason) {
3801        final String name = app.processName;
3802        final int uid = app.uid;
3803        if (DEBUG_PROCESSES) Slog.d(
3804            TAG, "Force removing proc " + app.toShortString() + " (" + name
3805            + "/" + uid + ")");
3806
3807        mProcessNames.remove(name, uid);
3808        mIsolatedProcesses.remove(app.uid);
3809        if (mHeavyWeightProcess == app) {
3810            mHeavyWeightProcess = null;
3811            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3812        }
3813        boolean needRestart = false;
3814        if (app.pid > 0 && app.pid != MY_PID) {
3815            int pid = app.pid;
3816            synchronized (mPidsSelfLocked) {
3817                mPidsSelfLocked.remove(pid);
3818                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3819            }
3820            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3821            handleAppDiedLocked(app, true, allowRestart);
3822            mLruProcesses.remove(app);
3823            Process.killProcessQuiet(pid);
3824
3825            if (app.persistent && !app.isolated) {
3826                if (!callerWillRestart) {
3827                    addAppLocked(app.info, false);
3828                } else {
3829                    needRestart = true;
3830                }
3831            }
3832        } else {
3833            mRemovedProcesses.add(app);
3834        }
3835
3836        return needRestart;
3837    }
3838
3839    private final void processStartTimedOutLocked(ProcessRecord app) {
3840        final int pid = app.pid;
3841        boolean gone = false;
3842        synchronized (mPidsSelfLocked) {
3843            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3844            if (knownApp != null && knownApp.thread == null) {
3845                mPidsSelfLocked.remove(pid);
3846                gone = true;
3847            }
3848        }
3849
3850        if (gone) {
3851            Slog.w(TAG, "Process " + app + " failed to attach");
3852            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
3853                    app.processName);
3854            mProcessNames.remove(app.processName, app.uid);
3855            mIsolatedProcesses.remove(app.uid);
3856            if (mHeavyWeightProcess == app) {
3857                mHeavyWeightProcess = null;
3858                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3859            }
3860            // Take care of any launching providers waiting for this process.
3861            checkAppInLaunchingProvidersLocked(app, true);
3862            // Take care of any services that are waiting for the process.
3863            mServices.processStartTimedOutLocked(app);
3864            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3865                    app.processName, app.setAdj, "start timeout");
3866            Process.killProcessQuiet(pid);
3867            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3868                Slog.w(TAG, "Unattached app died before backup, skipping");
3869                try {
3870                    IBackupManager bm = IBackupManager.Stub.asInterface(
3871                            ServiceManager.getService(Context.BACKUP_SERVICE));
3872                    bm.agentDisconnected(app.info.packageName);
3873                } catch (RemoteException e) {
3874                    // Can't happen; the backup manager is local
3875                }
3876            }
3877            if (isPendingBroadcastProcessLocked(pid)) {
3878                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3879                skipPendingBroadcastLocked(pid);
3880            }
3881        } else {
3882            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3883        }
3884    }
3885
3886    private final boolean attachApplicationLocked(IApplicationThread thread,
3887            int pid) {
3888
3889        // Find the application record that is being attached...  either via
3890        // the pid if we are running in multiple processes, or just pull the
3891        // next app record if we are emulating process with anonymous threads.
3892        ProcessRecord app;
3893        if (pid != MY_PID && pid >= 0) {
3894            synchronized (mPidsSelfLocked) {
3895                app = mPidsSelfLocked.get(pid);
3896            }
3897        } else {
3898            app = null;
3899        }
3900
3901        if (app == null) {
3902            Slog.w(TAG, "No pending application record for pid " + pid
3903                    + " (IApplicationThread " + thread + "); dropping process");
3904            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3905            if (pid > 0 && pid != MY_PID) {
3906                Process.killProcessQuiet(pid);
3907            } else {
3908                try {
3909                    thread.scheduleExit();
3910                } catch (Exception e) {
3911                    // Ignore exceptions.
3912                }
3913            }
3914            return false;
3915        }
3916
3917        // If this application record is still attached to a previous
3918        // process, clean it up now.
3919        if (app.thread != null) {
3920            handleAppDiedLocked(app, true, true);
3921        }
3922
3923        // Tell the process all about itself.
3924
3925        if (localLOGV) Slog.v(
3926                TAG, "Binding process pid " + pid + " to record " + app);
3927
3928        String processName = app.processName;
3929        try {
3930            AppDeathRecipient adr = new AppDeathRecipient(
3931                    app, pid, thread);
3932            thread.asBinder().linkToDeath(adr, 0);
3933            app.deathRecipient = adr;
3934        } catch (RemoteException e) {
3935            app.resetPackageList();
3936            startProcessLocked(app, "link fail", processName);
3937            return false;
3938        }
3939
3940        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3941
3942        app.thread = thread;
3943        app.curAdj = app.setAdj = -100;
3944        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3945        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3946        app.forcingToForeground = null;
3947        app.foregroundServices = false;
3948        app.hasShownUi = false;
3949        app.debugging = false;
3950
3951        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3952
3953        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3954        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3955
3956        if (!normalMode) {
3957            Slog.i(TAG, "Launching preboot mode app: " + app);
3958        }
3959
3960        if (localLOGV) Slog.v(
3961            TAG, "New app record " + app
3962            + " thread=" + thread.asBinder() + " pid=" + pid);
3963        try {
3964            int testMode = IApplicationThread.DEBUG_OFF;
3965            if (mDebugApp != null && mDebugApp.equals(processName)) {
3966                testMode = mWaitForDebugger
3967                    ? IApplicationThread.DEBUG_WAIT
3968                    : IApplicationThread.DEBUG_ON;
3969                app.debugging = true;
3970                if (mDebugTransient) {
3971                    mDebugApp = mOrigDebugApp;
3972                    mWaitForDebugger = mOrigWaitForDebugger;
3973                }
3974            }
3975            String profileFile = app.instrumentationProfileFile;
3976            ParcelFileDescriptor profileFd = null;
3977            boolean profileAutoStop = false;
3978            if (mProfileApp != null && mProfileApp.equals(processName)) {
3979                mProfileProc = app;
3980                profileFile = mProfileFile;
3981                profileFd = mProfileFd;
3982                profileAutoStop = mAutoStopProfiler;
3983            }
3984            boolean enableOpenGlTrace = false;
3985            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
3986                enableOpenGlTrace = true;
3987                mOpenGlTraceApp = null;
3988            }
3989
3990            // If the app is being launched for restore or full backup, set it up specially
3991            boolean isRestrictedBackupMode = false;
3992            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3993                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3994                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
3995                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3996            }
3997
3998            ensurePackageDexOpt(app.instrumentationInfo != null
3999                    ? app.instrumentationInfo.packageName
4000                    : app.info.packageName);
4001            if (app.instrumentationClass != null) {
4002                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4003            }
4004            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4005                    + processName + " with config " + mConfiguration);
4006            ApplicationInfo appInfo = app.instrumentationInfo != null
4007                    ? app.instrumentationInfo : app.info;
4008            app.compat = compatibilityInfoForPackageLocked(appInfo);
4009            if (profileFd != null) {
4010                profileFd = profileFd.dup();
4011            }
4012            thread.bindApplication(processName, appInfo, providers,
4013                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4014                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4015                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4016                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4017                    mCoreSettingsObserver.getCoreSettingsLocked());
4018            updateLruProcessLocked(app, false, true);
4019            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4020        } catch (Exception e) {
4021            // todo: Yikes!  What should we do?  For now we will try to
4022            // start another process, but that could easily get us in
4023            // an infinite loop of restarting processes...
4024            Slog.w(TAG, "Exception thrown during bind!", e);
4025
4026            app.resetPackageList();
4027            app.unlinkDeathRecipient();
4028            startProcessLocked(app, "bind fail", processName);
4029            return false;
4030        }
4031
4032        // Remove this record from the list of starting applications.
4033        mPersistentStartingProcesses.remove(app);
4034        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4035                "Attach application locked removing on hold: " + app);
4036        mProcessesOnHold.remove(app);
4037
4038        boolean badApp = false;
4039        boolean didSomething = false;
4040
4041        // See if the top visible activity is waiting to run in this process...
4042        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4043        if (hr != null && normalMode) {
4044            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4045                    && processName.equals(hr.processName)) {
4046                try {
4047                    if (mHeadless) {
4048                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4049                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4050                        didSomething = true;
4051                    }
4052                } catch (Exception e) {
4053                    Slog.w(TAG, "Exception in new application when starting activity "
4054                          + hr.intent.getComponent().flattenToShortString(), e);
4055                    badApp = true;
4056                }
4057            } else {
4058                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4059            }
4060        }
4061
4062        // Find any services that should be running in this process...
4063        if (!badApp) {
4064            try {
4065                didSomething |= mServices.attachApplicationLocked(app, processName);
4066            } catch (Exception e) {
4067                badApp = true;
4068            }
4069        }
4070
4071        // Check if a next-broadcast receiver is in this process...
4072        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4073            try {
4074                didSomething = sendPendingBroadcastsLocked(app);
4075            } catch (Exception e) {
4076                // If the app died trying to launch the receiver we declare it 'bad'
4077                badApp = true;
4078            }
4079        }
4080
4081        // Check whether the next backup agent is in this process...
4082        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4083            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4084            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4085            try {
4086                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4087                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4088                        mBackupTarget.backupMode);
4089            } catch (Exception e) {
4090                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4091                e.printStackTrace();
4092            }
4093        }
4094
4095        if (badApp) {
4096            // todo: Also need to kill application to deal with all
4097            // kinds of exceptions.
4098            handleAppDiedLocked(app, false, true);
4099            return false;
4100        }
4101
4102        if (!didSomething) {
4103            updateOomAdjLocked();
4104        }
4105
4106        return true;
4107    }
4108
4109    public final void attachApplication(IApplicationThread thread) {
4110        synchronized (this) {
4111            int callingPid = Binder.getCallingPid();
4112            final long origId = Binder.clearCallingIdentity();
4113            attachApplicationLocked(thread, callingPid);
4114            Binder.restoreCallingIdentity(origId);
4115        }
4116    }
4117
4118    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4119        final long origId = Binder.clearCallingIdentity();
4120        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4121        if (stopProfiling) {
4122            synchronized (this) {
4123                if (mProfileProc == r.app) {
4124                    if (mProfileFd != null) {
4125                        try {
4126                            mProfileFd.close();
4127                        } catch (IOException e) {
4128                        }
4129                        clearProfilerLocked();
4130                    }
4131                }
4132            }
4133        }
4134        Binder.restoreCallingIdentity(origId);
4135    }
4136
4137    void enableScreenAfterBoot() {
4138        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4139                SystemClock.uptimeMillis());
4140        mWindowManager.enableScreenAfterBoot();
4141
4142        synchronized (this) {
4143            updateEventDispatchingLocked();
4144        }
4145    }
4146
4147    public void showBootMessage(final CharSequence msg, final boolean always) {
4148        enforceNotIsolatedCaller("showBootMessage");
4149        mWindowManager.showBootMessage(msg, always);
4150    }
4151
4152    public void dismissKeyguardOnNextActivity() {
4153        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4154        final long token = Binder.clearCallingIdentity();
4155        try {
4156            synchronized (this) {
4157                if (mLockScreenShown) {
4158                    mLockScreenShown = false;
4159                    comeOutOfSleepIfNeededLocked();
4160                }
4161                mMainStack.dismissKeyguardOnNextActivityLocked();
4162            }
4163        } finally {
4164            Binder.restoreCallingIdentity(token);
4165        }
4166    }
4167
4168    final void finishBooting() {
4169        IntentFilter pkgFilter = new IntentFilter();
4170        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4171        pkgFilter.addDataScheme("package");
4172        mContext.registerReceiver(new BroadcastReceiver() {
4173            @Override
4174            public void onReceive(Context context, Intent intent) {
4175                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4176                if (pkgs != null) {
4177                    for (String pkg : pkgs) {
4178                        synchronized (ActivityManagerService.this) {
4179                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4180                                setResultCode(Activity.RESULT_OK);
4181                                return;
4182                            }
4183                        }
4184                    }
4185                }
4186            }
4187        }, pkgFilter);
4188
4189        IntentFilter userFilter = new IntentFilter();
4190        userFilter.addAction(Intent.ACTION_USER_REMOVED);
4191        mContext.registerReceiver(new BroadcastReceiver() {
4192            @Override
4193            public void onReceive(Context context, Intent intent) {
4194                onUserRemoved(intent);
4195            }
4196        }, userFilter);
4197
4198        synchronized (this) {
4199            // Ensure that any processes we had put on hold are now started
4200            // up.
4201            final int NP = mProcessesOnHold.size();
4202            if (NP > 0) {
4203                ArrayList<ProcessRecord> procs =
4204                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4205                for (int ip=0; ip<NP; ip++) {
4206                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4207                            + procs.get(ip));
4208                    startProcessLocked(procs.get(ip), "on-hold", null);
4209                }
4210            }
4211
4212            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4213                // Start looking for apps that are abusing wake locks.
4214                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4215                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4216                // Tell anyone interested that we are done booting!
4217                SystemProperties.set("sys.boot_completed", "1");
4218                SystemProperties.set("dev.bootcomplete", "1");
4219                List<UserInfo> users = getUserManager().getUsers();
4220                for (UserInfo user : users) {
4221                    broadcastIntentLocked(null, null,
4222                            new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4223                            null, null, 0, null, null,
4224                            android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4225                            false, false, MY_PID, Process.SYSTEM_UID, user.id);
4226                }
4227            }
4228        }
4229    }
4230
4231    final void ensureBootCompleted() {
4232        boolean booting;
4233        boolean enableScreen;
4234        synchronized (this) {
4235            booting = mBooting;
4236            mBooting = false;
4237            enableScreen = !mBooted;
4238            mBooted = true;
4239        }
4240
4241        if (booting) {
4242            finishBooting();
4243        }
4244
4245        if (enableScreen) {
4246            enableScreenAfterBoot();
4247        }
4248    }
4249
4250    public final void activityPaused(IBinder token) {
4251        final long origId = Binder.clearCallingIdentity();
4252        mMainStack.activityPaused(token, false);
4253        Binder.restoreCallingIdentity(origId);
4254    }
4255
4256    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4257            CharSequence description) {
4258        if (localLOGV) Slog.v(
4259            TAG, "Activity stopped: token=" + token);
4260
4261        // Refuse possible leaked file descriptors
4262        if (icicle != null && icicle.hasFileDescriptors()) {
4263            throw new IllegalArgumentException("File descriptors passed in Bundle");
4264        }
4265
4266        ActivityRecord r = null;
4267
4268        final long origId = Binder.clearCallingIdentity();
4269
4270        synchronized (this) {
4271            r = mMainStack.isInStackLocked(token);
4272            if (r != null) {
4273                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4274            }
4275        }
4276
4277        if (r != null) {
4278            sendPendingThumbnail(r, null, null, null, false);
4279        }
4280
4281        trimApplications();
4282
4283        Binder.restoreCallingIdentity(origId);
4284    }
4285
4286    public final void activityDestroyed(IBinder token) {
4287        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4288        mMainStack.activityDestroyed(token);
4289    }
4290
4291    public String getCallingPackage(IBinder token) {
4292        synchronized (this) {
4293            ActivityRecord r = getCallingRecordLocked(token);
4294            return r != null && r.app != null ? r.info.packageName : null;
4295        }
4296    }
4297
4298    public ComponentName getCallingActivity(IBinder token) {
4299        synchronized (this) {
4300            ActivityRecord r = getCallingRecordLocked(token);
4301            return r != null ? r.intent.getComponent() : null;
4302        }
4303    }
4304
4305    private ActivityRecord getCallingRecordLocked(IBinder token) {
4306        ActivityRecord r = mMainStack.isInStackLocked(token);
4307        if (r == null) {
4308            return null;
4309        }
4310        return r.resultTo;
4311    }
4312
4313    public ComponentName getActivityClassForToken(IBinder token) {
4314        synchronized(this) {
4315            ActivityRecord r = mMainStack.isInStackLocked(token);
4316            if (r == null) {
4317                return null;
4318            }
4319            return r.intent.getComponent();
4320        }
4321    }
4322
4323    public String getPackageForToken(IBinder token) {
4324        synchronized(this) {
4325            ActivityRecord r = mMainStack.isInStackLocked(token);
4326            if (r == null) {
4327                return null;
4328            }
4329            return r.packageName;
4330        }
4331    }
4332
4333    public IIntentSender getIntentSender(int type,
4334            String packageName, IBinder token, String resultWho,
4335            int requestCode, Intent[] intents, String[] resolvedTypes,
4336            int flags, Bundle options) {
4337        enforceNotIsolatedCaller("getIntentSender");
4338        // Refuse possible leaked file descriptors
4339        if (intents != null) {
4340            if (intents.length < 1) {
4341                throw new IllegalArgumentException("Intents array length must be >= 1");
4342            }
4343            for (int i=0; i<intents.length; i++) {
4344                Intent intent = intents[i];
4345                if (intent != null) {
4346                    if (intent.hasFileDescriptors()) {
4347                        throw new IllegalArgumentException("File descriptors passed in Intent");
4348                    }
4349                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4350                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4351                        throw new IllegalArgumentException(
4352                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4353                    }
4354                    intents[i] = new Intent(intent);
4355                }
4356            }
4357            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4358                throw new IllegalArgumentException(
4359                        "Intent array length does not match resolvedTypes length");
4360            }
4361        }
4362        if (options != null) {
4363            if (options.hasFileDescriptors()) {
4364                throw new IllegalArgumentException("File descriptors passed in options");
4365            }
4366        }
4367
4368        synchronized(this) {
4369            int callingUid = Binder.getCallingUid();
4370            try {
4371                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4372                    int uid = AppGlobals.getPackageManager()
4373                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4374                    if (!UserHandle.isSameApp(callingUid, uid)) {
4375                        String msg = "Permission Denial: getIntentSender() from pid="
4376                            + Binder.getCallingPid()
4377                            + ", uid=" + Binder.getCallingUid()
4378                            + ", (need uid=" + uid + ")"
4379                            + " is not allowed to send as package " + packageName;
4380                        Slog.w(TAG, msg);
4381                        throw new SecurityException(msg);
4382                    }
4383                }
4384
4385                if (DEBUG_MU)
4386                    Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
4387                            + Binder.getOrigCallingUid());
4388                return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
4389                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4390
4391            } catch (RemoteException e) {
4392                throw new SecurityException(e);
4393            }
4394        }
4395    }
4396
4397    IIntentSender getIntentSenderLocked(int type,
4398            String packageName, int callingUid, IBinder token, String resultWho,
4399            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4400            Bundle options) {
4401        if (DEBUG_MU)
4402            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4403        ActivityRecord activity = null;
4404        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4405            activity = mMainStack.isInStackLocked(token);
4406            if (activity == null) {
4407                return null;
4408            }
4409            if (activity.finishing) {
4410                return null;
4411            }
4412        }
4413
4414        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4415        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4416        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4417        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4418                |PendingIntent.FLAG_UPDATE_CURRENT);
4419
4420        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4421                type, packageName, activity, resultWho,
4422                requestCode, intents, resolvedTypes, flags, options);
4423        WeakReference<PendingIntentRecord> ref;
4424        ref = mIntentSenderRecords.get(key);
4425        PendingIntentRecord rec = ref != null ? ref.get() : null;
4426        if (rec != null) {
4427            if (!cancelCurrent) {
4428                if (updateCurrent) {
4429                    if (rec.key.requestIntent != null) {
4430                        rec.key.requestIntent.replaceExtras(intents != null ?
4431                                intents[intents.length - 1] : null);
4432                    }
4433                    if (intents != null) {
4434                        intents[intents.length-1] = rec.key.requestIntent;
4435                        rec.key.allIntents = intents;
4436                        rec.key.allResolvedTypes = resolvedTypes;
4437                    } else {
4438                        rec.key.allIntents = null;
4439                        rec.key.allResolvedTypes = null;
4440                    }
4441                }
4442                return rec;
4443            }
4444            rec.canceled = true;
4445            mIntentSenderRecords.remove(key);
4446        }
4447        if (noCreate) {
4448            return rec;
4449        }
4450        rec = new PendingIntentRecord(this, key, callingUid);
4451        mIntentSenderRecords.put(key, rec.ref);
4452        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4453            if (activity.pendingResults == null) {
4454                activity.pendingResults
4455                        = new HashSet<WeakReference<PendingIntentRecord>>();
4456            }
4457            activity.pendingResults.add(rec.ref);
4458        }
4459        return rec;
4460    }
4461
4462    public void cancelIntentSender(IIntentSender sender) {
4463        if (!(sender instanceof PendingIntentRecord)) {
4464            return;
4465        }
4466        synchronized(this) {
4467            PendingIntentRecord rec = (PendingIntentRecord)sender;
4468            try {
4469                int uid = AppGlobals.getPackageManager()
4470                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4471                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4472                    String msg = "Permission Denial: cancelIntentSender() from pid="
4473                        + Binder.getCallingPid()
4474                        + ", uid=" + Binder.getCallingUid()
4475                        + " is not allowed to cancel packges "
4476                        + rec.key.packageName;
4477                    Slog.w(TAG, msg);
4478                    throw new SecurityException(msg);
4479                }
4480            } catch (RemoteException e) {
4481                throw new SecurityException(e);
4482            }
4483            cancelIntentSenderLocked(rec, true);
4484        }
4485    }
4486
4487    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4488        rec.canceled = true;
4489        mIntentSenderRecords.remove(rec.key);
4490        if (cleanActivity && rec.key.activity != null) {
4491            rec.key.activity.pendingResults.remove(rec.ref);
4492        }
4493    }
4494
4495    public String getPackageForIntentSender(IIntentSender pendingResult) {
4496        if (!(pendingResult instanceof PendingIntentRecord)) {
4497            return null;
4498        }
4499        try {
4500            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4501            return res.key.packageName;
4502        } catch (ClassCastException e) {
4503        }
4504        return null;
4505    }
4506
4507    public int getUidForIntentSender(IIntentSender sender) {
4508        if (sender instanceof PendingIntentRecord) {
4509            try {
4510                PendingIntentRecord res = (PendingIntentRecord)sender;
4511                return res.uid;
4512            } catch (ClassCastException e) {
4513            }
4514        }
4515        return -1;
4516    }
4517
4518    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4519        if (!(pendingResult instanceof PendingIntentRecord)) {
4520            return false;
4521        }
4522        try {
4523            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4524            if (res.key.allIntents == null) {
4525                return false;
4526            }
4527            for (int i=0; i<res.key.allIntents.length; i++) {
4528                Intent intent = res.key.allIntents[i];
4529                if (intent.getPackage() != null && intent.getComponent() != null) {
4530                    return false;
4531                }
4532            }
4533            return true;
4534        } catch (ClassCastException e) {
4535        }
4536        return false;
4537    }
4538
4539    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4540        if (!(pendingResult instanceof PendingIntentRecord)) {
4541            return false;
4542        }
4543        try {
4544            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4545            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4546                return true;
4547            }
4548            return false;
4549        } catch (ClassCastException e) {
4550        }
4551        return false;
4552    }
4553
4554    public void setProcessLimit(int max) {
4555        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4556                "setProcessLimit()");
4557        synchronized (this) {
4558            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4559            mProcessLimitOverride = max;
4560        }
4561        trimApplications();
4562    }
4563
4564    public int getProcessLimit() {
4565        synchronized (this) {
4566            return mProcessLimitOverride;
4567        }
4568    }
4569
4570    void foregroundTokenDied(ForegroundToken token) {
4571        synchronized (ActivityManagerService.this) {
4572            synchronized (mPidsSelfLocked) {
4573                ForegroundToken cur
4574                    = mForegroundProcesses.get(token.pid);
4575                if (cur != token) {
4576                    return;
4577                }
4578                mForegroundProcesses.remove(token.pid);
4579                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4580                if (pr == null) {
4581                    return;
4582                }
4583                pr.forcingToForeground = null;
4584                pr.foregroundServices = false;
4585            }
4586            updateOomAdjLocked();
4587        }
4588    }
4589
4590    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4591        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4592                "setProcessForeground()");
4593        synchronized(this) {
4594            boolean changed = false;
4595
4596            synchronized (mPidsSelfLocked) {
4597                ProcessRecord pr = mPidsSelfLocked.get(pid);
4598                if (pr == null && isForeground) {
4599                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4600                    return;
4601                }
4602                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4603                if (oldToken != null) {
4604                    oldToken.token.unlinkToDeath(oldToken, 0);
4605                    mForegroundProcesses.remove(pid);
4606                    if (pr != null) {
4607                        pr.forcingToForeground = null;
4608                    }
4609                    changed = true;
4610                }
4611                if (isForeground && token != null) {
4612                    ForegroundToken newToken = new ForegroundToken() {
4613                        public void binderDied() {
4614                            foregroundTokenDied(this);
4615                        }
4616                    };
4617                    newToken.pid = pid;
4618                    newToken.token = token;
4619                    try {
4620                        token.linkToDeath(newToken, 0);
4621                        mForegroundProcesses.put(pid, newToken);
4622                        pr.forcingToForeground = token;
4623                        changed = true;
4624                    } catch (RemoteException e) {
4625                        // If the process died while doing this, we will later
4626                        // do the cleanup with the process death link.
4627                    }
4628                }
4629            }
4630
4631            if (changed) {
4632                updateOomAdjLocked();
4633            }
4634        }
4635    }
4636
4637    // =========================================================
4638    // PERMISSIONS
4639    // =========================================================
4640
4641    static class PermissionController extends IPermissionController.Stub {
4642        ActivityManagerService mActivityManagerService;
4643        PermissionController(ActivityManagerService activityManagerService) {
4644            mActivityManagerService = activityManagerService;
4645        }
4646
4647        public boolean checkPermission(String permission, int pid, int uid) {
4648            return mActivityManagerService.checkPermission(permission, pid,
4649                    uid) == PackageManager.PERMISSION_GRANTED;
4650        }
4651    }
4652
4653    /**
4654     * This can be called with or without the global lock held.
4655     */
4656    int checkComponentPermission(String permission, int pid, int uid,
4657            int owningUid, boolean exported) {
4658        // We might be performing an operation on behalf of an indirect binder
4659        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4660        // client identity accordingly before proceeding.
4661        Identity tlsIdentity = sCallerIdentity.get();
4662        if (tlsIdentity != null) {
4663            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4664                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4665            uid = tlsIdentity.uid;
4666            pid = tlsIdentity.pid;
4667        }
4668
4669        if (pid == MY_PID) {
4670            return PackageManager.PERMISSION_GRANTED;
4671        }
4672
4673        return ActivityManager.checkComponentPermission(permission, uid,
4674                owningUid, exported);
4675    }
4676
4677    /**
4678     * As the only public entry point for permissions checking, this method
4679     * can enforce the semantic that requesting a check on a null global
4680     * permission is automatically denied.  (Internally a null permission
4681     * string is used when calling {@link #checkComponentPermission} in cases
4682     * when only uid-based security is needed.)
4683     *
4684     * This can be called with or without the global lock held.
4685     */
4686    public int checkPermission(String permission, int pid, int uid) {
4687        if (permission == null) {
4688            return PackageManager.PERMISSION_DENIED;
4689        }
4690        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4691    }
4692
4693    /**
4694     * Binder IPC calls go through the public entry point.
4695     * This can be called with or without the global lock held.
4696     */
4697    int checkCallingPermission(String permission) {
4698        return checkPermission(permission,
4699                Binder.getCallingPid(),
4700                UserHandle.getAppId(Binder.getCallingUid()));
4701    }
4702
4703    /**
4704     * This can be called with or without the global lock held.
4705     */
4706    void enforceCallingPermission(String permission, String func) {
4707        if (checkCallingPermission(permission)
4708                == PackageManager.PERMISSION_GRANTED) {
4709            return;
4710        }
4711
4712        String msg = "Permission Denial: " + func + " from pid="
4713                + Binder.getCallingPid()
4714                + ", uid=" + Binder.getCallingUid()
4715                + " requires " + permission;
4716        Slog.w(TAG, msg);
4717        throw new SecurityException(msg);
4718    }
4719
4720    /**
4721     * Determine if UID is holding permissions required to access {@link Uri} in
4722     * the given {@link ProviderInfo}. Final permission checking is always done
4723     * in {@link ContentProvider}.
4724     */
4725    private final boolean checkHoldingPermissionsLocked(
4726            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4727        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4728                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4729
4730        if (pi.applicationInfo.uid == uid) {
4731            return true;
4732        } else if (!pi.exported) {
4733            return false;
4734        }
4735
4736        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4737        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4738        try {
4739            // check if target holds top-level <provider> permissions
4740            if (!readMet && pi.readPermission != null
4741                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4742                readMet = true;
4743            }
4744            if (!writeMet && pi.writePermission != null
4745                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4746                writeMet = true;
4747            }
4748
4749            // track if unprotected read/write is allowed; any denied
4750            // <path-permission> below removes this ability
4751            boolean allowDefaultRead = pi.readPermission == null;
4752            boolean allowDefaultWrite = pi.writePermission == null;
4753
4754            // check if target holds any <path-permission> that match uri
4755            final PathPermission[] pps = pi.pathPermissions;
4756            if (pps != null) {
4757                final String path = uri.getPath();
4758                int i = pps.length;
4759                while (i > 0 && (!readMet || !writeMet)) {
4760                    i--;
4761                    PathPermission pp = pps[i];
4762                    if (pp.match(path)) {
4763                        if (!readMet) {
4764                            final String pprperm = pp.getReadPermission();
4765                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4766                                    + pprperm + " for " + pp.getPath()
4767                                    + ": match=" + pp.match(path)
4768                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4769                            if (pprperm != null) {
4770                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4771                                    readMet = true;
4772                                } else {
4773                                    allowDefaultRead = false;
4774                                }
4775                            }
4776                        }
4777                        if (!writeMet) {
4778                            final String ppwperm = pp.getWritePermission();
4779                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4780                                    + ppwperm + " for " + pp.getPath()
4781                                    + ": match=" + pp.match(path)
4782                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4783                            if (ppwperm != null) {
4784                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4785                                    writeMet = true;
4786                                } else {
4787                                    allowDefaultWrite = false;
4788                                }
4789                            }
4790                        }
4791                    }
4792                }
4793            }
4794
4795            // grant unprotected <provider> read/write, if not blocked by
4796            // <path-permission> above
4797            if (allowDefaultRead) readMet = true;
4798            if (allowDefaultWrite) writeMet = true;
4799
4800        } catch (RemoteException e) {
4801            return false;
4802        }
4803
4804        return readMet && writeMet;
4805    }
4806
4807    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4808            int modeFlags) {
4809        // Root gets to do everything.
4810        if (uid == 0) {
4811            return true;
4812        }
4813        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4814        if (perms == null) return false;
4815        UriPermission perm = perms.get(uri);
4816        if (perm == null) return false;
4817        return (modeFlags&perm.modeFlags) == modeFlags;
4818    }
4819
4820    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4821        enforceNotIsolatedCaller("checkUriPermission");
4822
4823        // Another redirected-binder-call permissions check as in
4824        // {@link checkComponentPermission}.
4825        Identity tlsIdentity = sCallerIdentity.get();
4826        if (tlsIdentity != null) {
4827            uid = tlsIdentity.uid;
4828            pid = tlsIdentity.pid;
4829        }
4830
4831        uid = UserHandle.getAppId(uid);
4832        // Our own process gets to do everything.
4833        if (pid == MY_PID) {
4834            return PackageManager.PERMISSION_GRANTED;
4835        }
4836        synchronized(this) {
4837            return checkUriPermissionLocked(uri, uid, modeFlags)
4838                    ? PackageManager.PERMISSION_GRANTED
4839                    : PackageManager.PERMISSION_DENIED;
4840        }
4841    }
4842
4843    /**
4844     * Check if the targetPkg can be granted permission to access uri by
4845     * the callingUid using the given modeFlags.  Throws a security exception
4846     * if callingUid is not allowed to do this.  Returns the uid of the target
4847     * if the URI permission grant should be performed; returns -1 if it is not
4848     * needed (for example targetPkg already has permission to access the URI).
4849     * If you already know the uid of the target, you can supply it in
4850     * lastTargetUid else set that to -1.
4851     */
4852    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4853            Uri uri, int modeFlags, int lastTargetUid) {
4854        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4855                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4856        if (modeFlags == 0) {
4857            return -1;
4858        }
4859
4860        if (targetPkg != null) {
4861            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4862                    "Checking grant " + targetPkg + " permission to " + uri);
4863        }
4864
4865        final IPackageManager pm = AppGlobals.getPackageManager();
4866
4867        // If this is not a content: uri, we can't do anything with it.
4868        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4869            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4870                    "Can't grant URI permission for non-content URI: " + uri);
4871            return -1;
4872        }
4873
4874        String name = uri.getAuthority();
4875        ProviderInfo pi = null;
4876        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4877                UserHandle.getUserId(callingUid));
4878        if (cpr != null) {
4879            pi = cpr.info;
4880        } else {
4881            try {
4882                pi = pm.resolveContentProvider(name,
4883                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid));
4884            } catch (RemoteException ex) {
4885            }
4886        }
4887        if (pi == null) {
4888            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4889            return -1;
4890        }
4891
4892        int targetUid = lastTargetUid;
4893        if (targetUid < 0 && targetPkg != null) {
4894            try {
4895                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
4896                if (targetUid < 0) {
4897                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4898                            "Can't grant URI permission no uid for: " + targetPkg);
4899                    return -1;
4900                }
4901            } catch (RemoteException ex) {
4902                return -1;
4903            }
4904        }
4905
4906        if (targetUid >= 0) {
4907            // First...  does the target actually need this permission?
4908            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4909                // No need to grant the target this permission.
4910                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4911                        "Target " + targetPkg + " already has full permission to " + uri);
4912                return -1;
4913            }
4914        } else {
4915            // First...  there is no target package, so can anyone access it?
4916            boolean allowed = pi.exported;
4917            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4918                if (pi.readPermission != null) {
4919                    allowed = false;
4920                }
4921            }
4922            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4923                if (pi.writePermission != null) {
4924                    allowed = false;
4925                }
4926            }
4927            if (allowed) {
4928                return -1;
4929            }
4930        }
4931
4932        // Second...  is the provider allowing granting of URI permissions?
4933        if (!pi.grantUriPermissions) {
4934            throw new SecurityException("Provider " + pi.packageName
4935                    + "/" + pi.name
4936                    + " does not allow granting of Uri permissions (uri "
4937                    + uri + ")");
4938        }
4939        if (pi.uriPermissionPatterns != null) {
4940            final int N = pi.uriPermissionPatterns.length;
4941            boolean allowed = false;
4942            for (int i=0; i<N; i++) {
4943                if (pi.uriPermissionPatterns[i] != null
4944                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4945                    allowed = true;
4946                    break;
4947                }
4948            }
4949            if (!allowed) {
4950                throw new SecurityException("Provider " + pi.packageName
4951                        + "/" + pi.name
4952                        + " does not allow granting of permission to path of Uri "
4953                        + uri);
4954            }
4955        }
4956
4957        // Third...  does the caller itself have permission to access
4958        // this uri?
4959        if (callingUid != Process.myUid()) {
4960            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4961                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4962                    throw new SecurityException("Uid " + callingUid
4963                            + " does not have permission to uri " + uri);
4964                }
4965            }
4966        }
4967
4968        return targetUid;
4969    }
4970
4971    public int checkGrantUriPermission(int callingUid, String targetPkg,
4972            Uri uri, int modeFlags) {
4973        enforceNotIsolatedCaller("checkGrantUriPermission");
4974        synchronized(this) {
4975            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
4976        }
4977    }
4978
4979    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4980            Uri uri, int modeFlags, UriPermissionOwner owner) {
4981        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4982                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4983        if (modeFlags == 0) {
4984            return;
4985        }
4986
4987        // So here we are: the caller has the assumed permission
4988        // to the uri, and the target doesn't.  Let's now give this to
4989        // the target.
4990
4991        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4992                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
4993
4994        HashMap<Uri, UriPermission> targetUris
4995                = mGrantedUriPermissions.get(targetUid);
4996        if (targetUris == null) {
4997            targetUris = new HashMap<Uri, UriPermission>();
4998            mGrantedUriPermissions.put(targetUid, targetUris);
4999        }
5000
5001        UriPermission perm = targetUris.get(uri);
5002        if (perm == null) {
5003            perm = new UriPermission(targetUid, uri);
5004            targetUris.put(uri, perm);
5005        }
5006
5007        perm.modeFlags |= modeFlags;
5008        if (owner == null) {
5009            perm.globalModeFlags |= modeFlags;
5010        } else {
5011            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5012                 perm.readOwners.add(owner);
5013                 owner.addReadPermission(perm);
5014            }
5015            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5016                 perm.writeOwners.add(owner);
5017                 owner.addWritePermission(perm);
5018            }
5019        }
5020    }
5021
5022    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5023            int modeFlags, UriPermissionOwner owner) {
5024        if (targetPkg == null) {
5025            throw new NullPointerException("targetPkg");
5026        }
5027
5028        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5029        if (targetUid < 0) {
5030            return;
5031        }
5032
5033        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5034    }
5035
5036    static class NeededUriGrants extends ArrayList<Uri> {
5037        final String targetPkg;
5038        final int targetUid;
5039        final int flags;
5040
5041        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5042            targetPkg = _targetPkg;
5043            targetUid = _targetUid;
5044            flags = _flags;
5045        }
5046    }
5047
5048    /**
5049     * Like checkGrantUriPermissionLocked, but takes an Intent.
5050     */
5051    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5052            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5053        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5054                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5055                + " clip=" + (intent != null ? intent.getClipData() : null)
5056                + " from " + intent + "; flags=0x"
5057                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5058
5059        if (targetPkg == null) {
5060            throw new NullPointerException("targetPkg");
5061        }
5062
5063        if (intent == null) {
5064            return null;
5065        }
5066        Uri data = intent.getData();
5067        ClipData clip = intent.getClipData();
5068        if (data == null && clip == null) {
5069            return null;
5070        }
5071        if (data != null) {
5072            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5073                mode, needed != null ? needed.targetUid : -1);
5074            if (target > 0) {
5075                if (needed == null) {
5076                    needed = new NeededUriGrants(targetPkg, target, mode);
5077                }
5078                needed.add(data);
5079            }
5080        }
5081        if (clip != null) {
5082            for (int i=0; i<clip.getItemCount(); i++) {
5083                Uri uri = clip.getItemAt(i).getUri();
5084                if (uri != null) {
5085                    int target = -1;
5086                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5087                            mode, needed != null ? needed.targetUid : -1);
5088                    if (target > 0) {
5089                        if (needed == null) {
5090                            needed = new NeededUriGrants(targetPkg, target, mode);
5091                        }
5092                        needed.add(uri);
5093                    }
5094                } else {
5095                    Intent clipIntent = clip.getItemAt(i).getIntent();
5096                    if (clipIntent != null) {
5097                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5098                                callingUid, targetPkg, clipIntent, mode, needed);
5099                        if (newNeeded != null) {
5100                            needed = newNeeded;
5101                        }
5102                    }
5103                }
5104            }
5105        }
5106
5107        return needed;
5108    }
5109
5110    /**
5111     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5112     */
5113    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5114            UriPermissionOwner owner) {
5115        if (needed != null) {
5116            for (int i=0; i<needed.size(); i++) {
5117                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5118                        needed.get(i), needed.flags, owner);
5119            }
5120        }
5121    }
5122
5123    void grantUriPermissionFromIntentLocked(int callingUid,
5124            String targetPkg, Intent intent, UriPermissionOwner owner) {
5125        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5126                intent, intent != null ? intent.getFlags() : 0, null);
5127        if (needed == null) {
5128            return;
5129        }
5130
5131        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5132    }
5133
5134    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5135            Uri uri, int modeFlags) {
5136        enforceNotIsolatedCaller("grantUriPermission");
5137        synchronized(this) {
5138            final ProcessRecord r = getRecordForAppLocked(caller);
5139            if (r == null) {
5140                throw new SecurityException("Unable to find app for caller "
5141                        + caller
5142                        + " when granting permission to uri " + uri);
5143            }
5144            if (targetPkg == null) {
5145                throw new IllegalArgumentException("null target");
5146            }
5147            if (uri == null) {
5148                throw new IllegalArgumentException("null uri");
5149            }
5150
5151            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5152                    null);
5153        }
5154    }
5155
5156    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5157        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5158                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5159            HashMap<Uri, UriPermission> perms
5160                    = mGrantedUriPermissions.get(perm.uid);
5161            if (perms != null) {
5162                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5163                        "Removing " + perm.uid + " permission to " + perm.uri);
5164                perms.remove(perm.uri);
5165                if (perms.size() == 0) {
5166                    mGrantedUriPermissions.remove(perm.uid);
5167                }
5168            }
5169        }
5170    }
5171
5172    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5173            int modeFlags) {
5174        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5175                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5176        if (modeFlags == 0) {
5177            return;
5178        }
5179
5180        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5181                "Revoking all granted permissions to " + uri);
5182
5183        final IPackageManager pm = AppGlobals.getPackageManager();
5184
5185        final String authority = uri.getAuthority();
5186        ProviderInfo pi = null;
5187        int userId = UserHandle.getUserId(callingUid);
5188        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5189        if (cpr != null) {
5190            pi = cpr.info;
5191        } else {
5192            try {
5193                pi = pm.resolveContentProvider(authority,
5194                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5195            } catch (RemoteException ex) {
5196            }
5197        }
5198        if (pi == null) {
5199            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5200            return;
5201        }
5202
5203        // Does the caller have this permission on the URI?
5204        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5205            // Right now, if you are not the original owner of the permission,
5206            // you are not allowed to revoke it.
5207            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5208                throw new SecurityException("Uid " + callingUid
5209                        + " does not have permission to uri " + uri);
5210            //}
5211        }
5212
5213        // Go through all of the permissions and remove any that match.
5214        final List<String> SEGMENTS = uri.getPathSegments();
5215        if (SEGMENTS != null) {
5216            final int NS = SEGMENTS.size();
5217            int N = mGrantedUriPermissions.size();
5218            for (int i=0; i<N; i++) {
5219                HashMap<Uri, UriPermission> perms
5220                        = mGrantedUriPermissions.valueAt(i);
5221                Iterator<UriPermission> it = perms.values().iterator();
5222            toploop:
5223                while (it.hasNext()) {
5224                    UriPermission perm = it.next();
5225                    Uri targetUri = perm.uri;
5226                    if (!authority.equals(targetUri.getAuthority())) {
5227                        continue;
5228                    }
5229                    List<String> targetSegments = targetUri.getPathSegments();
5230                    if (targetSegments == null) {
5231                        continue;
5232                    }
5233                    if (targetSegments.size() < NS) {
5234                        continue;
5235                    }
5236                    for (int j=0; j<NS; j++) {
5237                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5238                            continue toploop;
5239                        }
5240                    }
5241                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5242                            "Revoking " + perm.uid + " permission to " + perm.uri);
5243                    perm.clearModes(modeFlags);
5244                    if (perm.modeFlags == 0) {
5245                        it.remove();
5246                    }
5247                }
5248                if (perms.size() == 0) {
5249                    mGrantedUriPermissions.remove(
5250                            mGrantedUriPermissions.keyAt(i));
5251                    N--;
5252                    i--;
5253                }
5254            }
5255        }
5256    }
5257
5258    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5259            int modeFlags) {
5260        enforceNotIsolatedCaller("revokeUriPermission");
5261        synchronized(this) {
5262            final ProcessRecord r = getRecordForAppLocked(caller);
5263            if (r == null) {
5264                throw new SecurityException("Unable to find app for caller "
5265                        + caller
5266                        + " when revoking permission to uri " + uri);
5267            }
5268            if (uri == null) {
5269                Slog.w(TAG, "revokeUriPermission: null uri");
5270                return;
5271            }
5272
5273            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5274                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5275            if (modeFlags == 0) {
5276                return;
5277            }
5278
5279            final IPackageManager pm = AppGlobals.getPackageManager();
5280
5281            final String authority = uri.getAuthority();
5282            ProviderInfo pi = null;
5283            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5284            if (cpr != null) {
5285                pi = cpr.info;
5286            } else {
5287                try {
5288                    pi = pm.resolveContentProvider(authority,
5289                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5290                } catch (RemoteException ex) {
5291                }
5292            }
5293            if (pi == null) {
5294                Slog.w(TAG, "No content provider found for permission revoke: "
5295                        + uri.toSafeString());
5296                return;
5297            }
5298
5299            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5300        }
5301    }
5302
5303    @Override
5304    public IBinder newUriPermissionOwner(String name) {
5305        enforceNotIsolatedCaller("newUriPermissionOwner");
5306        synchronized(this) {
5307            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5308            return owner.getExternalTokenLocked();
5309        }
5310    }
5311
5312    @Override
5313    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5314            Uri uri, int modeFlags) {
5315        synchronized(this) {
5316            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5317            if (owner == null) {
5318                throw new IllegalArgumentException("Unknown owner: " + token);
5319            }
5320            if (fromUid != Binder.getCallingUid()) {
5321                if (Binder.getCallingUid() != Process.myUid()) {
5322                    // Only system code can grant URI permissions on behalf
5323                    // of other users.
5324                    throw new SecurityException("nice try");
5325                }
5326            }
5327            if (targetPkg == null) {
5328                throw new IllegalArgumentException("null target");
5329            }
5330            if (uri == null) {
5331                throw new IllegalArgumentException("null uri");
5332            }
5333
5334            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5335        }
5336    }
5337
5338    @Override
5339    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5340        synchronized(this) {
5341            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5342            if (owner == null) {
5343                throw new IllegalArgumentException("Unknown owner: " + token);
5344            }
5345
5346            if (uri == null) {
5347                owner.removeUriPermissionsLocked(mode);
5348            } else {
5349                owner.removeUriPermissionLocked(uri, mode);
5350            }
5351        }
5352    }
5353
5354    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5355        synchronized (this) {
5356            ProcessRecord app =
5357                who != null ? getRecordForAppLocked(who) : null;
5358            if (app == null) return;
5359
5360            Message msg = Message.obtain();
5361            msg.what = WAIT_FOR_DEBUGGER_MSG;
5362            msg.obj = app;
5363            msg.arg1 = waiting ? 1 : 0;
5364            mHandler.sendMessage(msg);
5365        }
5366    }
5367
5368    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5369        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5370        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5371        outInfo.availMem = Process.getFreeMemory();
5372        outInfo.totalMem = Process.getTotalMemory();
5373        outInfo.threshold = homeAppMem;
5374        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5375        outInfo.hiddenAppThreshold = hiddenAppMem;
5376        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5377                ProcessList.SERVICE_ADJ);
5378        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5379                ProcessList.VISIBLE_APP_ADJ);
5380        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5381                ProcessList.FOREGROUND_APP_ADJ);
5382    }
5383
5384    // =========================================================
5385    // TASK MANAGEMENT
5386    // =========================================================
5387
5388    public List getTasks(int maxNum, int flags,
5389                         IThumbnailReceiver receiver) {
5390        ArrayList list = new ArrayList();
5391
5392        PendingThumbnailsRecord pending = null;
5393        IApplicationThread topThumbnail = null;
5394        ActivityRecord topRecord = null;
5395
5396        synchronized(this) {
5397            if (localLOGV) Slog.v(
5398                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5399                + ", receiver=" + receiver);
5400
5401            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5402                    != PackageManager.PERMISSION_GRANTED) {
5403                if (receiver != null) {
5404                    // If the caller wants to wait for pending thumbnails,
5405                    // it ain't gonna get them.
5406                    try {
5407                        receiver.finished();
5408                    } catch (RemoteException ex) {
5409                    }
5410                }
5411                String msg = "Permission Denial: getTasks() from pid="
5412                        + Binder.getCallingPid()
5413                        + ", uid=" + Binder.getCallingUid()
5414                        + " requires " + android.Manifest.permission.GET_TASKS;
5415                Slog.w(TAG, msg);
5416                throw new SecurityException(msg);
5417            }
5418
5419            int pos = mMainStack.mHistory.size()-1;
5420            ActivityRecord next =
5421                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5422            ActivityRecord top = null;
5423            TaskRecord curTask = null;
5424            int numActivities = 0;
5425            int numRunning = 0;
5426            while (pos >= 0 && maxNum > 0) {
5427                final ActivityRecord r = next;
5428                pos--;
5429                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5430
5431                // Initialize state for next task if needed.
5432                if (top == null ||
5433                        (top.state == ActivityState.INITIALIZING
5434                            && top.task == r.task)) {
5435                    top = r;
5436                    curTask = r.task;
5437                    numActivities = numRunning = 0;
5438                }
5439
5440                // Add 'r' into the current task.
5441                numActivities++;
5442                if (r.app != null && r.app.thread != null) {
5443                    numRunning++;
5444                }
5445
5446                if (localLOGV) Slog.v(
5447                    TAG, r.intent.getComponent().flattenToShortString()
5448                    + ": task=" + r.task);
5449
5450                // If the next one is a different task, generate a new
5451                // TaskInfo entry for what we have.
5452                if (next == null || next.task != curTask) {
5453                    ActivityManager.RunningTaskInfo ci
5454                            = new ActivityManager.RunningTaskInfo();
5455                    ci.id = curTask.taskId;
5456                    ci.baseActivity = r.intent.getComponent();
5457                    ci.topActivity = top.intent.getComponent();
5458                    if (top.thumbHolder != null) {
5459                        ci.description = top.thumbHolder.lastDescription;
5460                    }
5461                    ci.numActivities = numActivities;
5462                    ci.numRunning = numRunning;
5463                    //System.out.println(
5464                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5465                    if (ci.thumbnail == null && receiver != null) {
5466                        if (localLOGV) Slog.v(
5467                            TAG, "State=" + top.state + "Idle=" + top.idle
5468                            + " app=" + top.app
5469                            + " thr=" + (top.app != null ? top.app.thread : null));
5470                        if (top.state == ActivityState.RESUMED
5471                                || top.state == ActivityState.PAUSING) {
5472                            if (top.idle && top.app != null
5473                                && top.app.thread != null) {
5474                                topRecord = top;
5475                                topThumbnail = top.app.thread;
5476                            } else {
5477                                top.thumbnailNeeded = true;
5478                            }
5479                        }
5480                        if (pending == null) {
5481                            pending = new PendingThumbnailsRecord(receiver);
5482                        }
5483                        pending.pendingRecords.add(top);
5484                    }
5485                    list.add(ci);
5486                    maxNum--;
5487                    top = null;
5488                }
5489            }
5490
5491            if (pending != null) {
5492                mPendingThumbnails.add(pending);
5493            }
5494        }
5495
5496        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5497
5498        if (topThumbnail != null) {
5499            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5500            try {
5501                topThumbnail.requestThumbnail(topRecord.appToken);
5502            } catch (Exception e) {
5503                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5504                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5505            }
5506        }
5507
5508        if (pending == null && receiver != null) {
5509            // In this case all thumbnails were available and the client
5510            // is being asked to be told when the remaining ones come in...
5511            // which is unusually, since the top-most currently running
5512            // activity should never have a canned thumbnail!  Oh well.
5513            try {
5514                receiver.finished();
5515            } catch (RemoteException ex) {
5516            }
5517        }
5518
5519        return list;
5520    }
5521
5522    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5523            int flags, int userId) {
5524        final int callingUid = Binder.getCallingUid();
5525        if (userId != UserHandle.getCallingUserId()) {
5526            // Check if the caller is holding permissions for cross-user requests.
5527            if (checkComponentPermission(
5528                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5529                    Binder.getCallingPid(), callingUid, -1, true)
5530                    != PackageManager.PERMISSION_GRANTED) {
5531                String msg = "Permission Denial: "
5532                        + "Request to get recent tasks for user " + userId
5533                        + " but is calling from user " + UserHandle.getUserId(callingUid)
5534                        + "; this requires "
5535                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5536                Slog.w(TAG, msg);
5537                throw new SecurityException(msg);
5538            } else {
5539                if (userId == UserHandle.USER_CURRENT) {
5540                    userId = mCurrentUserId;
5541                }
5542            }
5543        }
5544
5545        synchronized (this) {
5546            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5547                    "getRecentTasks()");
5548            final boolean detailed = checkCallingPermission(
5549                    android.Manifest.permission.GET_DETAILED_TASKS)
5550                    == PackageManager.PERMISSION_GRANTED;
5551
5552            IPackageManager pm = AppGlobals.getPackageManager();
5553
5554            final int N = mRecentTasks.size();
5555            ArrayList<ActivityManager.RecentTaskInfo> res
5556                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5557                            maxNum < N ? maxNum : N);
5558            for (int i=0; i<N && maxNum > 0; i++) {
5559                TaskRecord tr = mRecentTasks.get(i);
5560                // Only add calling user's recent tasks
5561                if (tr.userId != userId) continue;
5562                // Return the entry if desired by the caller.  We always return
5563                // the first entry, because callers always expect this to be the
5564                // foreground app.  We may filter others if the caller has
5565                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5566                // we should exclude the entry.
5567
5568                if (i == 0
5569                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5570                        || (tr.intent == null)
5571                        || ((tr.intent.getFlags()
5572                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5573                    ActivityManager.RecentTaskInfo rti
5574                            = new ActivityManager.RecentTaskInfo();
5575                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5576                    rti.persistentId = tr.taskId;
5577                    rti.baseIntent = new Intent(
5578                            tr.intent != null ? tr.intent : tr.affinityIntent);
5579                    if (!detailed) {
5580                        rti.baseIntent.replaceExtras((Bundle)null);
5581                    }
5582                    rti.origActivity = tr.origActivity;
5583                    rti.description = tr.lastDescription;
5584
5585                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5586                        // Check whether this activity is currently available.
5587                        try {
5588                            if (rti.origActivity != null) {
5589                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5590                                        == null) {
5591                                    continue;
5592                                }
5593                            } else if (rti.baseIntent != null) {
5594                                if (pm.queryIntentActivities(rti.baseIntent,
5595                                        null, 0, userId) == null) {
5596                                    continue;
5597                                }
5598                            }
5599                        } catch (RemoteException e) {
5600                            // Will never happen.
5601                        }
5602                    }
5603
5604                    res.add(rti);
5605                    maxNum--;
5606                }
5607            }
5608            return res;
5609        }
5610    }
5611
5612    private TaskRecord taskForIdLocked(int id) {
5613        final int N = mRecentTasks.size();
5614        for (int i=0; i<N; i++) {
5615            TaskRecord tr = mRecentTasks.get(i);
5616            if (tr.taskId == id) {
5617                return tr;
5618            }
5619        }
5620        return null;
5621    }
5622
5623    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5624        synchronized (this) {
5625            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5626                    "getTaskThumbnails()");
5627            TaskRecord tr = taskForIdLocked(id);
5628            if (tr != null) {
5629                return mMainStack.getTaskThumbnailsLocked(tr);
5630            }
5631        }
5632        return null;
5633    }
5634
5635    public boolean removeSubTask(int taskId, int subTaskIndex) {
5636        synchronized (this) {
5637            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5638                    "removeSubTask()");
5639            long ident = Binder.clearCallingIdentity();
5640            try {
5641                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5642                        true) != null;
5643            } finally {
5644                Binder.restoreCallingIdentity(ident);
5645            }
5646        }
5647    }
5648
5649    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5650        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5651        Intent baseIntent = new Intent(
5652                tr.intent != null ? tr.intent : tr.affinityIntent);
5653        ComponentName component = baseIntent.getComponent();
5654        if (component == null) {
5655            Slog.w(TAG, "Now component for base intent of task: " + tr);
5656            return;
5657        }
5658
5659        // Find any running services associated with this app.
5660        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5661
5662        if (killProcesses) {
5663            // Find any running processes associated with this app.
5664            final String pkg = component.getPackageName();
5665            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5666            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5667            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5668                for (int i=0; i<uids.size(); i++) {
5669                    ProcessRecord proc = uids.valueAt(i);
5670                    if (proc.userId != tr.userId) {
5671                        continue;
5672                    }
5673                    if (!proc.pkgList.contains(pkg)) {
5674                        continue;
5675                    }
5676                    procs.add(proc);
5677                }
5678            }
5679
5680            // Kill the running processes.
5681            for (int i=0; i<procs.size(); i++) {
5682                ProcessRecord pr = procs.get(i);
5683                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5684                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5685                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5686                            pr.processName, pr.setAdj, "remove task");
5687                    pr.killedBackground = true;
5688                    Process.killProcessQuiet(pr.pid);
5689                } else {
5690                    pr.waitingToKill = "remove task";
5691                }
5692            }
5693        }
5694    }
5695
5696    public boolean removeTask(int taskId, int flags) {
5697        synchronized (this) {
5698            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5699                    "removeTask()");
5700            long ident = Binder.clearCallingIdentity();
5701            try {
5702                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5703                        false);
5704                if (r != null) {
5705                    mRecentTasks.remove(r.task);
5706                    cleanUpRemovedTaskLocked(r.task, flags);
5707                    return true;
5708                } else {
5709                    TaskRecord tr = null;
5710                    int i=0;
5711                    while (i < mRecentTasks.size()) {
5712                        TaskRecord t = mRecentTasks.get(i);
5713                        if (t.taskId == taskId) {
5714                            tr = t;
5715                            break;
5716                        }
5717                        i++;
5718                    }
5719                    if (tr != null) {
5720                        if (tr.numActivities <= 0) {
5721                            // Caller is just removing a recent task that is
5722                            // not actively running.  That is easy!
5723                            mRecentTasks.remove(i);
5724                            cleanUpRemovedTaskLocked(tr, flags);
5725                            return true;
5726                        } else {
5727                            Slog.w(TAG, "removeTask: task " + taskId
5728                                    + " does not have activities to remove, "
5729                                    + " but numActivities=" + tr.numActivities
5730                                    + ": " + tr);
5731                        }
5732                    }
5733                }
5734            } finally {
5735                Binder.restoreCallingIdentity(ident);
5736            }
5737        }
5738        return false;
5739    }
5740
5741    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5742        int j;
5743        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5744        TaskRecord jt = startTask;
5745
5746        // First look backwards
5747        for (j=startIndex-1; j>=0; j--) {
5748            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5749            if (r.task != jt) {
5750                jt = r.task;
5751                if (affinity.equals(jt.affinity)) {
5752                    return j;
5753                }
5754            }
5755        }
5756
5757        // Now look forwards
5758        final int N = mMainStack.mHistory.size();
5759        jt = startTask;
5760        for (j=startIndex+1; j<N; j++) {
5761            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5762            if (r.task != jt) {
5763                if (affinity.equals(jt.affinity)) {
5764                    return j;
5765                }
5766                jt = r.task;
5767            }
5768        }
5769
5770        // Might it be at the top?
5771        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5772            return N-1;
5773        }
5774
5775        return -1;
5776    }
5777
5778    /**
5779     * TODO: Add mController hook
5780     */
5781    public void moveTaskToFront(int task, int flags, Bundle options) {
5782        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5783                "moveTaskToFront()");
5784
5785        synchronized(this) {
5786            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5787                    Binder.getCallingUid(), "Task to front")) {
5788                ActivityOptions.abort(options);
5789                return;
5790            }
5791            final long origId = Binder.clearCallingIdentity();
5792            try {
5793                TaskRecord tr = taskForIdLocked(task);
5794                if (tr != null) {
5795                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5796                        mMainStack.mUserLeaving = true;
5797                    }
5798                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5799                        // Caller wants the home activity moved with it.  To accomplish this,
5800                        // we'll just move the home task to the top first.
5801                        mMainStack.moveHomeToFrontLocked();
5802                    }
5803                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5804                    return;
5805                }
5806                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5807                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5808                    if (hr.task.taskId == task) {
5809                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5810                            mMainStack.mUserLeaving = true;
5811                        }
5812                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5813                            // Caller wants the home activity moved with it.  To accomplish this,
5814                            // we'll just move the home task to the top first.
5815                            mMainStack.moveHomeToFrontLocked();
5816                        }
5817                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5818                        return;
5819                    }
5820                }
5821            } finally {
5822                Binder.restoreCallingIdentity(origId);
5823            }
5824            ActivityOptions.abort(options);
5825        }
5826    }
5827
5828    public void moveTaskToBack(int task) {
5829        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5830                "moveTaskToBack()");
5831
5832        synchronized(this) {
5833            if (mMainStack.mResumedActivity != null
5834                    && mMainStack.mResumedActivity.task.taskId == task) {
5835                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5836                        Binder.getCallingUid(), "Task to back")) {
5837                    return;
5838                }
5839            }
5840            final long origId = Binder.clearCallingIdentity();
5841            mMainStack.moveTaskToBackLocked(task, null);
5842            Binder.restoreCallingIdentity(origId);
5843        }
5844    }
5845
5846    /**
5847     * Moves an activity, and all of the other activities within the same task, to the bottom
5848     * of the history stack.  The activity's order within the task is unchanged.
5849     *
5850     * @param token A reference to the activity we wish to move
5851     * @param nonRoot If false then this only works if the activity is the root
5852     *                of a task; if true it will work for any activity in a task.
5853     * @return Returns true if the move completed, false if not.
5854     */
5855    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5856        enforceNotIsolatedCaller("moveActivityTaskToBack");
5857        synchronized(this) {
5858            final long origId = Binder.clearCallingIdentity();
5859            int taskId = getTaskForActivityLocked(token, !nonRoot);
5860            if (taskId >= 0) {
5861                return mMainStack.moveTaskToBackLocked(taskId, null);
5862            }
5863            Binder.restoreCallingIdentity(origId);
5864        }
5865        return false;
5866    }
5867
5868    public void moveTaskBackwards(int task) {
5869        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5870                "moveTaskBackwards()");
5871
5872        synchronized(this) {
5873            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5874                    Binder.getCallingUid(), "Task backwards")) {
5875                return;
5876            }
5877            final long origId = Binder.clearCallingIdentity();
5878            moveTaskBackwardsLocked(task);
5879            Binder.restoreCallingIdentity(origId);
5880        }
5881    }
5882
5883    private final void moveTaskBackwardsLocked(int task) {
5884        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5885    }
5886
5887    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5888        synchronized(this) {
5889            return getTaskForActivityLocked(token, onlyRoot);
5890        }
5891    }
5892
5893    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5894        final int N = mMainStack.mHistory.size();
5895        TaskRecord lastTask = null;
5896        for (int i=0; i<N; i++) {
5897            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5898            if (r.appToken == token) {
5899                if (!onlyRoot || lastTask != r.task) {
5900                    return r.task.taskId;
5901                }
5902                return -1;
5903            }
5904            lastTask = r.task;
5905        }
5906
5907        return -1;
5908    }
5909
5910    // =========================================================
5911    // THUMBNAILS
5912    // =========================================================
5913
5914    public void reportThumbnail(IBinder token,
5915            Bitmap thumbnail, CharSequence description) {
5916        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5917        final long origId = Binder.clearCallingIdentity();
5918        sendPendingThumbnail(null, token, thumbnail, description, true);
5919        Binder.restoreCallingIdentity(origId);
5920    }
5921
5922    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5923            Bitmap thumbnail, CharSequence description, boolean always) {
5924        TaskRecord task = null;
5925        ArrayList receivers = null;
5926
5927        //System.out.println("Send pending thumbnail: " + r);
5928
5929        synchronized(this) {
5930            if (r == null) {
5931                r = mMainStack.isInStackLocked(token);
5932                if (r == null) {
5933                    return;
5934                }
5935            }
5936            if (thumbnail == null && r.thumbHolder != null) {
5937                thumbnail = r.thumbHolder.lastThumbnail;
5938                description = r.thumbHolder.lastDescription;
5939            }
5940            if (thumbnail == null && !always) {
5941                // If there is no thumbnail, and this entry is not actually
5942                // going away, then abort for now and pick up the next
5943                // thumbnail we get.
5944                return;
5945            }
5946            task = r.task;
5947
5948            int N = mPendingThumbnails.size();
5949            int i=0;
5950            while (i<N) {
5951                PendingThumbnailsRecord pr =
5952                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5953                //System.out.println("Looking in " + pr.pendingRecords);
5954                if (pr.pendingRecords.remove(r)) {
5955                    if (receivers == null) {
5956                        receivers = new ArrayList();
5957                    }
5958                    receivers.add(pr);
5959                    if (pr.pendingRecords.size() == 0) {
5960                        pr.finished = true;
5961                        mPendingThumbnails.remove(i);
5962                        N--;
5963                        continue;
5964                    }
5965                }
5966                i++;
5967            }
5968        }
5969
5970        if (receivers != null) {
5971            final int N = receivers.size();
5972            for (int i=0; i<N; i++) {
5973                try {
5974                    PendingThumbnailsRecord pr =
5975                        (PendingThumbnailsRecord)receivers.get(i);
5976                    pr.receiver.newThumbnail(
5977                        task != null ? task.taskId : -1, thumbnail, description);
5978                    if (pr.finished) {
5979                        pr.receiver.finished();
5980                    }
5981                } catch (Exception e) {
5982                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
5983                }
5984            }
5985        }
5986    }
5987
5988    // =========================================================
5989    // CONTENT PROVIDERS
5990    // =========================================================
5991
5992    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5993        List<ProviderInfo> providers = null;
5994        try {
5995            providers = AppGlobals.getPackageManager().
5996                queryContentProviders(app.processName, app.uid,
5997                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
5998        } catch (RemoteException ex) {
5999        }
6000        if (DEBUG_MU)
6001            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6002        int userId = app.userId;
6003        if (providers != null) {
6004            int N = providers.size();
6005            for (int i=0; i<N; i++) {
6006                ProviderInfo cpi =
6007                    (ProviderInfo)providers.get(i);
6008                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6009                        cpi.name, cpi.flags);
6010                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6011                    // This is a singleton provider, but a user besides the
6012                    // default user is asking to initialize a process it runs
6013                    // in...  well, no, it doesn't actually run in this process,
6014                    // it runs in the process of the default user.  Get rid of it.
6015                    providers.remove(i);
6016                    N--;
6017                    continue;
6018                }
6019
6020                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6021                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6022                if (cpr == null) {
6023                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6024                    mProviderMap.putProviderByClass(comp, cpr);
6025                }
6026                if (DEBUG_MU)
6027                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6028                app.pubProviders.put(cpi.name, cpr);
6029                app.addPackage(cpi.applicationInfo.packageName);
6030                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6031            }
6032        }
6033        return providers;
6034    }
6035
6036    /**
6037     * Check if {@link ProcessRecord} has a possible chance at accessing the
6038     * given {@link ProviderInfo}. Final permission checking is always done
6039     * in {@link ContentProvider}.
6040     */
6041    private final String checkContentProviderPermissionLocked(
6042            ProviderInfo cpi, ProcessRecord r) {
6043        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6044        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6045        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6046                cpi.applicationInfo.uid, cpi.exported)
6047                == PackageManager.PERMISSION_GRANTED) {
6048            return null;
6049        }
6050        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6051                cpi.applicationInfo.uid, cpi.exported)
6052                == PackageManager.PERMISSION_GRANTED) {
6053            return null;
6054        }
6055
6056        PathPermission[] pps = cpi.pathPermissions;
6057        if (pps != null) {
6058            int i = pps.length;
6059            while (i > 0) {
6060                i--;
6061                PathPermission pp = pps[i];
6062                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6063                        cpi.applicationInfo.uid, cpi.exported)
6064                        == PackageManager.PERMISSION_GRANTED) {
6065                    return null;
6066                }
6067                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6068                        cpi.applicationInfo.uid, cpi.exported)
6069                        == PackageManager.PERMISSION_GRANTED) {
6070                    return null;
6071                }
6072            }
6073        }
6074
6075        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6076        if (perms != null) {
6077            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6078                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6079                    return null;
6080                }
6081            }
6082        }
6083
6084        String msg;
6085        if (!cpi.exported) {
6086            msg = "Permission Denial: opening provider " + cpi.name
6087                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6088                    + ", uid=" + callingUid + ") that is not exported from uid "
6089                    + cpi.applicationInfo.uid;
6090        } else {
6091            msg = "Permission Denial: opening provider " + cpi.name
6092                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6093                    + ", uid=" + callingUid + ") requires "
6094                    + cpi.readPermission + " or " + cpi.writePermission;
6095        }
6096        Slog.w(TAG, msg);
6097        return msg;
6098    }
6099
6100    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6101            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6102        if (r != null) {
6103            for (int i=0; i<r.conProviders.size(); i++) {
6104                ContentProviderConnection conn = r.conProviders.get(i);
6105                if (conn.provider == cpr) {
6106                    if (DEBUG_PROVIDER) Slog.v(TAG,
6107                            "Adding provider requested by "
6108                            + r.processName + " from process "
6109                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6110                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6111                    if (stable) {
6112                        conn.stableCount++;
6113                        conn.numStableIncs++;
6114                    } else {
6115                        conn.unstableCount++;
6116                        conn.numUnstableIncs++;
6117                    }
6118                    return conn;
6119                }
6120            }
6121            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6122            if (stable) {
6123                conn.stableCount = 1;
6124                conn.numStableIncs = 1;
6125            } else {
6126                conn.unstableCount = 1;
6127                conn.numUnstableIncs = 1;
6128            }
6129            cpr.connections.add(conn);
6130            r.conProviders.add(conn);
6131            return conn;
6132        }
6133        cpr.addExternalProcessHandleLocked(externalProcessToken);
6134        return null;
6135    }
6136
6137    boolean decProviderCountLocked(ContentProviderConnection conn,
6138            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6139        if (conn != null) {
6140            cpr = conn.provider;
6141            if (DEBUG_PROVIDER) Slog.v(TAG,
6142                    "Removing provider requested by "
6143                    + conn.client.processName + " from process "
6144                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6145                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6146            if (stable) {
6147                conn.stableCount--;
6148            } else {
6149                conn.unstableCount--;
6150            }
6151            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6152                cpr.connections.remove(conn);
6153                conn.client.conProviders.remove(conn);
6154                return true;
6155            }
6156            return false;
6157        }
6158        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6159        return false;
6160    }
6161
6162    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6163            String name, IBinder token, boolean stable) {
6164        ContentProviderRecord cpr;
6165        ContentProviderConnection conn = null;
6166        ProviderInfo cpi = null;
6167
6168        synchronized(this) {
6169            ProcessRecord r = null;
6170            if (caller != null) {
6171                r = getRecordForAppLocked(caller);
6172                if (r == null) {
6173                    throw new SecurityException(
6174                            "Unable to find app for caller " + caller
6175                          + " (pid=" + Binder.getCallingPid()
6176                          + ") when getting content provider " + name);
6177                }
6178            }
6179
6180            // First check if this content provider has been published...
6181            int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid());
6182            cpr = mProviderMap.getProviderByName(name, userId);
6183            boolean providerRunning = cpr != null;
6184            if (providerRunning) {
6185                cpi = cpr.info;
6186                String msg;
6187                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6188                    throw new SecurityException(msg);
6189                }
6190
6191                if (r != null && cpr.canRunHere(r)) {
6192                    // This provider has been published or is in the process
6193                    // of being published...  but it is also allowed to run
6194                    // in the caller's process, so don't make a connection
6195                    // and just let the caller instantiate its own instance.
6196                    ContentProviderHolder holder = cpr.newHolder(null);
6197                    // don't give caller the provider object, it needs
6198                    // to make its own.
6199                    holder.provider = null;
6200                    return holder;
6201                }
6202
6203                final long origId = Binder.clearCallingIdentity();
6204
6205                // In this case the provider instance already exists, so we can
6206                // return it right away.
6207                conn = incProviderCountLocked(r, cpr, token, stable);
6208                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6209                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6210                        // If this is a perceptible app accessing the provider,
6211                        // make sure to count it as being accessed and thus
6212                        // back up on the LRU list.  This is good because
6213                        // content providers are often expensive to start.
6214                        updateLruProcessLocked(cpr.proc, false, true);
6215                    }
6216                }
6217
6218                if (cpr.proc != null) {
6219                    if (false) {
6220                        if (cpr.name.flattenToShortString().equals(
6221                                "com.android.providers.calendar/.CalendarProvider2")) {
6222                            Slog.v(TAG, "****************** KILLING "
6223                                + cpr.name.flattenToShortString());
6224                            Process.killProcess(cpr.proc.pid);
6225                        }
6226                    }
6227                    boolean success = updateOomAdjLocked(cpr.proc);
6228                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6229                    // NOTE: there is still a race here where a signal could be
6230                    // pending on the process even though we managed to update its
6231                    // adj level.  Not sure what to do about this, but at least
6232                    // the race is now smaller.
6233                    if (!success) {
6234                        // Uh oh...  it looks like the provider's process
6235                        // has been killed on us.  We need to wait for a new
6236                        // process to be started, and make sure its death
6237                        // doesn't kill our process.
6238                        Slog.i(TAG,
6239                                "Existing provider " + cpr.name.flattenToShortString()
6240                                + " is crashing; detaching " + r);
6241                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6242                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6243                        if (!lastRef) {
6244                            // This wasn't the last ref our process had on
6245                            // the provider...  we have now been killed, bail.
6246                            return null;
6247                        }
6248                        providerRunning = false;
6249                        conn = null;
6250                    }
6251                }
6252
6253                Binder.restoreCallingIdentity(origId);
6254            }
6255
6256            boolean singleton;
6257            if (!providerRunning) {
6258                try {
6259                    cpi = AppGlobals.getPackageManager().
6260                        resolveContentProvider(name,
6261                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6262                } catch (RemoteException ex) {
6263                }
6264                if (cpi == null) {
6265                    return null;
6266                }
6267                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6268                        cpi.name, cpi.flags);
6269                if (singleton) {
6270                    userId = 0;
6271                }
6272                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6273
6274                String msg;
6275                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6276                    throw new SecurityException(msg);
6277                }
6278
6279                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6280                        && !cpi.processName.equals("system")) {
6281                    // If this content provider does not run in the system
6282                    // process, and the system is not yet ready to run other
6283                    // processes, then fail fast instead of hanging.
6284                    throw new IllegalArgumentException(
6285                            "Attempt to launch content provider before system ready");
6286                }
6287
6288                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6289                cpr = mProviderMap.getProviderByClass(comp, userId);
6290                final boolean firstClass = cpr == null;
6291                if (firstClass) {
6292                    try {
6293                        ApplicationInfo ai =
6294                            AppGlobals.getPackageManager().
6295                                getApplicationInfo(
6296                                        cpi.applicationInfo.packageName,
6297                                        STOCK_PM_FLAGS, userId);
6298                        if (ai == null) {
6299                            Slog.w(TAG, "No package info for content provider "
6300                                    + cpi.name);
6301                            return null;
6302                        }
6303                        ai = getAppInfoForUser(ai, userId);
6304                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6305                    } catch (RemoteException ex) {
6306                        // pm is in same process, this will never happen.
6307                    }
6308                }
6309
6310                if (r != null && cpr.canRunHere(r)) {
6311                    // If this is a multiprocess provider, then just return its
6312                    // info and allow the caller to instantiate it.  Only do
6313                    // this if the provider is the same user as the caller's
6314                    // process, or can run as root (so can be in any process).
6315                    return cpr.newHolder(null);
6316                }
6317
6318                if (DEBUG_PROVIDER) {
6319                    RuntimeException e = new RuntimeException("here");
6320                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6321                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6322                }
6323
6324                // This is single process, and our app is now connecting to it.
6325                // See if we are already in the process of launching this
6326                // provider.
6327                final int N = mLaunchingProviders.size();
6328                int i;
6329                for (i=0; i<N; i++) {
6330                    if (mLaunchingProviders.get(i) == cpr) {
6331                        break;
6332                    }
6333                }
6334
6335                // If the provider is not already being launched, then get it
6336                // started.
6337                if (i >= N) {
6338                    final long origId = Binder.clearCallingIdentity();
6339
6340                    try {
6341                        // Content provider is now in use, its package can't be stopped.
6342                        try {
6343                            AppGlobals.getPackageManager().setPackageStoppedState(
6344                                    cpr.appInfo.packageName, false, userId);
6345                        } catch (RemoteException e) {
6346                        } catch (IllegalArgumentException e) {
6347                            Slog.w(TAG, "Failed trying to unstop package "
6348                                    + cpr.appInfo.packageName + ": " + e);
6349                        }
6350
6351                        ProcessRecord proc = startProcessLocked(cpi.processName,
6352                                cpr.appInfo, false, 0, "content provider",
6353                                new ComponentName(cpi.applicationInfo.packageName,
6354                                        cpi.name), false, false);
6355                        if (proc == null) {
6356                            Slog.w(TAG, "Unable to launch app "
6357                                    + cpi.applicationInfo.packageName + "/"
6358                                    + cpi.applicationInfo.uid + " for provider "
6359                                    + name + ": process is bad");
6360                            return null;
6361                        }
6362                        cpr.launchingApp = proc;
6363                        mLaunchingProviders.add(cpr);
6364                    } finally {
6365                        Binder.restoreCallingIdentity(origId);
6366                    }
6367                }
6368
6369                // Make sure the provider is published (the same provider class
6370                // may be published under multiple names).
6371                if (firstClass) {
6372                    mProviderMap.putProviderByClass(comp, cpr);
6373                }
6374
6375                mProviderMap.putProviderByName(name, cpr);
6376                conn = incProviderCountLocked(r, cpr, token, stable);
6377                if (conn != null) {
6378                    conn.waiting = true;
6379                }
6380            }
6381        }
6382
6383        // Wait for the provider to be published...
6384        synchronized (cpr) {
6385            while (cpr.provider == null) {
6386                if (cpr.launchingApp == null) {
6387                    Slog.w(TAG, "Unable to launch app "
6388                            + cpi.applicationInfo.packageName + "/"
6389                            + cpi.applicationInfo.uid + " for provider "
6390                            + name + ": launching app became null");
6391                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6392                            cpi.applicationInfo.packageName,
6393                            cpi.applicationInfo.uid, name);
6394                    return null;
6395                }
6396                try {
6397                    if (DEBUG_MU) {
6398                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6399                                + cpr.launchingApp);
6400                    }
6401                    if (conn != null) {
6402                        conn.waiting = true;
6403                    }
6404                    cpr.wait();
6405                } catch (InterruptedException ex) {
6406                } finally {
6407                    if (conn != null) {
6408                        conn.waiting = false;
6409                    }
6410                }
6411            }
6412        }
6413        return cpr != null ? cpr.newHolder(conn) : null;
6414    }
6415
6416    public final ContentProviderHolder getContentProvider(
6417            IApplicationThread caller, String name, boolean stable) {
6418        enforceNotIsolatedCaller("getContentProvider");
6419        if (caller == null) {
6420            String msg = "null IApplicationThread when getting content provider "
6421                    + name;
6422            Slog.w(TAG, msg);
6423            throw new SecurityException(msg);
6424        }
6425
6426        return getContentProviderImpl(caller, name, null, stable);
6427    }
6428
6429    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6430        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6431            "Do not have permission in call getContentProviderExternal()");
6432        return getContentProviderExternalUnchecked(name, token);
6433    }
6434
6435    private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
6436        return getContentProviderImpl(null, name, token, true);
6437    }
6438
6439    /**
6440     * Drop a content provider from a ProcessRecord's bookkeeping
6441     * @param cpr
6442     */
6443    public void removeContentProvider(IBinder connection, boolean stable) {
6444        enforceNotIsolatedCaller("removeContentProvider");
6445        synchronized (this) {
6446            ContentProviderConnection conn;
6447            try {
6448                conn = (ContentProviderConnection)connection;
6449            } catch (ClassCastException e) {
6450                String msg ="removeContentProvider: " + connection
6451                        + " not a ContentProviderConnection";
6452                Slog.w(TAG, msg);
6453                throw new IllegalArgumentException(msg);
6454            }
6455            if (conn == null) {
6456                throw new NullPointerException("connection is null");
6457            }
6458            if (decProviderCountLocked(conn, null, null, stable)) {
6459                updateOomAdjLocked();
6460            }
6461        }
6462    }
6463
6464    public void removeContentProviderExternal(String name, IBinder token) {
6465        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6466            "Do not have permission in call removeContentProviderExternal()");
6467        removeContentProviderExternalUnchecked(name, token);
6468    }
6469
6470    private void removeContentProviderExternalUnchecked(String name, IBinder token) {
6471        synchronized (this) {
6472            ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6473                    Binder.getOrigCallingUser());
6474            if(cpr == null) {
6475                //remove from mProvidersByClass
6476                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6477                return;
6478            }
6479
6480            //update content provider record entry info
6481            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6482            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6483                    Binder.getOrigCallingUser());
6484            if (localCpr.hasExternalProcessHandles()) {
6485                if (localCpr.removeExternalProcessHandleLocked(token)) {
6486                    updateOomAdjLocked();
6487                } else {
6488                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6489                            + " with no external reference for token: "
6490                            + token + ".");
6491                }
6492            } else {
6493                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6494                        + " with no external references.");
6495            }
6496        }
6497    }
6498
6499    public final void publishContentProviders(IApplicationThread caller,
6500            List<ContentProviderHolder> providers) {
6501        if (providers == null) {
6502            return;
6503        }
6504
6505        enforceNotIsolatedCaller("publishContentProviders");
6506        synchronized (this) {
6507            final ProcessRecord r = getRecordForAppLocked(caller);
6508            if (DEBUG_MU)
6509                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6510            if (r == null) {
6511                throw new SecurityException(
6512                        "Unable to find app for caller " + caller
6513                      + " (pid=" + Binder.getCallingPid()
6514                      + ") when publishing content providers");
6515            }
6516
6517            final long origId = Binder.clearCallingIdentity();
6518
6519            final int N = providers.size();
6520            for (int i=0; i<N; i++) {
6521                ContentProviderHolder src = providers.get(i);
6522                if (src == null || src.info == null || src.provider == null) {
6523                    continue;
6524                }
6525                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6526                if (DEBUG_MU)
6527                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6528                if (dst != null) {
6529                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6530                    mProviderMap.putProviderByClass(comp, dst);
6531                    String names[] = dst.info.authority.split(";");
6532                    for (int j = 0; j < names.length; j++) {
6533                        mProviderMap.putProviderByName(names[j], dst);
6534                    }
6535
6536                    int NL = mLaunchingProviders.size();
6537                    int j;
6538                    for (j=0; j<NL; j++) {
6539                        if (mLaunchingProviders.get(j) == dst) {
6540                            mLaunchingProviders.remove(j);
6541                            j--;
6542                            NL--;
6543                        }
6544                    }
6545                    synchronized (dst) {
6546                        dst.provider = src.provider;
6547                        dst.proc = r;
6548                        dst.notifyAll();
6549                    }
6550                    updateOomAdjLocked(r);
6551                }
6552            }
6553
6554            Binder.restoreCallingIdentity(origId);
6555        }
6556    }
6557
6558    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6559        ContentProviderConnection conn;
6560        try {
6561            conn = (ContentProviderConnection)connection;
6562        } catch (ClassCastException e) {
6563            String msg ="refContentProvider: " + connection
6564                    + " not a ContentProviderConnection";
6565            Slog.w(TAG, msg);
6566            throw new IllegalArgumentException(msg);
6567        }
6568        if (conn == null) {
6569            throw new NullPointerException("connection is null");
6570        }
6571
6572        synchronized (this) {
6573            if (stable > 0) {
6574                conn.numStableIncs += stable;
6575            }
6576            stable = conn.stableCount + stable;
6577            if (stable < 0) {
6578                throw new IllegalStateException("stableCount < 0: " + stable);
6579            }
6580
6581            if (unstable > 0) {
6582                conn.numUnstableIncs += unstable;
6583            }
6584            unstable = conn.unstableCount + unstable;
6585            if (unstable < 0) {
6586                throw new IllegalStateException("unstableCount < 0: " + unstable);
6587            }
6588
6589            if ((stable+unstable) <= 0) {
6590                throw new IllegalStateException("ref counts can't go to zero here: stable="
6591                        + stable + " unstable=" + unstable);
6592            }
6593            conn.stableCount = stable;
6594            conn.unstableCount = unstable;
6595            return !conn.dead;
6596        }
6597    }
6598
6599    public void unstableProviderDied(IBinder connection) {
6600        ContentProviderConnection conn;
6601        try {
6602            conn = (ContentProviderConnection)connection;
6603        } catch (ClassCastException e) {
6604            String msg ="refContentProvider: " + connection
6605                    + " not a ContentProviderConnection";
6606            Slog.w(TAG, msg);
6607            throw new IllegalArgumentException(msg);
6608        }
6609        if (conn == null) {
6610            throw new NullPointerException("connection is null");
6611        }
6612
6613        // Safely retrieve the content provider associated with the connection.
6614        IContentProvider provider;
6615        synchronized (this) {
6616            provider = conn.provider.provider;
6617        }
6618
6619        if (provider == null) {
6620            // Um, yeah, we're way ahead of you.
6621            return;
6622        }
6623
6624        // Make sure the caller is being honest with us.
6625        if (provider.asBinder().pingBinder()) {
6626            // Er, no, still looks good to us.
6627            synchronized (this) {
6628                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6629                        + " says " + conn + " died, but we don't agree");
6630                return;
6631            }
6632        }
6633
6634        // Well look at that!  It's dead!
6635        synchronized (this) {
6636            if (conn.provider.provider != provider) {
6637                // But something changed...  good enough.
6638                return;
6639            }
6640
6641            ProcessRecord proc = conn.provider.proc;
6642            if (proc == null || proc.thread == null) {
6643                // Seems like the process is already cleaned up.
6644                return;
6645            }
6646
6647            // As far as we're concerned, this is just like receiving a
6648            // death notification...  just a bit prematurely.
6649            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6650                    + ") early provider death");
6651            final long ident = Binder.clearCallingIdentity();
6652            try {
6653                appDiedLocked(proc, proc.pid, proc.thread);
6654            } finally {
6655                Binder.restoreCallingIdentity(ident);
6656            }
6657        }
6658    }
6659
6660    public static final void installSystemProviders() {
6661        List<ProviderInfo> providers;
6662        synchronized (mSelf) {
6663            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6664            providers = mSelf.generateApplicationProvidersLocked(app);
6665            if (providers != null) {
6666                for (int i=providers.size()-1; i>=0; i--) {
6667                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6668                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6669                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6670                                + ": not system .apk");
6671                        providers.remove(i);
6672                    }
6673                }
6674            }
6675        }
6676        if (providers != null) {
6677            mSystemThread.installSystemProviders(providers);
6678        }
6679
6680        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6681
6682        mSelf.mUsageStatsService.monitorPackages();
6683    }
6684
6685    /**
6686     * Allows app to retrieve the MIME type of a URI without having permission
6687     * to access its content provider.
6688     *
6689     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6690     *
6691     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6692     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6693     */
6694    public String getProviderMimeType(Uri uri) {
6695        enforceNotIsolatedCaller("getProviderMimeType");
6696        final String name = uri.getAuthority();
6697        final long ident = Binder.clearCallingIdentity();
6698        ContentProviderHolder holder = null;
6699
6700        try {
6701            holder = getContentProviderExternalUnchecked(name, null);
6702            if (holder != null) {
6703                return holder.provider.getType(uri);
6704            }
6705        } catch (RemoteException e) {
6706            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6707            return null;
6708        } finally {
6709            if (holder != null) {
6710                removeContentProviderExternalUnchecked(name, null);
6711            }
6712            Binder.restoreCallingIdentity(ident);
6713        }
6714
6715        return null;
6716    }
6717
6718    // =========================================================
6719    // GLOBAL MANAGEMENT
6720    // =========================================================
6721
6722    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6723            ApplicationInfo info, String customProcess, boolean isolated) {
6724        String proc = customProcess != null ? customProcess : info.processName;
6725        BatteryStatsImpl.Uid.Proc ps = null;
6726        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6727        int uid = info.uid;
6728        if (isolated) {
6729            int userId = UserHandle.getUserId(uid);
6730            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6731            uid = 0;
6732            while (true) {
6733                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6734                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6735                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6736                }
6737                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6738                mNextIsolatedProcessUid++;
6739                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6740                    // No process for this uid, use it.
6741                    break;
6742                }
6743                stepsLeft--;
6744                if (stepsLeft <= 0) {
6745                    return null;
6746                }
6747            }
6748        }
6749        synchronized (stats) {
6750            ps = stats.getProcessStatsLocked(info.uid, proc);
6751        }
6752        return new ProcessRecord(ps, thread, info, proc, uid);
6753    }
6754
6755    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6756        ProcessRecord app;
6757        if (!isolated) {
6758            app = getProcessRecordLocked(info.processName, info.uid);
6759        } else {
6760            app = null;
6761        }
6762
6763        if (app == null) {
6764            app = newProcessRecordLocked(null, info, null, isolated);
6765            mProcessNames.put(info.processName, app.uid, app);
6766            if (isolated) {
6767                mIsolatedProcesses.put(app.uid, app);
6768            }
6769            updateLruProcessLocked(app, true, true);
6770        }
6771
6772        // This package really, really can not be stopped.
6773        try {
6774            AppGlobals.getPackageManager().setPackageStoppedState(
6775                    info.packageName, false, UserHandle.getUserId(app.uid));
6776        } catch (RemoteException e) {
6777        } catch (IllegalArgumentException e) {
6778            Slog.w(TAG, "Failed trying to unstop package "
6779                    + info.packageName + ": " + e);
6780        }
6781
6782        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6783                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6784            app.persistent = true;
6785            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6786        }
6787        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6788            mPersistentStartingProcesses.add(app);
6789            startProcessLocked(app, "added application", app.processName);
6790        }
6791
6792        return app;
6793    }
6794
6795    public void unhandledBack() {
6796        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6797                "unhandledBack()");
6798
6799        synchronized(this) {
6800            int count = mMainStack.mHistory.size();
6801            if (DEBUG_SWITCH) Slog.d(
6802                TAG, "Performing unhandledBack(): stack size = " + count);
6803            if (count > 1) {
6804                final long origId = Binder.clearCallingIdentity();
6805                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6806                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6807                Binder.restoreCallingIdentity(origId);
6808            }
6809        }
6810    }
6811
6812    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6813        enforceNotIsolatedCaller("openContentUri");
6814        String name = uri.getAuthority();
6815        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
6816        ParcelFileDescriptor pfd = null;
6817        if (cph != null) {
6818            // We record the binder invoker's uid in thread-local storage before
6819            // going to the content provider to open the file.  Later, in the code
6820            // that handles all permissions checks, we look for this uid and use
6821            // that rather than the Activity Manager's own uid.  The effect is that
6822            // we do the check against the caller's permissions even though it looks
6823            // to the content provider like the Activity Manager itself is making
6824            // the request.
6825            sCallerIdentity.set(new Identity(
6826                    Binder.getCallingPid(), Binder.getCallingUid()));
6827            try {
6828                pfd = cph.provider.openFile(uri, "r");
6829            } catch (FileNotFoundException e) {
6830                // do nothing; pfd will be returned null
6831            } finally {
6832                // Ensure that whatever happens, we clean up the identity state
6833                sCallerIdentity.remove();
6834            }
6835
6836            // We've got the fd now, so we're done with the provider.
6837            removeContentProviderExternalUnchecked(name, null);
6838        } else {
6839            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6840        }
6841        return pfd;
6842    }
6843
6844    // Actually is sleeping or shutting down or whatever else in the future
6845    // is an inactive state.
6846    public boolean isSleeping() {
6847        return mSleeping || mShuttingDown;
6848    }
6849
6850    public void goingToSleep() {
6851        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6852                != PackageManager.PERMISSION_GRANTED) {
6853            throw new SecurityException("Requires permission "
6854                    + android.Manifest.permission.DEVICE_POWER);
6855        }
6856
6857        synchronized(this) {
6858            mWentToSleep = true;
6859            updateEventDispatchingLocked();
6860
6861            if (!mSleeping) {
6862                mSleeping = true;
6863                mMainStack.stopIfSleepingLocked();
6864
6865                // Initialize the wake times of all processes.
6866                checkExcessivePowerUsageLocked(false);
6867                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6868                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6869                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6870            }
6871        }
6872    }
6873
6874    public boolean shutdown(int timeout) {
6875        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6876                != PackageManager.PERMISSION_GRANTED) {
6877            throw new SecurityException("Requires permission "
6878                    + android.Manifest.permission.SHUTDOWN);
6879        }
6880
6881        boolean timedout = false;
6882
6883        synchronized(this) {
6884            mShuttingDown = true;
6885            updateEventDispatchingLocked();
6886
6887            if (mMainStack.mResumedActivity != null) {
6888                mMainStack.stopIfSleepingLocked();
6889                final long endTime = System.currentTimeMillis() + timeout;
6890                while (mMainStack.mResumedActivity != null
6891                        || mMainStack.mPausingActivity != null) {
6892                    long delay = endTime - System.currentTimeMillis();
6893                    if (delay <= 0) {
6894                        Slog.w(TAG, "Activity manager shutdown timed out");
6895                        timedout = true;
6896                        break;
6897                    }
6898                    try {
6899                        this.wait();
6900                    } catch (InterruptedException e) {
6901                    }
6902                }
6903            }
6904        }
6905
6906        mUsageStatsService.shutdown();
6907        mBatteryStatsService.shutdown();
6908
6909        return timedout;
6910    }
6911
6912    public final void activitySlept(IBinder token) {
6913        if (localLOGV) Slog.v(
6914            TAG, "Activity slept: token=" + token);
6915
6916        ActivityRecord r = null;
6917
6918        final long origId = Binder.clearCallingIdentity();
6919
6920        synchronized (this) {
6921            r = mMainStack.isInStackLocked(token);
6922            if (r != null) {
6923                mMainStack.activitySleptLocked(r);
6924            }
6925        }
6926
6927        Binder.restoreCallingIdentity(origId);
6928    }
6929
6930    private void comeOutOfSleepIfNeededLocked() {
6931        if (!mWentToSleep && !mLockScreenShown) {
6932            if (mSleeping) {
6933                mSleeping = false;
6934                mMainStack.awakeFromSleepingLocked();
6935                mMainStack.resumeTopActivityLocked(null);
6936            }
6937        }
6938    }
6939
6940    public void wakingUp() {
6941        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6942                != PackageManager.PERMISSION_GRANTED) {
6943            throw new SecurityException("Requires permission "
6944                    + android.Manifest.permission.DEVICE_POWER);
6945        }
6946
6947        synchronized(this) {
6948            mWentToSleep = false;
6949            updateEventDispatchingLocked();
6950            comeOutOfSleepIfNeededLocked();
6951        }
6952    }
6953
6954    private void updateEventDispatchingLocked() {
6955        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
6956    }
6957
6958    public void setLockScreenShown(boolean shown) {
6959        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6960                != PackageManager.PERMISSION_GRANTED) {
6961            throw new SecurityException("Requires permission "
6962                    + android.Manifest.permission.DEVICE_POWER);
6963        }
6964
6965        synchronized(this) {
6966            mLockScreenShown = shown;
6967            comeOutOfSleepIfNeededLocked();
6968        }
6969    }
6970
6971    public void stopAppSwitches() {
6972        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6973                != PackageManager.PERMISSION_GRANTED) {
6974            throw new SecurityException("Requires permission "
6975                    + android.Manifest.permission.STOP_APP_SWITCHES);
6976        }
6977
6978        synchronized(this) {
6979            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6980                    + APP_SWITCH_DELAY_TIME;
6981            mDidAppSwitch = false;
6982            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6983            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6984            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6985        }
6986    }
6987
6988    public void resumeAppSwitches() {
6989        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6990                != PackageManager.PERMISSION_GRANTED) {
6991            throw new SecurityException("Requires permission "
6992                    + android.Manifest.permission.STOP_APP_SWITCHES);
6993        }
6994
6995        synchronized(this) {
6996            // Note that we don't execute any pending app switches... we will
6997            // let those wait until either the timeout, or the next start
6998            // activity request.
6999            mAppSwitchesAllowedTime = 0;
7000        }
7001    }
7002
7003    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7004            String name) {
7005        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7006            return true;
7007        }
7008
7009        final int perm = checkComponentPermission(
7010                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7011                callingUid, -1, true);
7012        if (perm == PackageManager.PERMISSION_GRANTED) {
7013            return true;
7014        }
7015
7016        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7017        return false;
7018    }
7019
7020    public void setDebugApp(String packageName, boolean waitForDebugger,
7021            boolean persistent) {
7022        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7023                "setDebugApp()");
7024
7025        // Note that this is not really thread safe if there are multiple
7026        // callers into it at the same time, but that's not a situation we
7027        // care about.
7028        if (persistent) {
7029            final ContentResolver resolver = mContext.getContentResolver();
7030            Settings.System.putString(
7031                resolver, Settings.System.DEBUG_APP,
7032                packageName);
7033            Settings.System.putInt(
7034                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7035                waitForDebugger ? 1 : 0);
7036        }
7037
7038        synchronized (this) {
7039            if (!persistent) {
7040                mOrigDebugApp = mDebugApp;
7041                mOrigWaitForDebugger = mWaitForDebugger;
7042            }
7043            mDebugApp = packageName;
7044            mWaitForDebugger = waitForDebugger;
7045            mDebugTransient = !persistent;
7046            if (packageName != null) {
7047                final long origId = Binder.clearCallingIdentity();
7048                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
7049                Binder.restoreCallingIdentity(origId);
7050            }
7051        }
7052    }
7053
7054    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7055        synchronized (this) {
7056            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7057            if (!isDebuggable) {
7058                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7059                    throw new SecurityException("Process not debuggable: " + app.packageName);
7060                }
7061            }
7062
7063            mOpenGlTraceApp = processName;
7064        }
7065    }
7066
7067    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7068            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7069        synchronized (this) {
7070            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7071            if (!isDebuggable) {
7072                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7073                    throw new SecurityException("Process not debuggable: " + app.packageName);
7074                }
7075            }
7076            mProfileApp = processName;
7077            mProfileFile = profileFile;
7078            if (mProfileFd != null) {
7079                try {
7080                    mProfileFd.close();
7081                } catch (IOException e) {
7082                }
7083                mProfileFd = null;
7084            }
7085            mProfileFd = profileFd;
7086            mProfileType = 0;
7087            mAutoStopProfiler = autoStopProfiler;
7088        }
7089    }
7090
7091    public void setAlwaysFinish(boolean enabled) {
7092        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7093                "setAlwaysFinish()");
7094
7095        Settings.System.putInt(
7096                mContext.getContentResolver(),
7097                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7098
7099        synchronized (this) {
7100            mAlwaysFinishActivities = enabled;
7101        }
7102    }
7103
7104    public void setActivityController(IActivityController controller) {
7105        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7106                "setActivityController()");
7107        synchronized (this) {
7108            mController = controller;
7109        }
7110    }
7111
7112    public boolean isUserAMonkey() {
7113        // For now the fact that there is a controller implies
7114        // we have a monkey.
7115        synchronized (this) {
7116            return mController != null;
7117        }
7118    }
7119
7120    public void registerProcessObserver(IProcessObserver observer) {
7121        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7122                "registerProcessObserver()");
7123        synchronized (this) {
7124            mProcessObservers.register(observer);
7125        }
7126    }
7127
7128    public void unregisterProcessObserver(IProcessObserver observer) {
7129        synchronized (this) {
7130            mProcessObservers.unregister(observer);
7131        }
7132    }
7133
7134    public void setImmersive(IBinder token, boolean immersive) {
7135        synchronized(this) {
7136            ActivityRecord r = mMainStack.isInStackLocked(token);
7137            if (r == null) {
7138                throw new IllegalArgumentException();
7139            }
7140            r.immersive = immersive;
7141        }
7142    }
7143
7144    public boolean isImmersive(IBinder token) {
7145        synchronized (this) {
7146            ActivityRecord r = mMainStack.isInStackLocked(token);
7147            if (r == null) {
7148                throw new IllegalArgumentException();
7149            }
7150            return r.immersive;
7151        }
7152    }
7153
7154    public boolean isTopActivityImmersive() {
7155        enforceNotIsolatedCaller("startActivity");
7156        synchronized (this) {
7157            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7158            return (r != null) ? r.immersive : false;
7159        }
7160    }
7161
7162    public final void enterSafeMode() {
7163        synchronized(this) {
7164            // It only makes sense to do this before the system is ready
7165            // and started launching other packages.
7166            if (!mSystemReady) {
7167                try {
7168                    AppGlobals.getPackageManager().enterSafeMode();
7169                } catch (RemoteException e) {
7170                }
7171            }
7172        }
7173    }
7174
7175    public final void showSafeModeOverlay() {
7176        View v = LayoutInflater.from(mContext).inflate(
7177                com.android.internal.R.layout.safe_mode, null);
7178        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7179        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7180        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7181        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7182        lp.gravity = Gravity.BOTTOM | Gravity.START;
7183        lp.format = v.getBackground().getOpacity();
7184        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7185                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7186        ((WindowManager)mContext.getSystemService(
7187                Context.WINDOW_SERVICE)).addView(v, lp);
7188    }
7189
7190    public void noteWakeupAlarm(IIntentSender sender) {
7191        if (!(sender instanceof PendingIntentRecord)) {
7192            return;
7193        }
7194        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7195        synchronized (stats) {
7196            if (mBatteryStatsService.isOnBattery()) {
7197                mBatteryStatsService.enforceCallingPermission();
7198                PendingIntentRecord rec = (PendingIntentRecord)sender;
7199                int MY_UID = Binder.getCallingUid();
7200                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7201                BatteryStatsImpl.Uid.Pkg pkg =
7202                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7203                pkg.incWakeupsLocked();
7204            }
7205        }
7206    }
7207
7208    public boolean killPids(int[] pids, String pReason, boolean secure) {
7209        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7210            throw new SecurityException("killPids only available to the system");
7211        }
7212        String reason = (pReason == null) ? "Unknown" : pReason;
7213        // XXX Note: don't acquire main activity lock here, because the window
7214        // manager calls in with its locks held.
7215
7216        boolean killed = false;
7217        synchronized (mPidsSelfLocked) {
7218            int[] types = new int[pids.length];
7219            int worstType = 0;
7220            for (int i=0; i<pids.length; i++) {
7221                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7222                if (proc != null) {
7223                    int type = proc.setAdj;
7224                    types[i] = type;
7225                    if (type > worstType) {
7226                        worstType = type;
7227                    }
7228                }
7229            }
7230
7231            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7232            // then constrain it so we will kill all hidden procs.
7233            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7234                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7235                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7236            }
7237
7238            // If this is not a secure call, don't let it kill processes that
7239            // are important.
7240            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7241                worstType = ProcessList.SERVICE_ADJ;
7242            }
7243
7244            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7245            for (int i=0; i<pids.length; i++) {
7246                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7247                if (proc == null) {
7248                    continue;
7249                }
7250                int adj = proc.setAdj;
7251                if (adj >= worstType && !proc.killedBackground) {
7252                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7253                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7254                            proc.processName, adj, reason);
7255                    killed = true;
7256                    proc.killedBackground = true;
7257                    Process.killProcessQuiet(pids[i]);
7258                }
7259            }
7260        }
7261        return killed;
7262    }
7263
7264    @Override
7265    public boolean killProcessesBelowForeground(String reason) {
7266        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7267            throw new SecurityException("killProcessesBelowForeground() only available to system");
7268        }
7269
7270        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7271    }
7272
7273    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7274        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7275            throw new SecurityException("killProcessesBelowAdj() only available to system");
7276        }
7277
7278        boolean killed = false;
7279        synchronized (mPidsSelfLocked) {
7280            final int size = mPidsSelfLocked.size();
7281            for (int i = 0; i < size; i++) {
7282                final int pid = mPidsSelfLocked.keyAt(i);
7283                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7284                if (proc == null) continue;
7285
7286                final int adj = proc.setAdj;
7287                if (adj > belowAdj && !proc.killedBackground) {
7288                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7289                    EventLog.writeEvent(
7290                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7291                    killed = true;
7292                    proc.killedBackground = true;
7293                    Process.killProcessQuiet(pid);
7294                }
7295            }
7296        }
7297        return killed;
7298    }
7299
7300    public final void startRunning(String pkg, String cls, String action,
7301            String data) {
7302        synchronized(this) {
7303            if (mStartRunning) {
7304                return;
7305            }
7306            mStartRunning = true;
7307            mTopComponent = pkg != null && cls != null
7308                    ? new ComponentName(pkg, cls) : null;
7309            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7310            mTopData = data;
7311            if (!mSystemReady) {
7312                return;
7313            }
7314        }
7315
7316        systemReady(null);
7317    }
7318
7319    private void retrieveSettings() {
7320        final ContentResolver resolver = mContext.getContentResolver();
7321        String debugApp = Settings.System.getString(
7322            resolver, Settings.System.DEBUG_APP);
7323        boolean waitForDebugger = Settings.System.getInt(
7324            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7325        boolean alwaysFinishActivities = Settings.System.getInt(
7326            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7327
7328        Configuration configuration = new Configuration();
7329        Settings.System.getConfiguration(resolver, configuration);
7330
7331        synchronized (this) {
7332            mDebugApp = mOrigDebugApp = debugApp;
7333            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7334            mAlwaysFinishActivities = alwaysFinishActivities;
7335            // This happens before any activities are started, so we can
7336            // change mConfiguration in-place.
7337            updateConfigurationLocked(configuration, null, false, true);
7338            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7339        }
7340    }
7341
7342    public boolean testIsSystemReady() {
7343        // no need to synchronize(this) just to read & return the value
7344        return mSystemReady;
7345    }
7346
7347    private static File getCalledPreBootReceiversFile() {
7348        File dataDir = Environment.getDataDirectory();
7349        File systemDir = new File(dataDir, "system");
7350        File fname = new File(systemDir, "called_pre_boots.dat");
7351        return fname;
7352    }
7353
7354    static final int LAST_DONE_VERSION = 10000;
7355
7356    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7357        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7358        File file = getCalledPreBootReceiversFile();
7359        FileInputStream fis = null;
7360        try {
7361            fis = new FileInputStream(file);
7362            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7363            int fvers = dis.readInt();
7364            if (fvers == LAST_DONE_VERSION) {
7365                String vers = dis.readUTF();
7366                String codename = dis.readUTF();
7367                String build = dis.readUTF();
7368                if (android.os.Build.VERSION.RELEASE.equals(vers)
7369                        && android.os.Build.VERSION.CODENAME.equals(codename)
7370                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7371                    int num = dis.readInt();
7372                    while (num > 0) {
7373                        num--;
7374                        String pkg = dis.readUTF();
7375                        String cls = dis.readUTF();
7376                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7377                    }
7378                }
7379            }
7380        } catch (FileNotFoundException e) {
7381        } catch (IOException e) {
7382            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7383        } finally {
7384            if (fis != null) {
7385                try {
7386                    fis.close();
7387                } catch (IOException e) {
7388                }
7389            }
7390        }
7391        return lastDoneReceivers;
7392    }
7393
7394    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7395        File file = getCalledPreBootReceiversFile();
7396        FileOutputStream fos = null;
7397        DataOutputStream dos = null;
7398        try {
7399            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7400            fos = new FileOutputStream(file);
7401            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7402            dos.writeInt(LAST_DONE_VERSION);
7403            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7404            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7405            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7406            dos.writeInt(list.size());
7407            for (int i=0; i<list.size(); i++) {
7408                dos.writeUTF(list.get(i).getPackageName());
7409                dos.writeUTF(list.get(i).getClassName());
7410            }
7411        } catch (IOException e) {
7412            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7413            file.delete();
7414        } finally {
7415            FileUtils.sync(fos);
7416            if (dos != null) {
7417                try {
7418                    dos.close();
7419                } catch (IOException e) {
7420                    // TODO Auto-generated catch block
7421                    e.printStackTrace();
7422                }
7423            }
7424        }
7425    }
7426
7427    public void systemReady(final Runnable goingCallback) {
7428        synchronized(this) {
7429            if (mSystemReady) {
7430                if (goingCallback != null) goingCallback.run();
7431                return;
7432            }
7433
7434            // Check to see if there are any update receivers to run.
7435            if (!mDidUpdate) {
7436                if (mWaitingUpdate) {
7437                    return;
7438                }
7439                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7440                List<ResolveInfo> ris = null;
7441                try {
7442                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7443                            intent, null, 0, 0);
7444                } catch (RemoteException e) {
7445                }
7446                if (ris != null) {
7447                    for (int i=ris.size()-1; i>=0; i--) {
7448                        if ((ris.get(i).activityInfo.applicationInfo.flags
7449                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7450                            ris.remove(i);
7451                        }
7452                    }
7453                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7454
7455                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7456
7457                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7458                    for (int i=0; i<ris.size(); i++) {
7459                        ActivityInfo ai = ris.get(i).activityInfo;
7460                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7461                        if (lastDoneReceivers.contains(comp)) {
7462                            ris.remove(i);
7463                            i--;
7464                        }
7465                    }
7466
7467                    for (int i=0; i<ris.size(); i++) {
7468                        ActivityInfo ai = ris.get(i).activityInfo;
7469                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7470                        doneReceivers.add(comp);
7471                        intent.setComponent(comp);
7472                        IIntentReceiver finisher = null;
7473                        if (i == ris.size()-1) {
7474                            finisher = new IIntentReceiver.Stub() {
7475                                public void performReceive(Intent intent, int resultCode,
7476                                        String data, Bundle extras, boolean ordered,
7477                                        boolean sticky) {
7478                                    // The raw IIntentReceiver interface is called
7479                                    // with the AM lock held, so redispatch to
7480                                    // execute our code without the lock.
7481                                    mHandler.post(new Runnable() {
7482                                        public void run() {
7483                                            synchronized (ActivityManagerService.this) {
7484                                                mDidUpdate = true;
7485                                            }
7486                                            writeLastDonePreBootReceivers(doneReceivers);
7487                                            showBootMessage(mContext.getText(
7488                                                    R.string.android_upgrading_complete),
7489                                                    false);
7490                                            systemReady(goingCallback);
7491                                        }
7492                                    });
7493                                }
7494                            };
7495                        }
7496                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7497                        /* TODO: Send this to all users */
7498                        broadcastIntentLocked(null, null, intent, null, finisher,
7499                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7500                                0 /* UserId zero */);
7501                        if (finisher != null) {
7502                            mWaitingUpdate = true;
7503                        }
7504                    }
7505                }
7506                if (mWaitingUpdate) {
7507                    return;
7508                }
7509                mDidUpdate = true;
7510            }
7511
7512            mSystemReady = true;
7513            if (!mStartRunning) {
7514                return;
7515            }
7516        }
7517
7518        ArrayList<ProcessRecord> procsToKill = null;
7519        synchronized(mPidsSelfLocked) {
7520            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7521                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7522                if (!isAllowedWhileBooting(proc.info)){
7523                    if (procsToKill == null) {
7524                        procsToKill = new ArrayList<ProcessRecord>();
7525                    }
7526                    procsToKill.add(proc);
7527                }
7528            }
7529        }
7530
7531        synchronized(this) {
7532            if (procsToKill != null) {
7533                for (int i=procsToKill.size()-1; i>=0; i--) {
7534                    ProcessRecord proc = procsToKill.get(i);
7535                    Slog.i(TAG, "Removing system update proc: " + proc);
7536                    removeProcessLocked(proc, true, false, "system update done");
7537                }
7538            }
7539
7540            // Now that we have cleaned up any update processes, we
7541            // are ready to start launching real processes and know that
7542            // we won't trample on them any more.
7543            mProcessesReady = true;
7544        }
7545
7546        Slog.i(TAG, "System now ready");
7547        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7548            SystemClock.uptimeMillis());
7549
7550        synchronized(this) {
7551            // Make sure we have no pre-ready processes sitting around.
7552
7553            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7554                ResolveInfo ri = mContext.getPackageManager()
7555                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7556                                STOCK_PM_FLAGS);
7557                CharSequence errorMsg = null;
7558                if (ri != null) {
7559                    ActivityInfo ai = ri.activityInfo;
7560                    ApplicationInfo app = ai.applicationInfo;
7561                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7562                        mTopAction = Intent.ACTION_FACTORY_TEST;
7563                        mTopData = null;
7564                        mTopComponent = new ComponentName(app.packageName,
7565                                ai.name);
7566                    } else {
7567                        errorMsg = mContext.getResources().getText(
7568                                com.android.internal.R.string.factorytest_not_system);
7569                    }
7570                } else {
7571                    errorMsg = mContext.getResources().getText(
7572                            com.android.internal.R.string.factorytest_no_action);
7573                }
7574                if (errorMsg != null) {
7575                    mTopAction = null;
7576                    mTopData = null;
7577                    mTopComponent = null;
7578                    Message msg = Message.obtain();
7579                    msg.what = SHOW_FACTORY_ERROR_MSG;
7580                    msg.getData().putCharSequence("msg", errorMsg);
7581                    mHandler.sendMessage(msg);
7582                }
7583            }
7584        }
7585
7586        retrieveSettings();
7587
7588        if (goingCallback != null) goingCallback.run();
7589
7590        synchronized (this) {
7591            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7592                try {
7593                    List apps = AppGlobals.getPackageManager().
7594                        getPersistentApplications(STOCK_PM_FLAGS);
7595                    if (apps != null) {
7596                        int N = apps.size();
7597                        int i;
7598                        for (i=0; i<N; i++) {
7599                            ApplicationInfo info
7600                                = (ApplicationInfo)apps.get(i);
7601                            if (info != null &&
7602                                    !info.packageName.equals("android")) {
7603                                addAppLocked(info, false);
7604                            }
7605                        }
7606                    }
7607                } catch (RemoteException ex) {
7608                    // pm is in same process, this will never happen.
7609                }
7610            }
7611
7612            // Start up initial activity.
7613            mBooting = true;
7614
7615            try {
7616                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7617                    Message msg = Message.obtain();
7618                    msg.what = SHOW_UID_ERROR_MSG;
7619                    mHandler.sendMessage(msg);
7620                }
7621            } catch (RemoteException e) {
7622            }
7623
7624            mMainStack.resumeTopActivityLocked(null);
7625        }
7626    }
7627
7628    private boolean makeAppCrashingLocked(ProcessRecord app,
7629            String shortMsg, String longMsg, String stackTrace) {
7630        app.crashing = true;
7631        app.crashingReport = generateProcessError(app,
7632                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7633        startAppProblemLocked(app);
7634        app.stopFreezingAllLocked();
7635        return handleAppCrashLocked(app);
7636    }
7637
7638    private void makeAppNotRespondingLocked(ProcessRecord app,
7639            String activity, String shortMsg, String longMsg) {
7640        app.notResponding = true;
7641        app.notRespondingReport = generateProcessError(app,
7642                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7643                activity, shortMsg, longMsg, null);
7644        startAppProblemLocked(app);
7645        app.stopFreezingAllLocked();
7646    }
7647
7648    /**
7649     * Generate a process error record, suitable for attachment to a ProcessRecord.
7650     *
7651     * @param app The ProcessRecord in which the error occurred.
7652     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7653     *                      ActivityManager.AppErrorStateInfo
7654     * @param activity The activity associated with the crash, if known.
7655     * @param shortMsg Short message describing the crash.
7656     * @param longMsg Long message describing the crash.
7657     * @param stackTrace Full crash stack trace, may be null.
7658     *
7659     * @return Returns a fully-formed AppErrorStateInfo record.
7660     */
7661    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7662            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7663        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7664
7665        report.condition = condition;
7666        report.processName = app.processName;
7667        report.pid = app.pid;
7668        report.uid = app.info.uid;
7669        report.tag = activity;
7670        report.shortMsg = shortMsg;
7671        report.longMsg = longMsg;
7672        report.stackTrace = stackTrace;
7673
7674        return report;
7675    }
7676
7677    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7678        synchronized (this) {
7679            app.crashing = false;
7680            app.crashingReport = null;
7681            app.notResponding = false;
7682            app.notRespondingReport = null;
7683            if (app.anrDialog == fromDialog) {
7684                app.anrDialog = null;
7685            }
7686            if (app.waitDialog == fromDialog) {
7687                app.waitDialog = null;
7688            }
7689            if (app.pid > 0 && app.pid != MY_PID) {
7690                handleAppCrashLocked(app);
7691                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7692                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7693                        app.processName, app.setAdj, "user's request after error");
7694                Process.killProcessQuiet(app.pid);
7695            }
7696        }
7697    }
7698
7699    private boolean handleAppCrashLocked(ProcessRecord app) {
7700        if (mHeadless) {
7701            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7702            return false;
7703        }
7704        long now = SystemClock.uptimeMillis();
7705
7706        Long crashTime;
7707        if (!app.isolated) {
7708            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7709        } else {
7710            crashTime = null;
7711        }
7712        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7713            // This process loses!
7714            Slog.w(TAG, "Process " + app.info.processName
7715                    + " has crashed too many times: killing!");
7716            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7717                    app.info.processName, app.uid);
7718            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7719                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7720                if (r.app == app) {
7721                    Slog.w(TAG, "  Force finishing activity "
7722                        + r.intent.getComponent().flattenToShortString());
7723                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7724                }
7725            }
7726            if (!app.persistent) {
7727                // We don't want to start this process again until the user
7728                // explicitly does so...  but for persistent process, we really
7729                // need to keep it running.  If a persistent process is actually
7730                // repeatedly crashing, then badness for everyone.
7731                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7732                        app.info.processName);
7733                if (!app.isolated) {
7734                    // XXX We don't have a way to mark isolated processes
7735                    // as bad, since they don't have a peristent identity.
7736                    mBadProcesses.put(app.info.processName, app.uid, now);
7737                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7738                }
7739                app.bad = true;
7740                app.removed = true;
7741                // Don't let services in this process be restarted and potentially
7742                // annoy the user repeatedly.  Unless it is persistent, since those
7743                // processes run critical code.
7744                removeProcessLocked(app, false, false, "crash");
7745                mMainStack.resumeTopActivityLocked(null);
7746                return false;
7747            }
7748            mMainStack.resumeTopActivityLocked(null);
7749        } else {
7750            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7751            if (r != null && r.app == app) {
7752                // If the top running activity is from this crashing
7753                // process, then terminate it to avoid getting in a loop.
7754                Slog.w(TAG, "  Force finishing activity "
7755                        + r.intent.getComponent().flattenToShortString());
7756                int index = mMainStack.indexOfActivityLocked(r);
7757                r.stack.finishActivityLocked(r, index,
7758                        Activity.RESULT_CANCELED, null, "crashed");
7759                // Also terminate any activities below it that aren't yet
7760                // stopped, to avoid a situation where one will get
7761                // re-start our crashing activity once it gets resumed again.
7762                index--;
7763                if (index >= 0) {
7764                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7765                    if (r.state == ActivityState.RESUMED
7766                            || r.state == ActivityState.PAUSING
7767                            || r.state == ActivityState.PAUSED) {
7768                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7769                            Slog.w(TAG, "  Force finishing activity "
7770                                    + r.intent.getComponent().flattenToShortString());
7771                            r.stack.finishActivityLocked(r, index,
7772                                    Activity.RESULT_CANCELED, null, "crashed");
7773                        }
7774                    }
7775                }
7776            }
7777        }
7778
7779        // Bump up the crash count of any services currently running in the proc.
7780        if (app.services.size() != 0) {
7781            // Any services running in the application need to be placed
7782            // back in the pending list.
7783            Iterator<ServiceRecord> it = app.services.iterator();
7784            while (it.hasNext()) {
7785                ServiceRecord sr = it.next();
7786                sr.crashCount++;
7787            }
7788        }
7789
7790        // If the crashing process is what we consider to be the "home process" and it has been
7791        // replaced by a third-party app, clear the package preferred activities from packages
7792        // with a home activity running in the process to prevent a repeatedly crashing app
7793        // from blocking the user to manually clear the list.
7794        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7795                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7796            Iterator it = mHomeProcess.activities.iterator();
7797            while (it.hasNext()) {
7798                ActivityRecord r = (ActivityRecord)it.next();
7799                if (r.isHomeActivity) {
7800                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7801                    try {
7802                        ActivityThread.getPackageManager()
7803                                .clearPackagePreferredActivities(r.packageName);
7804                    } catch (RemoteException c) {
7805                        // pm is in same process, this will never happen.
7806                    }
7807                }
7808            }
7809        }
7810
7811        if (!app.isolated) {
7812            // XXX Can't keep track of crash times for isolated processes,
7813            // because they don't have a perisistent identity.
7814            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7815        }
7816
7817        return true;
7818    }
7819
7820    void startAppProblemLocked(ProcessRecord app) {
7821        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7822                mContext, app.info.packageName, app.info.flags);
7823        skipCurrentReceiverLocked(app);
7824    }
7825
7826    void skipCurrentReceiverLocked(ProcessRecord app) {
7827        for (BroadcastQueue queue : mBroadcastQueues) {
7828            queue.skipCurrentReceiverLocked(app);
7829        }
7830    }
7831
7832    /**
7833     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7834     * The application process will exit immediately after this call returns.
7835     * @param app object of the crashing app, null for the system server
7836     * @param crashInfo describing the exception
7837     */
7838    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7839        ProcessRecord r = findAppProcess(app, "Crash");
7840        final String processName = app == null ? "system_server"
7841                : (r == null ? "unknown" : r.processName);
7842
7843        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7844                processName,
7845                r == null ? -1 : r.info.flags,
7846                crashInfo.exceptionClassName,
7847                crashInfo.exceptionMessage,
7848                crashInfo.throwFileName,
7849                crashInfo.throwLineNumber);
7850
7851        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7852
7853        crashApplication(r, crashInfo);
7854    }
7855
7856    public void handleApplicationStrictModeViolation(
7857            IBinder app,
7858            int violationMask,
7859            StrictMode.ViolationInfo info) {
7860        ProcessRecord r = findAppProcess(app, "StrictMode");
7861        if (r == null) {
7862            return;
7863        }
7864
7865        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7866            Integer stackFingerprint = info.hashCode();
7867            boolean logIt = true;
7868            synchronized (mAlreadyLoggedViolatedStacks) {
7869                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7870                    logIt = false;
7871                    // TODO: sub-sample into EventLog for these, with
7872                    // the info.durationMillis?  Then we'd get
7873                    // the relative pain numbers, without logging all
7874                    // the stack traces repeatedly.  We'd want to do
7875                    // likewise in the client code, which also does
7876                    // dup suppression, before the Binder call.
7877                } else {
7878                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7879                        mAlreadyLoggedViolatedStacks.clear();
7880                    }
7881                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7882                }
7883            }
7884            if (logIt) {
7885                logStrictModeViolationToDropBox(r, info);
7886            }
7887        }
7888
7889        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7890            AppErrorResult result = new AppErrorResult();
7891            synchronized (this) {
7892                final long origId = Binder.clearCallingIdentity();
7893
7894                Message msg = Message.obtain();
7895                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7896                HashMap<String, Object> data = new HashMap<String, Object>();
7897                data.put("result", result);
7898                data.put("app", r);
7899                data.put("violationMask", violationMask);
7900                data.put("info", info);
7901                msg.obj = data;
7902                mHandler.sendMessage(msg);
7903
7904                Binder.restoreCallingIdentity(origId);
7905            }
7906            int res = result.get();
7907            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7908        }
7909    }
7910
7911    // Depending on the policy in effect, there could be a bunch of
7912    // these in quick succession so we try to batch these together to
7913    // minimize disk writes, number of dropbox entries, and maximize
7914    // compression, by having more fewer, larger records.
7915    private void logStrictModeViolationToDropBox(
7916            ProcessRecord process,
7917            StrictMode.ViolationInfo info) {
7918        if (info == null) {
7919            return;
7920        }
7921        final boolean isSystemApp = process == null ||
7922                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7923                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7924        final String processName = process == null ? "unknown" : process.processName;
7925        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7926        final DropBoxManager dbox = (DropBoxManager)
7927                mContext.getSystemService(Context.DROPBOX_SERVICE);
7928
7929        // Exit early if the dropbox isn't configured to accept this report type.
7930        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7931
7932        boolean bufferWasEmpty;
7933        boolean needsFlush;
7934        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7935        synchronized (sb) {
7936            bufferWasEmpty = sb.length() == 0;
7937            appendDropBoxProcessHeaders(process, processName, sb);
7938            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7939            sb.append("System-App: ").append(isSystemApp).append("\n");
7940            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7941            if (info.violationNumThisLoop != 0) {
7942                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7943            }
7944            if (info.numAnimationsRunning != 0) {
7945                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7946            }
7947            if (info.broadcastIntentAction != null) {
7948                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7949            }
7950            if (info.durationMillis != -1) {
7951                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
7952            }
7953            if (info.numInstances != -1) {
7954                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7955            }
7956            if (info.tags != null) {
7957                for (String tag : info.tags) {
7958                    sb.append("Span-Tag: ").append(tag).append("\n");
7959                }
7960            }
7961            sb.append("\n");
7962            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7963                sb.append(info.crashInfo.stackTrace);
7964            }
7965            sb.append("\n");
7966
7967            // Only buffer up to ~64k.  Various logging bits truncate
7968            // things at 128k.
7969            needsFlush = (sb.length() > 64 * 1024);
7970        }
7971
7972        // Flush immediately if the buffer's grown too large, or this
7973        // is a non-system app.  Non-system apps are isolated with a
7974        // different tag & policy and not batched.
7975        //
7976        // Batching is useful during internal testing with
7977        // StrictMode settings turned up high.  Without batching,
7978        // thousands of separate files could be created on boot.
7979        if (!isSystemApp || needsFlush) {
7980            new Thread("Error dump: " + dropboxTag) {
7981                @Override
7982                public void run() {
7983                    String report;
7984                    synchronized (sb) {
7985                        report = sb.toString();
7986                        sb.delete(0, sb.length());
7987                        sb.trimToSize();
7988                    }
7989                    if (report.length() != 0) {
7990                        dbox.addText(dropboxTag, report);
7991                    }
7992                }
7993            }.start();
7994            return;
7995        }
7996
7997        // System app batching:
7998        if (!bufferWasEmpty) {
7999            // An existing dropbox-writing thread is outstanding, so
8000            // we don't need to start it up.  The existing thread will
8001            // catch the buffer appends we just did.
8002            return;
8003        }
8004
8005        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8006        // (After this point, we shouldn't access AMS internal data structures.)
8007        new Thread("Error dump: " + dropboxTag) {
8008            @Override
8009            public void run() {
8010                // 5 second sleep to let stacks arrive and be batched together
8011                try {
8012                    Thread.sleep(5000);  // 5 seconds
8013                } catch (InterruptedException e) {}
8014
8015                String errorReport;
8016                synchronized (mStrictModeBuffer) {
8017                    errorReport = mStrictModeBuffer.toString();
8018                    if (errorReport.length() == 0) {
8019                        return;
8020                    }
8021                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8022                    mStrictModeBuffer.trimToSize();
8023                }
8024                dbox.addText(dropboxTag, errorReport);
8025            }
8026        }.start();
8027    }
8028
8029    /**
8030     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8031     * @param app object of the crashing app, null for the system server
8032     * @param tag reported by the caller
8033     * @param crashInfo describing the context of the error
8034     * @return true if the process should exit immediately (WTF is fatal)
8035     */
8036    public boolean handleApplicationWtf(IBinder app, String tag,
8037            ApplicationErrorReport.CrashInfo crashInfo) {
8038        ProcessRecord r = findAppProcess(app, "WTF");
8039        final String processName = app == null ? "system_server"
8040                : (r == null ? "unknown" : r.processName);
8041
8042        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8043                processName,
8044                r == null ? -1 : r.info.flags,
8045                tag, crashInfo.exceptionMessage);
8046
8047        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8048
8049        if (r != null && r.pid != Process.myPid() &&
8050                Settings.Secure.getInt(mContext.getContentResolver(),
8051                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8052            crashApplication(r, crashInfo);
8053            return true;
8054        } else {
8055            return false;
8056        }
8057    }
8058
8059    /**
8060     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8061     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8062     */
8063    private ProcessRecord findAppProcess(IBinder app, String reason) {
8064        if (app == null) {
8065            return null;
8066        }
8067
8068        synchronized (this) {
8069            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8070                final int NA = apps.size();
8071                for (int ia=0; ia<NA; ia++) {
8072                    ProcessRecord p = apps.valueAt(ia);
8073                    if (p.thread != null && p.thread.asBinder() == app) {
8074                        return p;
8075                    }
8076                }
8077            }
8078
8079            Slog.w(TAG, "Can't find mystery application for " + reason
8080                    + " from pid=" + Binder.getCallingPid()
8081                    + " uid=" + Binder.getCallingUid() + ": " + app);
8082            return null;
8083        }
8084    }
8085
8086    /**
8087     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8088     * to append various headers to the dropbox log text.
8089     */
8090    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8091            StringBuilder sb) {
8092        // Watchdog thread ends up invoking this function (with
8093        // a null ProcessRecord) to add the stack file to dropbox.
8094        // Do not acquire a lock on this (am) in such cases, as it
8095        // could cause a potential deadlock, if and when watchdog
8096        // is invoked due to unavailability of lock on am and it
8097        // would prevent watchdog from killing system_server.
8098        if (process == null) {
8099            sb.append("Process: ").append(processName).append("\n");
8100            return;
8101        }
8102        // Note: ProcessRecord 'process' is guarded by the service
8103        // instance.  (notably process.pkgList, which could otherwise change
8104        // concurrently during execution of this method)
8105        synchronized (this) {
8106            sb.append("Process: ").append(processName).append("\n");
8107            int flags = process.info.flags;
8108            IPackageManager pm = AppGlobals.getPackageManager();
8109            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8110            for (String pkg : process.pkgList) {
8111                sb.append("Package: ").append(pkg);
8112                try {
8113                    PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
8114                    if (pi != null) {
8115                        sb.append(" v").append(pi.versionCode);
8116                        if (pi.versionName != null) {
8117                            sb.append(" (").append(pi.versionName).append(")");
8118                        }
8119                    }
8120                } catch (RemoteException e) {
8121                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8122                }
8123                sb.append("\n");
8124            }
8125        }
8126    }
8127
8128    private static String processClass(ProcessRecord process) {
8129        if (process == null || process.pid == MY_PID) {
8130            return "system_server";
8131        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8132            return "system_app";
8133        } else {
8134            return "data_app";
8135        }
8136    }
8137
8138    /**
8139     * Write a description of an error (crash, WTF, ANR) to the drop box.
8140     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8141     * @param process which caused the error, null means the system server
8142     * @param activity which triggered the error, null if unknown
8143     * @param parent activity related to the error, null if unknown
8144     * @param subject line related to the error, null if absent
8145     * @param report in long form describing the error, null if absent
8146     * @param logFile to include in the report, null if none
8147     * @param crashInfo giving an application stack trace, null if absent
8148     */
8149    public void addErrorToDropBox(String eventType,
8150            ProcessRecord process, String processName, ActivityRecord activity,
8151            ActivityRecord parent, String subject,
8152            final String report, final File logFile,
8153            final ApplicationErrorReport.CrashInfo crashInfo) {
8154        // NOTE -- this must never acquire the ActivityManagerService lock,
8155        // otherwise the watchdog may be prevented from resetting the system.
8156
8157        final String dropboxTag = processClass(process) + "_" + eventType;
8158        final DropBoxManager dbox = (DropBoxManager)
8159                mContext.getSystemService(Context.DROPBOX_SERVICE);
8160
8161        // Exit early if the dropbox isn't configured to accept this report type.
8162        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8163
8164        final StringBuilder sb = new StringBuilder(1024);
8165        appendDropBoxProcessHeaders(process, processName, sb);
8166        if (activity != null) {
8167            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8168        }
8169        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8170            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8171        }
8172        if (parent != null && parent != activity) {
8173            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8174        }
8175        if (subject != null) {
8176            sb.append("Subject: ").append(subject).append("\n");
8177        }
8178        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8179        if (Debug.isDebuggerConnected()) {
8180            sb.append("Debugger: Connected\n");
8181        }
8182        sb.append("\n");
8183
8184        // Do the rest in a worker thread to avoid blocking the caller on I/O
8185        // (After this point, we shouldn't access AMS internal data structures.)
8186        Thread worker = new Thread("Error dump: " + dropboxTag) {
8187            @Override
8188            public void run() {
8189                if (report != null) {
8190                    sb.append(report);
8191                }
8192                if (logFile != null) {
8193                    try {
8194                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8195                    } catch (IOException e) {
8196                        Slog.e(TAG, "Error reading " + logFile, e);
8197                    }
8198                }
8199                if (crashInfo != null && crashInfo.stackTrace != null) {
8200                    sb.append(crashInfo.stackTrace);
8201                }
8202
8203                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8204                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8205                if (lines > 0) {
8206                    sb.append("\n");
8207
8208                    // Merge several logcat streams, and take the last N lines
8209                    InputStreamReader input = null;
8210                    try {
8211                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8212                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8213                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8214
8215                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8216                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8217                        input = new InputStreamReader(logcat.getInputStream());
8218
8219                        int num;
8220                        char[] buf = new char[8192];
8221                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8222                    } catch (IOException e) {
8223                        Slog.e(TAG, "Error running logcat", e);
8224                    } finally {
8225                        if (input != null) try { input.close(); } catch (IOException e) {}
8226                    }
8227                }
8228
8229                dbox.addText(dropboxTag, sb.toString());
8230            }
8231        };
8232
8233        if (process == null) {
8234            // If process is null, we are being called from some internal code
8235            // and may be about to die -- run this synchronously.
8236            worker.run();
8237        } else {
8238            worker.start();
8239        }
8240    }
8241
8242    /**
8243     * Bring up the "unexpected error" dialog box for a crashing app.
8244     * Deal with edge cases (intercepts from instrumented applications,
8245     * ActivityController, error intent receivers, that sort of thing).
8246     * @param r the application crashing
8247     * @param crashInfo describing the failure
8248     */
8249    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8250        long timeMillis = System.currentTimeMillis();
8251        String shortMsg = crashInfo.exceptionClassName;
8252        String longMsg = crashInfo.exceptionMessage;
8253        String stackTrace = crashInfo.stackTrace;
8254        if (shortMsg != null && longMsg != null) {
8255            longMsg = shortMsg + ": " + longMsg;
8256        } else if (shortMsg != null) {
8257            longMsg = shortMsg;
8258        }
8259
8260        AppErrorResult result = new AppErrorResult();
8261        synchronized (this) {
8262            if (mController != null) {
8263                try {
8264                    String name = r != null ? r.processName : null;
8265                    int pid = r != null ? r.pid : Binder.getCallingPid();
8266                    if (!mController.appCrashed(name, pid,
8267                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8268                        Slog.w(TAG, "Force-killing crashed app " + name
8269                                + " at watcher's request");
8270                        Process.killProcess(pid);
8271                        return;
8272                    }
8273                } catch (RemoteException e) {
8274                    mController = null;
8275                }
8276            }
8277
8278            final long origId = Binder.clearCallingIdentity();
8279
8280            // If this process is running instrumentation, finish it.
8281            if (r != null && r.instrumentationClass != null) {
8282                Slog.w(TAG, "Error in app " + r.processName
8283                      + " running instrumentation " + r.instrumentationClass + ":");
8284                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8285                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8286                Bundle info = new Bundle();
8287                info.putString("shortMsg", shortMsg);
8288                info.putString("longMsg", longMsg);
8289                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8290                Binder.restoreCallingIdentity(origId);
8291                return;
8292            }
8293
8294            // If we can't identify the process or it's already exceeded its crash quota,
8295            // quit right away without showing a crash dialog.
8296            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8297                Binder.restoreCallingIdentity(origId);
8298                return;
8299            }
8300
8301            Message msg = Message.obtain();
8302            msg.what = SHOW_ERROR_MSG;
8303            HashMap data = new HashMap();
8304            data.put("result", result);
8305            data.put("app", r);
8306            msg.obj = data;
8307            mHandler.sendMessage(msg);
8308
8309            Binder.restoreCallingIdentity(origId);
8310        }
8311
8312        int res = result.get();
8313
8314        Intent appErrorIntent = null;
8315        synchronized (this) {
8316            if (r != null && !r.isolated) {
8317                // XXX Can't keep track of crash time for isolated processes,
8318                // since they don't have a persistent identity.
8319                mProcessCrashTimes.put(r.info.processName, r.uid,
8320                        SystemClock.uptimeMillis());
8321            }
8322            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8323                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8324            }
8325        }
8326
8327        if (appErrorIntent != null) {
8328            try {
8329                mContext.startActivity(appErrorIntent);
8330            } catch (ActivityNotFoundException e) {
8331                Slog.w(TAG, "bug report receiver dissappeared", e);
8332            }
8333        }
8334    }
8335
8336    Intent createAppErrorIntentLocked(ProcessRecord r,
8337            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8338        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8339        if (report == null) {
8340            return null;
8341        }
8342        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8343        result.setComponent(r.errorReportReceiver);
8344        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8345        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8346        return result;
8347    }
8348
8349    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8350            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8351        if (r.errorReportReceiver == null) {
8352            return null;
8353        }
8354
8355        if (!r.crashing && !r.notResponding) {
8356            return null;
8357        }
8358
8359        ApplicationErrorReport report = new ApplicationErrorReport();
8360        report.packageName = r.info.packageName;
8361        report.installerPackageName = r.errorReportReceiver.getPackageName();
8362        report.processName = r.processName;
8363        report.time = timeMillis;
8364        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8365
8366        if (r.crashing) {
8367            report.type = ApplicationErrorReport.TYPE_CRASH;
8368            report.crashInfo = crashInfo;
8369        } else if (r.notResponding) {
8370            report.type = ApplicationErrorReport.TYPE_ANR;
8371            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8372
8373            report.anrInfo.activity = r.notRespondingReport.tag;
8374            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8375            report.anrInfo.info = r.notRespondingReport.longMsg;
8376        }
8377
8378        return report;
8379    }
8380
8381    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8382        enforceNotIsolatedCaller("getProcessesInErrorState");
8383        // assume our apps are happy - lazy create the list
8384        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8385
8386        final boolean allUsers = ActivityManager.checkUidPermission(
8387                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8388                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8389        int userId = UserHandle.getUserId(Binder.getCallingUid());
8390
8391        synchronized (this) {
8392
8393            // iterate across all processes
8394            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8395                ProcessRecord app = mLruProcesses.get(i);
8396                if (!allUsers && app.userId != userId) {
8397                    continue;
8398                }
8399                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8400                    // This one's in trouble, so we'll generate a report for it
8401                    // crashes are higher priority (in case there's a crash *and* an anr)
8402                    ActivityManager.ProcessErrorStateInfo report = null;
8403                    if (app.crashing) {
8404                        report = app.crashingReport;
8405                    } else if (app.notResponding) {
8406                        report = app.notRespondingReport;
8407                    }
8408
8409                    if (report != null) {
8410                        if (errList == null) {
8411                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8412                        }
8413                        errList.add(report);
8414                    } else {
8415                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8416                                " crashing = " + app.crashing +
8417                                " notResponding = " + app.notResponding);
8418                    }
8419                }
8420            }
8421        }
8422
8423        return errList;
8424    }
8425
8426    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8427        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8428            if (currApp != null) {
8429                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8430            }
8431            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8432        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8433            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8434        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8435            if (currApp != null) {
8436                currApp.lru = 0;
8437            }
8438            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8439        } else if (adj >= ProcessList.SERVICE_ADJ) {
8440            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8441        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8442            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8443        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8444            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8445        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8446            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8447        } else {
8448            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8449        }
8450    }
8451
8452    private void fillInProcMemInfo(ProcessRecord app,
8453            ActivityManager.RunningAppProcessInfo outInfo) {
8454        outInfo.pid = app.pid;
8455        outInfo.uid = app.info.uid;
8456        if (mHeavyWeightProcess == app) {
8457            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8458        }
8459        if (app.persistent) {
8460            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8461        }
8462        if (app.hasActivities) {
8463            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8464        }
8465        outInfo.lastTrimLevel = app.trimMemoryLevel;
8466        int adj = app.curAdj;
8467        outInfo.importance = oomAdjToImportance(adj, outInfo);
8468        outInfo.importanceReasonCode = app.adjTypeCode;
8469    }
8470
8471    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8472        enforceNotIsolatedCaller("getRunningAppProcesses");
8473        // Lazy instantiation of list
8474        List<ActivityManager.RunningAppProcessInfo> runList = null;
8475        final boolean allUsers = ActivityManager.checkUidPermission(
8476                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8477                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8478        int userId = UserHandle.getUserId(Binder.getCallingUid());
8479        synchronized (this) {
8480            // Iterate across all processes
8481            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8482                ProcessRecord app = mLruProcesses.get(i);
8483                if (!allUsers && app.userId != userId) {
8484                    continue;
8485                }
8486                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8487                    // Generate process state info for running application
8488                    ActivityManager.RunningAppProcessInfo currApp =
8489                        new ActivityManager.RunningAppProcessInfo(app.processName,
8490                                app.pid, app.getPackageList());
8491                    fillInProcMemInfo(app, currApp);
8492                    if (app.adjSource instanceof ProcessRecord) {
8493                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8494                        currApp.importanceReasonImportance = oomAdjToImportance(
8495                                app.adjSourceOom, null);
8496                    } else if (app.adjSource instanceof ActivityRecord) {
8497                        ActivityRecord r = (ActivityRecord)app.adjSource;
8498                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8499                    }
8500                    if (app.adjTarget instanceof ComponentName) {
8501                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8502                    }
8503                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8504                    //        + " lru=" + currApp.lru);
8505                    if (runList == null) {
8506                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8507                    }
8508                    runList.add(currApp);
8509                }
8510            }
8511        }
8512        return runList;
8513    }
8514
8515    public List<ApplicationInfo> getRunningExternalApplications() {
8516        enforceNotIsolatedCaller("getRunningExternalApplications");
8517        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8518        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8519        if (runningApps != null && runningApps.size() > 0) {
8520            Set<String> extList = new HashSet<String>();
8521            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8522                if (app.pkgList != null) {
8523                    for (String pkg : app.pkgList) {
8524                        extList.add(pkg);
8525                    }
8526                }
8527            }
8528            IPackageManager pm = AppGlobals.getPackageManager();
8529            for (String pkg : extList) {
8530                try {
8531                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8532                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8533                        retList.add(info);
8534                    }
8535                } catch (RemoteException e) {
8536                }
8537            }
8538        }
8539        return retList;
8540    }
8541
8542    @Override
8543    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8544        enforceNotIsolatedCaller("getMyMemoryState");
8545        synchronized (this) {
8546            ProcessRecord proc;
8547            synchronized (mPidsSelfLocked) {
8548                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8549            }
8550            fillInProcMemInfo(proc, outInfo);
8551        }
8552    }
8553
8554    @Override
8555    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8556        if (checkCallingPermission(android.Manifest.permission.DUMP)
8557                != PackageManager.PERMISSION_GRANTED) {
8558            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8559                    + Binder.getCallingPid()
8560                    + ", uid=" + Binder.getCallingUid()
8561                    + " without permission "
8562                    + android.Manifest.permission.DUMP);
8563            return;
8564        }
8565
8566        boolean dumpAll = false;
8567        boolean dumpClient = false;
8568        String dumpPackage = null;
8569
8570        int opti = 0;
8571        while (opti < args.length) {
8572            String opt = args[opti];
8573            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8574                break;
8575            }
8576            opti++;
8577            if ("-a".equals(opt)) {
8578                dumpAll = true;
8579            } else if ("-c".equals(opt)) {
8580                dumpClient = true;
8581            } else if ("-h".equals(opt)) {
8582                pw.println("Activity manager dump options:");
8583                pw.println("  [-a] [-c] [-h] [cmd] ...");
8584                pw.println("  cmd may be one of:");
8585                pw.println("    a[ctivities]: activity stack state");
8586                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8587                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8588                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8589                pw.println("    o[om]: out of memory management");
8590                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8591                pw.println("    provider [COMP_SPEC]: provider client-side state");
8592                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8593                pw.println("    service [COMP_SPEC]: service client-side state");
8594                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8595                pw.println("    all: dump all activities");
8596                pw.println("    top: dump the top activity");
8597                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8598                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8599                pw.println("    a partial substring in a component name, a");
8600                pw.println("    hex object identifier.");
8601                pw.println("  -a: include all available server state.");
8602                pw.println("  -c: include client state.");
8603                return;
8604            } else {
8605                pw.println("Unknown argument: " + opt + "; use -h for help");
8606            }
8607        }
8608
8609        long origId = Binder.clearCallingIdentity();
8610        boolean more = false;
8611        // Is the caller requesting to dump a particular piece of data?
8612        if (opti < args.length) {
8613            String cmd = args[opti];
8614            opti++;
8615            if ("activities".equals(cmd) || "a".equals(cmd)) {
8616                synchronized (this) {
8617                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8618                }
8619            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8620                String[] newArgs;
8621                String name;
8622                if (opti >= args.length) {
8623                    name = null;
8624                    newArgs = EMPTY_STRING_ARRAY;
8625                } else {
8626                    name = args[opti];
8627                    opti++;
8628                    newArgs = new String[args.length - opti];
8629                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8630                            args.length - opti);
8631                }
8632                synchronized (this) {
8633                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8634                }
8635            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8636                String[] newArgs;
8637                String name;
8638                if (opti >= args.length) {
8639                    name = null;
8640                    newArgs = EMPTY_STRING_ARRAY;
8641                } else {
8642                    name = args[opti];
8643                    opti++;
8644                    newArgs = new String[args.length - opti];
8645                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8646                            args.length - opti);
8647                }
8648                synchronized (this) {
8649                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8650                }
8651            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8652                String[] newArgs;
8653                String name;
8654                if (opti >= args.length) {
8655                    name = null;
8656                    newArgs = EMPTY_STRING_ARRAY;
8657                } else {
8658                    name = args[opti];
8659                    opti++;
8660                    newArgs = new String[args.length - opti];
8661                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8662                            args.length - opti);
8663                }
8664                synchronized (this) {
8665                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8666                }
8667            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8668                synchronized (this) {
8669                    dumpOomLocked(fd, pw, args, opti, true);
8670                }
8671            } else if ("provider".equals(cmd)) {
8672                String[] newArgs;
8673                String name;
8674                if (opti >= args.length) {
8675                    name = null;
8676                    newArgs = EMPTY_STRING_ARRAY;
8677                } else {
8678                    name = args[opti];
8679                    opti++;
8680                    newArgs = new String[args.length - opti];
8681                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8682                }
8683                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8684                    pw.println("No providers match: " + name);
8685                    pw.println("Use -h for help.");
8686                }
8687            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8688                synchronized (this) {
8689                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8690                }
8691            } else if ("service".equals(cmd)) {
8692                String[] newArgs;
8693                String name;
8694                if (opti >= args.length) {
8695                    name = null;
8696                    newArgs = EMPTY_STRING_ARRAY;
8697                } else {
8698                    name = args[opti];
8699                    opti++;
8700                    newArgs = new String[args.length - opti];
8701                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8702                            args.length - opti);
8703                }
8704                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8705                    pw.println("No services match: " + name);
8706                    pw.println("Use -h for help.");
8707                }
8708            } else if ("package".equals(cmd)) {
8709                String[] newArgs;
8710                if (opti >= args.length) {
8711                    pw.println("package: no package name specified");
8712                    pw.println("Use -h for help.");
8713                } else {
8714                    dumpPackage = args[opti];
8715                    opti++;
8716                    newArgs = new String[args.length - opti];
8717                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8718                            args.length - opti);
8719                    args = newArgs;
8720                    opti = 0;
8721                    more = true;
8722                }
8723            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8724                synchronized (this) {
8725                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8726                }
8727            } else {
8728                // Dumping a single activity?
8729                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8730                    pw.println("Bad activity command, or no activities match: " + cmd);
8731                    pw.println("Use -h for help.");
8732                }
8733            }
8734            if (!more) {
8735                Binder.restoreCallingIdentity(origId);
8736                return;
8737            }
8738        }
8739
8740        // No piece of data specified, dump everything.
8741        synchronized (this) {
8742            boolean needSep;
8743            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8744            if (needSep) {
8745                pw.println(" ");
8746            }
8747            if (dumpAll) {
8748                pw.println("-------------------------------------------------------------------------------");
8749            }
8750            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8751            if (needSep) {
8752                pw.println(" ");
8753            }
8754            if (dumpAll) {
8755                pw.println("-------------------------------------------------------------------------------");
8756            }
8757            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8758            if (needSep) {
8759                pw.println(" ");
8760            }
8761            if (dumpAll) {
8762                pw.println("-------------------------------------------------------------------------------");
8763            }
8764            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8765            if (needSep) {
8766                pw.println(" ");
8767            }
8768            if (dumpAll) {
8769                pw.println("-------------------------------------------------------------------------------");
8770            }
8771            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8772            if (needSep) {
8773                pw.println(" ");
8774            }
8775            if (dumpAll) {
8776                pw.println("-------------------------------------------------------------------------------");
8777            }
8778            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8779        }
8780        Binder.restoreCallingIdentity(origId);
8781    }
8782
8783    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8784            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8785        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8786        pw.println("  Main stack:");
8787        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8788                dumpPackage);
8789        pw.println(" ");
8790        pw.println("  Running activities (most recent first):");
8791        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8792                dumpPackage);
8793        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8794            pw.println(" ");
8795            pw.println("  Activities waiting for another to become visible:");
8796            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8797                    !dumpAll, false, dumpPackage);
8798        }
8799        if (mMainStack.mStoppingActivities.size() > 0) {
8800            pw.println(" ");
8801            pw.println("  Activities waiting to stop:");
8802            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8803                    !dumpAll, false, dumpPackage);
8804        }
8805        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8806            pw.println(" ");
8807            pw.println("  Activities waiting to sleep:");
8808            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8809                    !dumpAll, false, dumpPackage);
8810        }
8811        if (mMainStack.mFinishingActivities.size() > 0) {
8812            pw.println(" ");
8813            pw.println("  Activities waiting to finish:");
8814            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8815                    !dumpAll, false, dumpPackage);
8816        }
8817
8818        pw.println(" ");
8819        if (mMainStack.mPausingActivity != null) {
8820            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8821        }
8822        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8823        pw.println("  mFocusedActivity: " + mFocusedActivity);
8824        if (dumpAll) {
8825            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8826            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8827            pw.println("  mDismissKeyguardOnNextActivity: "
8828                    + mMainStack.mDismissKeyguardOnNextActivity);
8829        }
8830
8831        if (mRecentTasks.size() > 0) {
8832            pw.println();
8833            pw.println("  Recent tasks:");
8834
8835            final int N = mRecentTasks.size();
8836            for (int i=0; i<N; i++) {
8837                TaskRecord tr = mRecentTasks.get(i);
8838                if (dumpPackage != null) {
8839                    if (tr.realActivity == null ||
8840                            !dumpPackage.equals(tr.realActivity)) {
8841                        continue;
8842                    }
8843                }
8844                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8845                        pw.println(tr);
8846                if (dumpAll) {
8847                    mRecentTasks.get(i).dump(pw, "    ");
8848                }
8849            }
8850        }
8851
8852        if (dumpAll) {
8853            pw.println(" ");
8854            pw.println("  mCurTask: " + mCurTask);
8855        }
8856
8857        return true;
8858    }
8859
8860    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8861            int opti, boolean dumpAll, String dumpPackage) {
8862        boolean needSep = false;
8863        int numPers = 0;
8864
8865        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8866
8867        if (dumpAll) {
8868            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8869                final int NA = procs.size();
8870                for (int ia=0; ia<NA; ia++) {
8871                    ProcessRecord r = procs.valueAt(ia);
8872                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8873                        continue;
8874                    }
8875                    if (!needSep) {
8876                        pw.println("  All known processes:");
8877                        needSep = true;
8878                    }
8879                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8880                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8881                        pw.print(" "); pw.println(r);
8882                    r.dump(pw, "    ");
8883                    if (r.persistent) {
8884                        numPers++;
8885                    }
8886                }
8887            }
8888        }
8889
8890        if (mIsolatedProcesses.size() > 0) {
8891            if (needSep) pw.println(" ");
8892            needSep = true;
8893            pw.println("  Isolated process list (sorted by uid):");
8894            for (int i=0; i<mIsolatedProcesses.size(); i++) {
8895                ProcessRecord r = mIsolatedProcesses.valueAt(i);
8896                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8897                    continue;
8898                }
8899                pw.println(String.format("%sIsolated #%2d: %s",
8900                        "    ", i, r.toString()));
8901            }
8902        }
8903
8904        if (mLruProcesses.size() > 0) {
8905            if (needSep) pw.println(" ");
8906            needSep = true;
8907            pw.println("  Process LRU list (sorted by oom_adj):");
8908            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8909                    "Proc", "PERS", false, dumpPackage);
8910            needSep = true;
8911        }
8912
8913        if (dumpAll) {
8914            synchronized (mPidsSelfLocked) {
8915                boolean printed = false;
8916                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8917                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8918                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8919                        continue;
8920                    }
8921                    if (!printed) {
8922                        if (needSep) pw.println(" ");
8923                        needSep = true;
8924                        pw.println("  PID mappings:");
8925                        printed = true;
8926                    }
8927                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8928                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8929                }
8930            }
8931        }
8932
8933        if (mForegroundProcesses.size() > 0) {
8934            synchronized (mPidsSelfLocked) {
8935                boolean printed = false;
8936                for (int i=0; i<mForegroundProcesses.size(); i++) {
8937                    ProcessRecord r = mPidsSelfLocked.get(
8938                            mForegroundProcesses.valueAt(i).pid);
8939                    if (dumpPackage != null && (r == null
8940                            || !dumpPackage.equals(r.info.packageName))) {
8941                        continue;
8942                    }
8943                    if (!printed) {
8944                        if (needSep) pw.println(" ");
8945                        needSep = true;
8946                        pw.println("  Foreground Processes:");
8947                        printed = true;
8948                    }
8949                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
8950                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8951                }
8952            }
8953        }
8954
8955        if (mPersistentStartingProcesses.size() > 0) {
8956            if (needSep) pw.println(" ");
8957            needSep = true;
8958            pw.println("  Persisent processes that are starting:");
8959            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
8960                    "Starting Norm", "Restarting PERS", dumpPackage);
8961        }
8962
8963        if (mRemovedProcesses.size() > 0) {
8964            if (needSep) pw.println(" ");
8965            needSep = true;
8966            pw.println("  Processes that are being removed:");
8967            dumpProcessList(pw, this, mRemovedProcesses, "    ",
8968                    "Removed Norm", "Removed PERS", dumpPackage);
8969        }
8970
8971        if (mProcessesOnHold.size() > 0) {
8972            if (needSep) pw.println(" ");
8973            needSep = true;
8974            pw.println("  Processes that are on old until the system is ready:");
8975            dumpProcessList(pw, this, mProcessesOnHold, "    ",
8976                    "OnHold Norm", "OnHold PERS", dumpPackage);
8977        }
8978
8979        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
8980
8981        if (mProcessCrashTimes.getMap().size() > 0) {
8982            boolean printed = false;
8983            long now = SystemClock.uptimeMillis();
8984            for (Map.Entry<String, SparseArray<Long>> procs
8985                    : mProcessCrashTimes.getMap().entrySet()) {
8986                String pname = procs.getKey();
8987                SparseArray<Long> uids = procs.getValue();
8988                final int N = uids.size();
8989                for (int i=0; i<N; i++) {
8990                    int puid = uids.keyAt(i);
8991                    ProcessRecord r = mProcessNames.get(pname, puid);
8992                    if (dumpPackage != null && (r == null
8993                            || !dumpPackage.equals(r.info.packageName))) {
8994                        continue;
8995                    }
8996                    if (!printed) {
8997                        if (needSep) pw.println(" ");
8998                        needSep = true;
8999                        pw.println("  Time since processes crashed:");
9000                        printed = true;
9001                    }
9002                    pw.print("    Process "); pw.print(pname);
9003                            pw.print(" uid "); pw.print(puid);
9004                            pw.print(": last crashed ");
9005                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9006                            pw.println(" ago");
9007                }
9008            }
9009        }
9010
9011        if (mBadProcesses.getMap().size() > 0) {
9012            boolean printed = false;
9013            for (Map.Entry<String, SparseArray<Long>> procs
9014                    : mBadProcesses.getMap().entrySet()) {
9015                String pname = procs.getKey();
9016                SparseArray<Long> uids = procs.getValue();
9017                final int N = uids.size();
9018                for (int i=0; i<N; i++) {
9019                    int puid = uids.keyAt(i);
9020                    ProcessRecord r = mProcessNames.get(pname, puid);
9021                    if (dumpPackage != null && (r == null
9022                            || !dumpPackage.equals(r.info.packageName))) {
9023                        continue;
9024                    }
9025                    if (!printed) {
9026                        if (needSep) pw.println(" ");
9027                        needSep = true;
9028                        pw.println("  Bad processes:");
9029                    }
9030                    pw.print("    Bad process "); pw.print(pname);
9031                            pw.print(" uid "); pw.print(puid);
9032                            pw.print(": crashed at time ");
9033                            pw.println(uids.valueAt(i));
9034                }
9035            }
9036        }
9037
9038        pw.println();
9039        pw.println("  mHomeProcess: " + mHomeProcess);
9040        pw.println("  mPreviousProcess: " + mPreviousProcess);
9041        if (dumpAll) {
9042            StringBuilder sb = new StringBuilder(128);
9043            sb.append("  mPreviousProcessVisibleTime: ");
9044            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9045            pw.println(sb);
9046        }
9047        if (mHeavyWeightProcess != null) {
9048            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9049        }
9050        pw.println("  mConfiguration: " + mConfiguration);
9051        if (dumpAll) {
9052            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9053            if (mCompatModePackages.getPackages().size() > 0) {
9054                boolean printed = false;
9055                for (Map.Entry<String, Integer> entry
9056                        : mCompatModePackages.getPackages().entrySet()) {
9057                    String pkg = entry.getKey();
9058                    int mode = entry.getValue();
9059                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9060                        continue;
9061                    }
9062                    if (!printed) {
9063                        pw.println("  mScreenCompatPackages:");
9064                        printed = true;
9065                    }
9066                    pw.print("    "); pw.print(pkg); pw.print(": ");
9067                            pw.print(mode); pw.println();
9068                }
9069            }
9070        }
9071        if (mSleeping || mWentToSleep || mLockScreenShown) {
9072            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9073                    + " mLockScreenShown " + mLockScreenShown);
9074        }
9075        if (mShuttingDown) {
9076            pw.println("  mShuttingDown=" + mShuttingDown);
9077        }
9078        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9079                || mOrigWaitForDebugger) {
9080            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9081                    + " mDebugTransient=" + mDebugTransient
9082                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9083        }
9084        if (mOpenGlTraceApp != null) {
9085            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9086        }
9087        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9088                || mProfileFd != null) {
9089            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9090            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9091            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9092                    + mAutoStopProfiler);
9093        }
9094        if (mAlwaysFinishActivities || mController != null) {
9095            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9096                    + " mController=" + mController);
9097        }
9098        if (dumpAll) {
9099            pw.println("  Total persistent processes: " + numPers);
9100            pw.println("  mStartRunning=" + mStartRunning
9101                    + " mProcessesReady=" + mProcessesReady
9102                    + " mSystemReady=" + mSystemReady);
9103            pw.println("  mBooting=" + mBooting
9104                    + " mBooted=" + mBooted
9105                    + " mFactoryTest=" + mFactoryTest);
9106            pw.print("  mLastPowerCheckRealtime=");
9107                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9108                    pw.println("");
9109            pw.print("  mLastPowerCheckUptime=");
9110                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9111                    pw.println("");
9112            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9113            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9114            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9115            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9116                    + " mNumHiddenProcs=" + mNumHiddenProcs
9117                    + " mNumServiceProcs=" + mNumServiceProcs
9118                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9119        }
9120
9121        return true;
9122    }
9123
9124    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9125            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9126        if (mProcessesToGc.size() > 0) {
9127            boolean printed = false;
9128            long now = SystemClock.uptimeMillis();
9129            for (int i=0; i<mProcessesToGc.size(); i++) {
9130                ProcessRecord proc = mProcessesToGc.get(i);
9131                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9132                    continue;
9133                }
9134                if (!printed) {
9135                    if (needSep) pw.println(" ");
9136                    needSep = true;
9137                    pw.println("  Processes that are waiting to GC:");
9138                    printed = true;
9139                }
9140                pw.print("    Process "); pw.println(proc);
9141                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9142                        pw.print(", last gced=");
9143                        pw.print(now-proc.lastRequestedGc);
9144                        pw.print(" ms ago, last lowMem=");
9145                        pw.print(now-proc.lastLowMemory);
9146                        pw.println(" ms ago");
9147
9148            }
9149        }
9150        return needSep;
9151    }
9152
9153    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9154            int opti, boolean dumpAll) {
9155        boolean needSep = false;
9156
9157        if (mLruProcesses.size() > 0) {
9158            if (needSep) pw.println(" ");
9159            needSep = true;
9160            pw.println("  OOM levels:");
9161            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9162            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9163            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9164            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9165            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9166            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9167            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9168            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9169            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9170            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9171            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9172            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9173            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9174
9175            if (needSep) pw.println(" ");
9176            needSep = true;
9177            pw.println("  Process OOM control:");
9178            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9179                    "Proc", "PERS", true, null);
9180            needSep = true;
9181        }
9182
9183        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9184
9185        pw.println();
9186        pw.println("  mHomeProcess: " + mHomeProcess);
9187        pw.println("  mPreviousProcess: " + mPreviousProcess);
9188        if (mHeavyWeightProcess != null) {
9189            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9190        }
9191
9192        return true;
9193    }
9194
9195    /**
9196     * There are three ways to call this:
9197     *  - no provider specified: dump all the providers
9198     *  - a flattened component name that matched an existing provider was specified as the
9199     *    first arg: dump that one provider
9200     *  - the first arg isn't the flattened component name of an existing provider:
9201     *    dump all providers whose component contains the first arg as a substring
9202     */
9203    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9204            int opti, boolean dumpAll) {
9205        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9206    }
9207
9208    static class ItemMatcher {
9209        ArrayList<ComponentName> components;
9210        ArrayList<String> strings;
9211        ArrayList<Integer> objects;
9212        boolean all;
9213
9214        ItemMatcher() {
9215            all = true;
9216        }
9217
9218        void build(String name) {
9219            ComponentName componentName = ComponentName.unflattenFromString(name);
9220            if (componentName != null) {
9221                if (components == null) {
9222                    components = new ArrayList<ComponentName>();
9223                }
9224                components.add(componentName);
9225                all = false;
9226            } else {
9227                int objectId = 0;
9228                // Not a '/' separated full component name; maybe an object ID?
9229                try {
9230                    objectId = Integer.parseInt(name, 16);
9231                    if (objects == null) {
9232                        objects = new ArrayList<Integer>();
9233                    }
9234                    objects.add(objectId);
9235                    all = false;
9236                } catch (RuntimeException e) {
9237                    // Not an integer; just do string match.
9238                    if (strings == null) {
9239                        strings = new ArrayList<String>();
9240                    }
9241                    strings.add(name);
9242                    all = false;
9243                }
9244            }
9245        }
9246
9247        int build(String[] args, int opti) {
9248            for (; opti<args.length; opti++) {
9249                String name = args[opti];
9250                if ("--".equals(name)) {
9251                    return opti+1;
9252                }
9253                build(name);
9254            }
9255            return opti;
9256        }
9257
9258        boolean match(Object object, ComponentName comp) {
9259            if (all) {
9260                return true;
9261            }
9262            if (components != null) {
9263                for (int i=0; i<components.size(); i++) {
9264                    if (components.get(i).equals(comp)) {
9265                        return true;
9266                    }
9267                }
9268            }
9269            if (objects != null) {
9270                for (int i=0; i<objects.size(); i++) {
9271                    if (System.identityHashCode(object) == objects.get(i)) {
9272                        return true;
9273                    }
9274                }
9275            }
9276            if (strings != null) {
9277                String flat = comp.flattenToString();
9278                for (int i=0; i<strings.size(); i++) {
9279                    if (flat.contains(strings.get(i))) {
9280                        return true;
9281                    }
9282                }
9283            }
9284            return false;
9285        }
9286    }
9287
9288    /**
9289     * There are three things that cmd can be:
9290     *  - a flattened component name that matches an existing activity
9291     *  - the cmd arg isn't the flattened component name of an existing activity:
9292     *    dump all activity whose component contains the cmd as a substring
9293     *  - A hex number of the ActivityRecord object instance.
9294     */
9295    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9296            int opti, boolean dumpAll) {
9297        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9298
9299        if ("all".equals(name)) {
9300            synchronized (this) {
9301                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9302                    activities.add(r1);
9303                }
9304            }
9305        } else if ("top".equals(name)) {
9306            synchronized (this) {
9307                final int N = mMainStack.mHistory.size();
9308                if (N > 0) {
9309                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9310                }
9311            }
9312        } else {
9313            ItemMatcher matcher = new ItemMatcher();
9314            matcher.build(name);
9315
9316            synchronized (this) {
9317                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9318                    if (matcher.match(r1, r1.intent.getComponent())) {
9319                        activities.add(r1);
9320                    }
9321                }
9322            }
9323        }
9324
9325        if (activities.size() <= 0) {
9326            return false;
9327        }
9328
9329        String[] newArgs = new String[args.length - opti];
9330        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9331
9332        TaskRecord lastTask = null;
9333        boolean needSep = false;
9334        for (int i=activities.size()-1; i>=0; i--) {
9335            ActivityRecord r = (ActivityRecord)activities.get(i);
9336            if (needSep) {
9337                pw.println();
9338            }
9339            needSep = true;
9340            synchronized (this) {
9341                if (lastTask != r.task) {
9342                    lastTask = r.task;
9343                    pw.print("TASK "); pw.print(lastTask.affinity);
9344                            pw.print(" id="); pw.println(lastTask.taskId);
9345                    if (dumpAll) {
9346                        lastTask.dump(pw, "  ");
9347                    }
9348                }
9349            }
9350            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9351        }
9352        return true;
9353    }
9354
9355    /**
9356     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9357     * there is a thread associated with the activity.
9358     */
9359    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9360            final ActivityRecord r, String[] args, boolean dumpAll) {
9361        String innerPrefix = prefix + "  ";
9362        synchronized (this) {
9363            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9364                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9365                    pw.print(" pid=");
9366                    if (r.app != null) pw.println(r.app.pid);
9367                    else pw.println("(not running)");
9368            if (dumpAll) {
9369                r.dump(pw, innerPrefix);
9370            }
9371        }
9372        if (r.app != null && r.app.thread != null) {
9373            // flush anything that is already in the PrintWriter since the thread is going
9374            // to write to the file descriptor directly
9375            pw.flush();
9376            try {
9377                TransferPipe tp = new TransferPipe();
9378                try {
9379                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9380                            r.appToken, innerPrefix, args);
9381                    tp.go(fd);
9382                } finally {
9383                    tp.kill();
9384                }
9385            } catch (IOException e) {
9386                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9387            } catch (RemoteException e) {
9388                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9389            }
9390        }
9391    }
9392
9393    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9394            int opti, boolean dumpAll, String dumpPackage) {
9395        boolean needSep = false;
9396
9397        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9398        if (dumpAll) {
9399            if (mRegisteredReceivers.size() > 0) {
9400                boolean printed = false;
9401                Iterator it = mRegisteredReceivers.values().iterator();
9402                while (it.hasNext()) {
9403                    ReceiverList r = (ReceiverList)it.next();
9404                    if (dumpPackage != null && (r.app == null ||
9405                            !dumpPackage.equals(r.app.info.packageName))) {
9406                        continue;
9407                    }
9408                    if (!printed) {
9409                        pw.println("  Registered Receivers:");
9410                        needSep = true;
9411                        printed = true;
9412                    }
9413                    pw.print("  * "); pw.println(r);
9414                    r.dump(pw, "    ");
9415                }
9416            }
9417
9418            if (mReceiverResolver.dump(pw, needSep ?
9419                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9420                    "    ", dumpPackage, false)) {
9421                needSep = true;
9422            }
9423        }
9424
9425        for (BroadcastQueue q : mBroadcastQueues) {
9426            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9427        }
9428
9429        needSep = true;
9430
9431        if (mStickyBroadcasts != null && dumpPackage == null) {
9432            if (needSep) {
9433                pw.println();
9434            }
9435            needSep = true;
9436            pw.println("  Sticky broadcasts:");
9437            StringBuilder sb = new StringBuilder(128);
9438            for (Map.Entry<String, ArrayList<Intent>> ent
9439                    : mStickyBroadcasts.entrySet()) {
9440                pw.print("  * Sticky action "); pw.print(ent.getKey());
9441                if (dumpAll) {
9442                    pw.println(":");
9443                    ArrayList<Intent> intents = ent.getValue();
9444                    final int N = intents.size();
9445                    for (int i=0; i<N; i++) {
9446                        sb.setLength(0);
9447                        sb.append("    Intent: ");
9448                        intents.get(i).toShortString(sb, false, true, false, false);
9449                        pw.println(sb.toString());
9450                        Bundle bundle = intents.get(i).getExtras();
9451                        if (bundle != null) {
9452                            pw.print("      ");
9453                            pw.println(bundle.toString());
9454                        }
9455                    }
9456                } else {
9457                    pw.println("");
9458                }
9459            }
9460            needSep = true;
9461        }
9462
9463        if (dumpAll) {
9464            pw.println();
9465            for (BroadcastQueue queue : mBroadcastQueues) {
9466                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9467                        + queue.mBroadcastsScheduled);
9468            }
9469            pw.println("  mHandler:");
9470            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9471            needSep = true;
9472        }
9473
9474        return needSep;
9475    }
9476
9477    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9478            int opti, boolean dumpAll, String dumpPackage) {
9479        boolean needSep = true;
9480
9481        ItemMatcher matcher = new ItemMatcher();
9482        matcher.build(args, opti);
9483
9484        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9485
9486        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9487
9488        if (mLaunchingProviders.size() > 0) {
9489            boolean printed = false;
9490            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9491                ContentProviderRecord r = mLaunchingProviders.get(i);
9492                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9493                    continue;
9494                }
9495                if (!printed) {
9496                    if (needSep) pw.println(" ");
9497                    needSep = true;
9498                    pw.println("  Launching content providers:");
9499                    printed = true;
9500                }
9501                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9502                        pw.println(r);
9503            }
9504        }
9505
9506        if (mGrantedUriPermissions.size() > 0) {
9507            if (needSep) pw.println();
9508            needSep = true;
9509            pw.println("Granted Uri Permissions:");
9510            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9511                int uid = mGrantedUriPermissions.keyAt(i);
9512                HashMap<Uri, UriPermission> perms
9513                        = mGrantedUriPermissions.valueAt(i);
9514                pw.print("  * UID "); pw.print(uid);
9515                        pw.println(" holds:");
9516                for (UriPermission perm : perms.values()) {
9517                    pw.print("    "); pw.println(perm);
9518                    if (dumpAll) {
9519                        perm.dump(pw, "      ");
9520                    }
9521                }
9522            }
9523            needSep = true;
9524        }
9525
9526        return needSep;
9527    }
9528
9529    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9530            int opti, boolean dumpAll, String dumpPackage) {
9531        boolean needSep = false;
9532
9533        if (mIntentSenderRecords.size() > 0) {
9534            boolean printed = false;
9535            Iterator<WeakReference<PendingIntentRecord>> it
9536                    = mIntentSenderRecords.values().iterator();
9537            while (it.hasNext()) {
9538                WeakReference<PendingIntentRecord> ref = it.next();
9539                PendingIntentRecord rec = ref != null ? ref.get(): null;
9540                if (dumpPackage != null && (rec == null
9541                        || !dumpPackage.equals(rec.key.packageName))) {
9542                    continue;
9543                }
9544                if (!printed) {
9545                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9546                    printed = true;
9547                }
9548                needSep = true;
9549                if (rec != null) {
9550                    pw.print("  * "); pw.println(rec);
9551                    if (dumpAll) {
9552                        rec.dump(pw, "    ");
9553                    }
9554                } else {
9555                    pw.print("  * "); pw.println(ref);
9556                }
9557            }
9558        }
9559
9560        return needSep;
9561    }
9562
9563    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9564            String prefix, String label, boolean complete, boolean brief, boolean client,
9565            String dumpPackage) {
9566        TaskRecord lastTask = null;
9567        boolean needNL = false;
9568        final String innerPrefix = prefix + "      ";
9569        final String[] args = new String[0];
9570        for (int i=list.size()-1; i>=0; i--) {
9571            final ActivityRecord r = (ActivityRecord)list.get(i);
9572            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9573                continue;
9574            }
9575            final boolean full = !brief && (complete || !r.isInHistory());
9576            if (needNL) {
9577                pw.println(" ");
9578                needNL = false;
9579            }
9580            if (lastTask != r.task) {
9581                lastTask = r.task;
9582                pw.print(prefix);
9583                pw.print(full ? "* " : "  ");
9584                pw.println(lastTask);
9585                if (full) {
9586                    lastTask.dump(pw, prefix + "  ");
9587                } else if (complete) {
9588                    // Complete + brief == give a summary.  Isn't that obvious?!?
9589                    if (lastTask.intent != null) {
9590                        pw.print(prefix); pw.print("  ");
9591                                pw.println(lastTask.intent.toInsecureStringWithClip());
9592                    }
9593                }
9594            }
9595            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9596            pw.print(" #"); pw.print(i); pw.print(": ");
9597            pw.println(r);
9598            if (full) {
9599                r.dump(pw, innerPrefix);
9600            } else if (complete) {
9601                // Complete + brief == give a summary.  Isn't that obvious?!?
9602                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9603                if (r.app != null) {
9604                    pw.print(innerPrefix); pw.println(r.app);
9605                }
9606            }
9607            if (client && r.app != null && r.app.thread != null) {
9608                // flush anything that is already in the PrintWriter since the thread is going
9609                // to write to the file descriptor directly
9610                pw.flush();
9611                try {
9612                    TransferPipe tp = new TransferPipe();
9613                    try {
9614                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9615                                r.appToken, innerPrefix, args);
9616                        // Short timeout, since blocking here can
9617                        // deadlock with the application.
9618                        tp.go(fd, 2000);
9619                    } finally {
9620                        tp.kill();
9621                    }
9622                } catch (IOException e) {
9623                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9624                } catch (RemoteException e) {
9625                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9626                }
9627                needNL = true;
9628            }
9629        }
9630    }
9631
9632    private static String buildOomTag(String prefix, String space, int val, int base) {
9633        if (val == base) {
9634            if (space == null) return prefix;
9635            return prefix + "  ";
9636        }
9637        return prefix + "+" + Integer.toString(val-base);
9638    }
9639
9640    private static final int dumpProcessList(PrintWriter pw,
9641            ActivityManagerService service, List list,
9642            String prefix, String normalLabel, String persistentLabel,
9643            String dumpPackage) {
9644        int numPers = 0;
9645        final int N = list.size()-1;
9646        for (int i=N; i>=0; i--) {
9647            ProcessRecord r = (ProcessRecord)list.get(i);
9648            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9649                continue;
9650            }
9651            pw.println(String.format("%s%s #%2d: %s",
9652                    prefix, (r.persistent ? persistentLabel : normalLabel),
9653                    i, r.toString()));
9654            if (r.persistent) {
9655                numPers++;
9656            }
9657        }
9658        return numPers;
9659    }
9660
9661    private static final boolean dumpProcessOomList(PrintWriter pw,
9662            ActivityManagerService service, List<ProcessRecord> origList,
9663            String prefix, String normalLabel, String persistentLabel,
9664            boolean inclDetails, String dumpPackage) {
9665
9666        ArrayList<Pair<ProcessRecord, Integer>> list
9667                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9668        for (int i=0; i<origList.size(); i++) {
9669            ProcessRecord r = origList.get(i);
9670            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9671                continue;
9672            }
9673            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9674        }
9675
9676        if (list.size() <= 0) {
9677            return false;
9678        }
9679
9680        Comparator<Pair<ProcessRecord, Integer>> comparator
9681                = new Comparator<Pair<ProcessRecord, Integer>>() {
9682            @Override
9683            public int compare(Pair<ProcessRecord, Integer> object1,
9684                    Pair<ProcessRecord, Integer> object2) {
9685                if (object1.first.setAdj != object2.first.setAdj) {
9686                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9687                }
9688                if (object1.second.intValue() != object2.second.intValue()) {
9689                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9690                }
9691                return 0;
9692            }
9693        };
9694
9695        Collections.sort(list, comparator);
9696
9697        final long curRealtime = SystemClock.elapsedRealtime();
9698        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9699        final long curUptime = SystemClock.uptimeMillis();
9700        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9701
9702        for (int i=list.size()-1; i>=0; i--) {
9703            ProcessRecord r = list.get(i).first;
9704            String oomAdj;
9705            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9706                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9707            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9708                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9709            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9710                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9711            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9712                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9713            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9714                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9715            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9716                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9717            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9718                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9719            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9720                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9721            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9722                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9723            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9724                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9725            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9726                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9727            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9728                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9729            } else {
9730                oomAdj = Integer.toString(r.setAdj);
9731            }
9732            String schedGroup;
9733            switch (r.setSchedGroup) {
9734                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9735                    schedGroup = "B";
9736                    break;
9737                case Process.THREAD_GROUP_DEFAULT:
9738                    schedGroup = "F";
9739                    break;
9740                default:
9741                    schedGroup = Integer.toString(r.setSchedGroup);
9742                    break;
9743            }
9744            String foreground;
9745            if (r.foregroundActivities) {
9746                foreground = "A";
9747            } else if (r.foregroundServices) {
9748                foreground = "S";
9749            } else {
9750                foreground = " ";
9751            }
9752            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9753                    prefix, (r.persistent ? persistentLabel : normalLabel),
9754                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9755                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9756            if (r.adjSource != null || r.adjTarget != null) {
9757                pw.print(prefix);
9758                pw.print("    ");
9759                if (r.adjTarget instanceof ComponentName) {
9760                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9761                } else if (r.adjTarget != null) {
9762                    pw.print(r.adjTarget.toString());
9763                } else {
9764                    pw.print("{null}");
9765                }
9766                pw.print("<=");
9767                if (r.adjSource instanceof ProcessRecord) {
9768                    pw.print("Proc{");
9769                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9770                    pw.println("}");
9771                } else if (r.adjSource != null) {
9772                    pw.println(r.adjSource.toString());
9773                } else {
9774                    pw.println("{null}");
9775                }
9776            }
9777            if (inclDetails) {
9778                pw.print(prefix);
9779                pw.print("    ");
9780                pw.print("oom: max="); pw.print(r.maxAdj);
9781                pw.print(" hidden="); pw.print(r.hiddenAdj);
9782                pw.print(" empty="); pw.print(r.emptyAdj);
9783                pw.print(" curRaw="); pw.print(r.curRawAdj);
9784                pw.print(" setRaw="); pw.print(r.setRawAdj);
9785                pw.print(" cur="); pw.print(r.curAdj);
9786                pw.print(" set="); pw.println(r.setAdj);
9787                pw.print(prefix);
9788                pw.print("    ");
9789                pw.print("keeping="); pw.print(r.keeping);
9790                pw.print(" hidden="); pw.print(r.hidden);
9791                pw.print(" empty="); pw.print(r.empty);
9792                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9793
9794                if (!r.keeping) {
9795                    if (r.lastWakeTime != 0) {
9796                        long wtime;
9797                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9798                        synchronized (stats) {
9799                            wtime = stats.getProcessWakeTime(r.info.uid,
9800                                    r.pid, curRealtime);
9801                        }
9802                        long timeUsed = wtime - r.lastWakeTime;
9803                        pw.print(prefix);
9804                        pw.print("    ");
9805                        pw.print("keep awake over ");
9806                        TimeUtils.formatDuration(realtimeSince, pw);
9807                        pw.print(" used ");
9808                        TimeUtils.formatDuration(timeUsed, pw);
9809                        pw.print(" (");
9810                        pw.print((timeUsed*100)/realtimeSince);
9811                        pw.println("%)");
9812                    }
9813                    if (r.lastCpuTime != 0) {
9814                        long timeUsed = r.curCpuTime - r.lastCpuTime;
9815                        pw.print(prefix);
9816                        pw.print("    ");
9817                        pw.print("run cpu over ");
9818                        TimeUtils.formatDuration(uptimeSince, pw);
9819                        pw.print(" used ");
9820                        TimeUtils.formatDuration(timeUsed, pw);
9821                        pw.print(" (");
9822                        pw.print((timeUsed*100)/uptimeSince);
9823                        pw.println("%)");
9824                    }
9825                }
9826            }
9827        }
9828        return true;
9829    }
9830
9831    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
9832        ArrayList<ProcessRecord> procs;
9833        synchronized (this) {
9834            if (args != null && args.length > start
9835                    && args[start].charAt(0) != '-') {
9836                procs = new ArrayList<ProcessRecord>();
9837                int pid = -1;
9838                try {
9839                    pid = Integer.parseInt(args[start]);
9840                } catch (NumberFormatException e) {
9841
9842                }
9843                for (int i=mLruProcesses.size()-1; i>=0; i--) {
9844                    ProcessRecord proc = mLruProcesses.get(i);
9845                    if (proc.pid == pid) {
9846                        procs.add(proc);
9847                    } else if (proc.processName.equals(args[start])) {
9848                        procs.add(proc);
9849                    }
9850                }
9851                if (procs.size() <= 0) {
9852                    pw.println("No process found for: " + args[start]);
9853                    return null;
9854                }
9855            } else {
9856                procs = new ArrayList<ProcessRecord>(mLruProcesses);
9857            }
9858        }
9859        return procs;
9860    }
9861
9862    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9863            PrintWriter pw, String[] args) {
9864        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9865        if (procs == null) {
9866            return;
9867        }
9868
9869        long uptime = SystemClock.uptimeMillis();
9870        long realtime = SystemClock.elapsedRealtime();
9871        pw.println("Applications Graphics Acceleration Info:");
9872        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9873
9874        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9875            ProcessRecord r = procs.get(i);
9876            if (r.thread != null) {
9877                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9878                pw.flush();
9879                try {
9880                    TransferPipe tp = new TransferPipe();
9881                    try {
9882                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9883                        tp.go(fd);
9884                    } finally {
9885                        tp.kill();
9886                    }
9887                } catch (IOException e) {
9888                    pw.println("Failure while dumping the app: " + r);
9889                    pw.flush();
9890                } catch (RemoteException e) {
9891                    pw.println("Got a RemoteException while dumping the app " + r);
9892                    pw.flush();
9893                }
9894            }
9895        }
9896    }
9897
9898    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
9899        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9900        if (procs == null) {
9901            return;
9902        }
9903
9904        pw.println("Applications Database Info:");
9905
9906        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9907            ProcessRecord r = procs.get(i);
9908            if (r.thread != null) {
9909                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
9910                pw.flush();
9911                try {
9912                    TransferPipe tp = new TransferPipe();
9913                    try {
9914                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
9915                        tp.go(fd);
9916                    } finally {
9917                        tp.kill();
9918                    }
9919                } catch (IOException e) {
9920                    pw.println("Failure while dumping the app: " + r);
9921                    pw.flush();
9922                } catch (RemoteException e) {
9923                    pw.println("Got a RemoteException while dumping the app " + r);
9924                    pw.flush();
9925                }
9926            }
9927        }
9928    }
9929
9930    final static class MemItem {
9931        final String label;
9932        final String shortLabel;
9933        final long pss;
9934        final int id;
9935        ArrayList<MemItem> subitems;
9936
9937        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
9938            label = _label;
9939            shortLabel = _shortLabel;
9940            pss = _pss;
9941            id = _id;
9942        }
9943    }
9944
9945    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9946            boolean sort) {
9947        if (sort) {
9948            Collections.sort(items, new Comparator<MemItem>() {
9949                @Override
9950                public int compare(MemItem lhs, MemItem rhs) {
9951                    if (lhs.pss < rhs.pss) {
9952                        return 1;
9953                    } else if (lhs.pss > rhs.pss) {
9954                        return -1;
9955                    }
9956                    return 0;
9957                }
9958            });
9959        }
9960
9961        for (int i=0; i<items.size(); i++) {
9962            MemItem mi = items.get(i);
9963            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
9964            if (mi.subitems != null) {
9965                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
9966            }
9967        }
9968    }
9969
9970    // These are in KB.
9971    static final long[] DUMP_MEM_BUCKETS = new long[] {
9972        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9973        120*1024, 160*1024, 200*1024,
9974        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9975        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9976    };
9977
9978    static final void appendMemBucket(StringBuilder out, long memKB, String label,
9979            boolean stackLike) {
9980        int start = label.lastIndexOf('.');
9981        if (start >= 0) start++;
9982        else start = 0;
9983        int end = label.length();
9984        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
9985            if (DUMP_MEM_BUCKETS[i] >= memKB) {
9986                long bucket = DUMP_MEM_BUCKETS[i]/1024;
9987                out.append(bucket);
9988                out.append(stackLike ? "MB." : "MB ");
9989                out.append(label, start, end);
9990                return;
9991            }
9992        }
9993        out.append(memKB/1024);
9994        out.append(stackLike ? "MB." : "MB ");
9995        out.append(label, start, end);
9996    }
9997
9998    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
9999            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10000            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10001            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10002            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10003    };
10004    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10005            "System", "Persistent", "Foreground",
10006            "Visible", "Perceptible", "Heavy Weight",
10007            "Backup", "A Services", "Home", "Previous",
10008            "B Services", "Background"
10009    };
10010
10011    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10012            PrintWriter pw, String prefix, String[] args, boolean brief,
10013            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10014        boolean dumpAll = false;
10015        boolean oomOnly = false;
10016
10017        int opti = 0;
10018        while (opti < args.length) {
10019            String opt = args[opti];
10020            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10021                break;
10022            }
10023            opti++;
10024            if ("-a".equals(opt)) {
10025                dumpAll = true;
10026            } else if ("--oom".equals(opt)) {
10027                oomOnly = true;
10028            } else if ("-h".equals(opt)) {
10029                pw.println("meminfo dump options: [-a] [--oom] [process]");
10030                pw.println("  -a: include all available information for each process.");
10031                pw.println("  --oom: only show processes organized by oom adj.");
10032                pw.println("If [process] is specified it can be the name or ");
10033                pw.println("pid of a specific process to dump.");
10034                return;
10035            } else {
10036                pw.println("Unknown argument: " + opt + "; use -h for help");
10037            }
10038        }
10039
10040        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10041        if (procs == null) {
10042            return;
10043        }
10044
10045        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10046        long uptime = SystemClock.uptimeMillis();
10047        long realtime = SystemClock.elapsedRealtime();
10048
10049        if (procs.size() == 1 || isCheckinRequest) {
10050            dumpAll = true;
10051        }
10052
10053        if (isCheckinRequest) {
10054            // short checkin version
10055            pw.println(uptime + "," + realtime);
10056            pw.flush();
10057        } else {
10058            pw.println("Applications Memory Usage (kB):");
10059            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10060        }
10061
10062        String[] innerArgs = new String[args.length-opti];
10063        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10064
10065        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10066        long nativePss=0, dalvikPss=0, otherPss=0;
10067        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10068
10069        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10070        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10071                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10072
10073        long totalPss = 0;
10074
10075        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10076            ProcessRecord r = procs.get(i);
10077            if (r.thread != null) {
10078                if (!isCheckinRequest && dumpAll) {
10079                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10080                    pw.flush();
10081                }
10082                Debug.MemoryInfo mi = null;
10083                if (dumpAll) {
10084                    try {
10085                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10086                    } catch (RemoteException e) {
10087                        if (!isCheckinRequest) {
10088                            pw.println("Got RemoteException!");
10089                            pw.flush();
10090                        }
10091                    }
10092                } else {
10093                    mi = new Debug.MemoryInfo();
10094                    Debug.getMemoryInfo(r.pid, mi);
10095                }
10096
10097                if (!isCheckinRequest && mi != null) {
10098                    long myTotalPss = mi.getTotalPss();
10099                    totalPss += myTotalPss;
10100                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10101                            r.processName, myTotalPss, 0);
10102                    procMems.add(pssItem);
10103
10104                    nativePss += mi.nativePss;
10105                    dalvikPss += mi.dalvikPss;
10106                    otherPss += mi.otherPss;
10107                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10108                        long mem = mi.getOtherPss(j);
10109                        miscPss[j] += mem;
10110                        otherPss -= mem;
10111                    }
10112
10113                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10114                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10115                                || oomIndex == (oomPss.length-1)) {
10116                            oomPss[oomIndex] += myTotalPss;
10117                            if (oomProcs[oomIndex] == null) {
10118                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10119                            }
10120                            oomProcs[oomIndex].add(pssItem);
10121                            break;
10122                        }
10123                    }
10124                }
10125            }
10126        }
10127
10128        if (!isCheckinRequest && procs.size() > 1) {
10129            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10130
10131            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10132            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10133            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10134            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10135                String label = Debug.MemoryInfo.getOtherLabel(j);
10136                catMems.add(new MemItem(label, label, miscPss[j], j));
10137            }
10138
10139            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10140            for (int j=0; j<oomPss.length; j++) {
10141                if (oomPss[j] != 0) {
10142                    String label = DUMP_MEM_OOM_LABEL[j];
10143                    MemItem item = new MemItem(label, label, oomPss[j],
10144                            DUMP_MEM_OOM_ADJ[j]);
10145                    item.subitems = oomProcs[j];
10146                    oomMems.add(item);
10147                }
10148            }
10149
10150            if (outTag != null || outStack != null) {
10151                if (outTag != null) {
10152                    appendMemBucket(outTag, totalPss, "total", false);
10153                }
10154                if (outStack != null) {
10155                    appendMemBucket(outStack, totalPss, "total", true);
10156                }
10157                boolean firstLine = true;
10158                for (int i=0; i<oomMems.size(); i++) {
10159                    MemItem miCat = oomMems.get(i);
10160                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10161                        continue;
10162                    }
10163                    if (miCat.id < ProcessList.SERVICE_ADJ
10164                            || miCat.id == ProcessList.HOME_APP_ADJ
10165                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10166                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10167                            outTag.append(" / ");
10168                        }
10169                        if (outStack != null) {
10170                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10171                                if (firstLine) {
10172                                    outStack.append(":");
10173                                    firstLine = false;
10174                                }
10175                                outStack.append("\n\t at ");
10176                            } else {
10177                                outStack.append("$");
10178                            }
10179                        }
10180                        for (int j=0; j<miCat.subitems.size(); j++) {
10181                            MemItem mi = miCat.subitems.get(j);
10182                            if (j > 0) {
10183                                if (outTag != null) {
10184                                    outTag.append(" ");
10185                                }
10186                                if (outStack != null) {
10187                                    outStack.append("$");
10188                                }
10189                            }
10190                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10191                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10192                            }
10193                            if (outStack != null) {
10194                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10195                            }
10196                        }
10197                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10198                            outStack.append("(");
10199                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10200                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10201                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10202                                    outStack.append(":");
10203                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10204                                }
10205                            }
10206                            outStack.append(")");
10207                        }
10208                    }
10209                }
10210            }
10211
10212            if (!brief && !oomOnly) {
10213                pw.println();
10214                pw.println("Total PSS by process:");
10215                dumpMemItems(pw, "  ", procMems, true);
10216                pw.println();
10217            }
10218            pw.println("Total PSS by OOM adjustment:");
10219            dumpMemItems(pw, "  ", oomMems, false);
10220            if (!oomOnly) {
10221                PrintWriter out = categoryPw != null ? categoryPw : pw;
10222                out.println();
10223                out.println("Total PSS by category:");
10224                dumpMemItems(out, "  ", catMems, true);
10225            }
10226            pw.println();
10227            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10228            final int[] SINGLE_LONG_FORMAT = new int[] {
10229                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10230            };
10231            long[] longOut = new long[1];
10232            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10233                    SINGLE_LONG_FORMAT, null, longOut, null);
10234            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10235            longOut[0] = 0;
10236            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10237                    SINGLE_LONG_FORMAT, null, longOut, null);
10238            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10239            longOut[0] = 0;
10240            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10241                    SINGLE_LONG_FORMAT, null, longOut, null);
10242            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10243            longOut[0] = 0;
10244            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10245                    SINGLE_LONG_FORMAT, null, longOut, null);
10246            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10247            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10248                    pw.print(shared); pw.println(" kB");
10249            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10250                    pw.print(voltile); pw.println(" kB volatile");
10251        }
10252    }
10253
10254    /**
10255     * Searches array of arguments for the specified string
10256     * @param args array of argument strings
10257     * @param value value to search for
10258     * @return true if the value is contained in the array
10259     */
10260    private static boolean scanArgs(String[] args, String value) {
10261        if (args != null) {
10262            for (String arg : args) {
10263                if (value.equals(arg)) {
10264                    return true;
10265                }
10266            }
10267        }
10268        return false;
10269    }
10270
10271    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10272            ContentProviderRecord cpr, boolean always) {
10273        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10274
10275        if (!inLaunching || always) {
10276            synchronized (cpr) {
10277                cpr.launchingApp = null;
10278                cpr.notifyAll();
10279            }
10280            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10281            String names[] = cpr.info.authority.split(";");
10282            for (int j = 0; j < names.length; j++) {
10283                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10284            }
10285        }
10286
10287        for (int i=0; i<cpr.connections.size(); i++) {
10288            ContentProviderConnection conn = cpr.connections.get(i);
10289            if (conn.waiting) {
10290                // If this connection is waiting for the provider, then we don't
10291                // need to mess with its process unless we are always removing
10292                // or for some reason the provider is not currently launching.
10293                if (inLaunching && !always) {
10294                    continue;
10295                }
10296            }
10297            ProcessRecord capp = conn.client;
10298            conn.dead = true;
10299            if (conn.stableCount > 0) {
10300                if (!capp.persistent && capp.thread != null
10301                        && capp.pid != 0
10302                        && capp.pid != MY_PID) {
10303                    Slog.i(TAG, "Kill " + capp.processName
10304                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10305                            + " in dying process " + (proc != null ? proc.processName : "??"));
10306                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10307                            capp.processName, capp.setAdj, "dying provider "
10308                                    + cpr.name.toShortString());
10309                    Process.killProcessQuiet(capp.pid);
10310                }
10311            } else if (capp.thread != null && conn.provider.provider != null) {
10312                try {
10313                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10314                } catch (RemoteException e) {
10315                }
10316                // In the protocol here, we don't expect the client to correctly
10317                // clean up this connection, we'll just remove it.
10318                cpr.connections.remove(i);
10319                conn.client.conProviders.remove(conn);
10320            }
10321        }
10322
10323        if (inLaunching && always) {
10324            mLaunchingProviders.remove(cpr);
10325        }
10326        return inLaunching;
10327    }
10328
10329    /**
10330     * Main code for cleaning up a process when it has gone away.  This is
10331     * called both as a result of the process dying, or directly when stopping
10332     * a process when running in single process mode.
10333     */
10334    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10335            boolean restarting, boolean allowRestart, int index) {
10336        if (index >= 0) {
10337            mLruProcesses.remove(index);
10338        }
10339
10340        mProcessesToGc.remove(app);
10341
10342        // Dismiss any open dialogs.
10343        if (app.crashDialog != null) {
10344            app.crashDialog.dismiss();
10345            app.crashDialog = null;
10346        }
10347        if (app.anrDialog != null) {
10348            app.anrDialog.dismiss();
10349            app.anrDialog = null;
10350        }
10351        if (app.waitDialog != null) {
10352            app.waitDialog.dismiss();
10353            app.waitDialog = null;
10354        }
10355
10356        app.crashing = false;
10357        app.notResponding = false;
10358
10359        app.resetPackageList();
10360        app.unlinkDeathRecipient();
10361        app.thread = null;
10362        app.forcingToForeground = null;
10363        app.foregroundServices = false;
10364        app.foregroundActivities = false;
10365        app.hasShownUi = false;
10366        app.hasAboveClient = false;
10367
10368        mServices.killServicesLocked(app, allowRestart);
10369
10370        boolean restart = false;
10371
10372        // Remove published content providers.
10373        if (!app.pubProviders.isEmpty()) {
10374            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10375            while (it.hasNext()) {
10376                ContentProviderRecord cpr = it.next();
10377
10378                final boolean always = app.bad || !allowRestart;
10379                if (removeDyingProviderLocked(app, cpr, always) || always) {
10380                    // We left the provider in the launching list, need to
10381                    // restart it.
10382                    restart = true;
10383                }
10384
10385                cpr.provider = null;
10386                cpr.proc = null;
10387            }
10388            app.pubProviders.clear();
10389        }
10390
10391        // Take care of any launching providers waiting for this process.
10392        if (checkAppInLaunchingProvidersLocked(app, false)) {
10393            restart = true;
10394        }
10395
10396        // Unregister from connected content providers.
10397        if (!app.conProviders.isEmpty()) {
10398            for (int i=0; i<app.conProviders.size(); i++) {
10399                ContentProviderConnection conn = app.conProviders.get(i);
10400                conn.provider.connections.remove(conn);
10401            }
10402            app.conProviders.clear();
10403        }
10404
10405        // At this point there may be remaining entries in mLaunchingProviders
10406        // where we were the only one waiting, so they are no longer of use.
10407        // Look for these and clean up if found.
10408        // XXX Commented out for now.  Trying to figure out a way to reproduce
10409        // the actual situation to identify what is actually going on.
10410        if (false) {
10411            for (int i=0; i<mLaunchingProviders.size(); i++) {
10412                ContentProviderRecord cpr = (ContentProviderRecord)
10413                        mLaunchingProviders.get(i);
10414                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10415                    synchronized (cpr) {
10416                        cpr.launchingApp = null;
10417                        cpr.notifyAll();
10418                    }
10419                }
10420            }
10421        }
10422
10423        skipCurrentReceiverLocked(app);
10424
10425        // Unregister any receivers.
10426        if (app.receivers.size() > 0) {
10427            Iterator<ReceiverList> it = app.receivers.iterator();
10428            while (it.hasNext()) {
10429                removeReceiverLocked(it.next());
10430            }
10431            app.receivers.clear();
10432        }
10433
10434        // If the app is undergoing backup, tell the backup manager about it
10435        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10436            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10437            try {
10438                IBackupManager bm = IBackupManager.Stub.asInterface(
10439                        ServiceManager.getService(Context.BACKUP_SERVICE));
10440                bm.agentDisconnected(app.info.packageName);
10441            } catch (RemoteException e) {
10442                // can't happen; backup manager is local
10443            }
10444        }
10445
10446        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10447            ProcessChangeItem item = mPendingProcessChanges.get(i);
10448            if (item.pid == app.pid) {
10449                mPendingProcessChanges.remove(i);
10450                mAvailProcessChanges.add(item);
10451            }
10452        }
10453        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10454
10455        // If the caller is restarting this app, then leave it in its
10456        // current lists and let the caller take care of it.
10457        if (restarting) {
10458            return;
10459        }
10460
10461        if (!app.persistent || app.isolated) {
10462            if (DEBUG_PROCESSES) Slog.v(TAG,
10463                    "Removing non-persistent process during cleanup: " + app);
10464            mProcessNames.remove(app.processName, app.uid);
10465            mIsolatedProcesses.remove(app.uid);
10466            if (mHeavyWeightProcess == app) {
10467                mHeavyWeightProcess = null;
10468                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10469            }
10470        } else if (!app.removed) {
10471            // This app is persistent, so we need to keep its record around.
10472            // If it is not already on the pending app list, add it there
10473            // and start a new process for it.
10474            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10475                mPersistentStartingProcesses.add(app);
10476                restart = true;
10477            }
10478        }
10479        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10480                "Clean-up removing on hold: " + app);
10481        mProcessesOnHold.remove(app);
10482
10483        if (app == mHomeProcess) {
10484            mHomeProcess = null;
10485        }
10486        if (app == mPreviousProcess) {
10487            mPreviousProcess = null;
10488        }
10489
10490        if (restart && !app.isolated) {
10491            // We have components that still need to be running in the
10492            // process, so re-launch it.
10493            mProcessNames.put(app.processName, app.uid, app);
10494            startProcessLocked(app, "restart", app.processName);
10495        } else if (app.pid > 0 && app.pid != MY_PID) {
10496            // Goodbye!
10497            synchronized (mPidsSelfLocked) {
10498                mPidsSelfLocked.remove(app.pid);
10499                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10500            }
10501            app.setPid(0);
10502        }
10503    }
10504
10505    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10506        // Look through the content providers we are waiting to have launched,
10507        // and if any run in this process then either schedule a restart of
10508        // the process or kill the client waiting for it if this process has
10509        // gone bad.
10510        int NL = mLaunchingProviders.size();
10511        boolean restart = false;
10512        for (int i=0; i<NL; i++) {
10513            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10514            if (cpr.launchingApp == app) {
10515                if (!alwaysBad && !app.bad) {
10516                    restart = true;
10517                } else {
10518                    removeDyingProviderLocked(app, cpr, true);
10519                    NL = mLaunchingProviders.size();
10520                }
10521            }
10522        }
10523        return restart;
10524    }
10525
10526    // =========================================================
10527    // SERVICES
10528    // =========================================================
10529
10530    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10531            int flags) {
10532        enforceNotIsolatedCaller("getServices");
10533        synchronized (this) {
10534            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10535        }
10536    }
10537
10538    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10539        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10540        synchronized (this) {
10541            return mServices.getRunningServiceControlPanelLocked(name);
10542        }
10543    }
10544
10545    public ComponentName startService(IApplicationThread caller, Intent service,
10546            String resolvedType) {
10547        enforceNotIsolatedCaller("startService");
10548        // Refuse possible leaked file descriptors
10549        if (service != null && service.hasFileDescriptors() == true) {
10550            throw new IllegalArgumentException("File descriptors passed in Intent");
10551        }
10552
10553        if (DEBUG_SERVICE)
10554            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10555        synchronized(this) {
10556            final int callingPid = Binder.getCallingPid();
10557            final int callingUid = Binder.getCallingUid();
10558            final long origId = Binder.clearCallingIdentity();
10559            ComponentName res = mServices.startServiceLocked(caller, service,
10560                    resolvedType, callingPid, callingUid);
10561            Binder.restoreCallingIdentity(origId);
10562            return res;
10563        }
10564    }
10565
10566    ComponentName startServiceInPackage(int uid,
10567            Intent service, String resolvedType) {
10568        synchronized(this) {
10569            if (DEBUG_SERVICE)
10570                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10571            final long origId = Binder.clearCallingIdentity();
10572            ComponentName res = mServices.startServiceLocked(null, service,
10573                    resolvedType, -1, uid);
10574            Binder.restoreCallingIdentity(origId);
10575            return res;
10576        }
10577    }
10578
10579    public int stopService(IApplicationThread caller, Intent service,
10580            String resolvedType) {
10581        enforceNotIsolatedCaller("stopService");
10582        // Refuse possible leaked file descriptors
10583        if (service != null && service.hasFileDescriptors() == true) {
10584            throw new IllegalArgumentException("File descriptors passed in Intent");
10585        }
10586
10587        synchronized(this) {
10588            return mServices.stopServiceLocked(caller, service, resolvedType);
10589        }
10590    }
10591
10592    public IBinder peekService(Intent service, String resolvedType) {
10593        enforceNotIsolatedCaller("peekService");
10594        // Refuse possible leaked file descriptors
10595        if (service != null && service.hasFileDescriptors() == true) {
10596            throw new IllegalArgumentException("File descriptors passed in Intent");
10597        }
10598        synchronized(this) {
10599            return mServices.peekServiceLocked(service, resolvedType);
10600        }
10601    }
10602
10603    public boolean stopServiceToken(ComponentName className, IBinder token,
10604            int startId) {
10605        synchronized(this) {
10606            return mServices.stopServiceTokenLocked(className, token, startId);
10607        }
10608    }
10609
10610    public void setServiceForeground(ComponentName className, IBinder token,
10611            int id, Notification notification, boolean removeNotification) {
10612        synchronized(this) {
10613            mServices.setServiceForegroundLocked(className, token, id, notification,
10614                    removeNotification);
10615        }
10616    }
10617
10618    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10619            String className, int flags) {
10620        boolean result = false;
10621        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10622            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10623                if (ActivityManager.checkUidPermission(
10624                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10625                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10626                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10627                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10628                            + " requests FLAG_SINGLE_USER, but app does not hold "
10629                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10630                    Slog.w(TAG, msg);
10631                    throw new SecurityException(msg);
10632                }
10633                result = true;
10634            }
10635        } else if (componentProcessName == aInfo.packageName) {
10636            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10637        } else if ("system".equals(componentProcessName)) {
10638            result = true;
10639        }
10640        if (DEBUG_MU) {
10641            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10642                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10643        }
10644        return result;
10645    }
10646
10647    public int bindService(IApplicationThread caller, IBinder token,
10648            Intent service, String resolvedType,
10649            IServiceConnection connection, int flags, int userId) {
10650        enforceNotIsolatedCaller("bindService");
10651        // Refuse possible leaked file descriptors
10652        if (service != null && service.hasFileDescriptors() == true) {
10653            throw new IllegalArgumentException("File descriptors passed in Intent");
10654        }
10655
10656        checkValidCaller(Binder.getCallingUid(), userId);
10657
10658        synchronized(this) {
10659            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10660                    connection, flags, userId);
10661        }
10662    }
10663
10664    public boolean unbindService(IServiceConnection connection) {
10665        synchronized (this) {
10666            return mServices.unbindServiceLocked(connection);
10667        }
10668    }
10669
10670    public void publishService(IBinder token, Intent intent, IBinder service) {
10671        // Refuse possible leaked file descriptors
10672        if (intent != null && intent.hasFileDescriptors() == true) {
10673            throw new IllegalArgumentException("File descriptors passed in Intent");
10674        }
10675
10676        synchronized(this) {
10677            if (!(token instanceof ServiceRecord)) {
10678                throw new IllegalArgumentException("Invalid service token");
10679            }
10680            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
10681        }
10682    }
10683
10684    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10685        // Refuse possible leaked file descriptors
10686        if (intent != null && intent.hasFileDescriptors() == true) {
10687            throw new IllegalArgumentException("File descriptors passed in Intent");
10688        }
10689
10690        synchronized(this) {
10691            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
10692        }
10693    }
10694
10695    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10696        synchronized(this) {
10697            if (!(token instanceof ServiceRecord)) {
10698                throw new IllegalArgumentException("Invalid service token");
10699            }
10700            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
10701        }
10702    }
10703
10704    // =========================================================
10705    // BACKUP AND RESTORE
10706    // =========================================================
10707
10708    // Cause the target app to be launched if necessary and its backup agent
10709    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10710    // activity manager to announce its creation.
10711    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10712        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10713        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10714
10715        synchronized(this) {
10716            // !!! TODO: currently no check here that we're already bound
10717            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10718            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10719            synchronized (stats) {
10720                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10721            }
10722
10723            // Backup agent is now in use, its package can't be stopped.
10724            try {
10725                AppGlobals.getPackageManager().setPackageStoppedState(
10726                        app.packageName, false, UserHandle.getUserId(app.uid));
10727            } catch (RemoteException e) {
10728            } catch (IllegalArgumentException e) {
10729                Slog.w(TAG, "Failed trying to unstop package "
10730                        + app.packageName + ": " + e);
10731            }
10732
10733            BackupRecord r = new BackupRecord(ss, app, backupMode);
10734            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10735                    ? new ComponentName(app.packageName, app.backupAgentName)
10736                    : new ComponentName("android", "FullBackupAgent");
10737            // startProcessLocked() returns existing proc's record if it's already running
10738            ProcessRecord proc = startProcessLocked(app.processName, app,
10739                    false, 0, "backup", hostingName, false, false);
10740            if (proc == null) {
10741                Slog.e(TAG, "Unable to start backup agent process " + r);
10742                return false;
10743            }
10744
10745            r.app = proc;
10746            mBackupTarget = r;
10747            mBackupAppName = app.packageName;
10748
10749            // Try not to kill the process during backup
10750            updateOomAdjLocked(proc);
10751
10752            // If the process is already attached, schedule the creation of the backup agent now.
10753            // If it is not yet live, this will be done when it attaches to the framework.
10754            if (proc.thread != null) {
10755                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
10756                try {
10757                    proc.thread.scheduleCreateBackupAgent(app,
10758                            compatibilityInfoForPackageLocked(app), backupMode);
10759                } catch (RemoteException e) {
10760                    // Will time out on the backup manager side
10761                }
10762            } else {
10763                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
10764            }
10765            // Invariants: at this point, the target app process exists and the application
10766            // is either already running or in the process of coming up.  mBackupTarget and
10767            // mBackupAppName describe the app, so that when it binds back to the AM we
10768            // know that it's scheduled for a backup-agent operation.
10769        }
10770
10771        return true;
10772    }
10773
10774    // A backup agent has just come up
10775    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10776        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
10777                + " = " + agent);
10778
10779        synchronized(this) {
10780            if (!agentPackageName.equals(mBackupAppName)) {
10781                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10782                return;
10783            }
10784        }
10785
10786        long oldIdent = Binder.clearCallingIdentity();
10787        try {
10788            IBackupManager bm = IBackupManager.Stub.asInterface(
10789                    ServiceManager.getService(Context.BACKUP_SERVICE));
10790            bm.agentConnected(agentPackageName, agent);
10791        } catch (RemoteException e) {
10792            // can't happen; the backup manager service is local
10793        } catch (Exception e) {
10794            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10795            e.printStackTrace();
10796        } finally {
10797            Binder.restoreCallingIdentity(oldIdent);
10798        }
10799    }
10800
10801    // done with this agent
10802    public void unbindBackupAgent(ApplicationInfo appInfo) {
10803        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
10804        if (appInfo == null) {
10805            Slog.w(TAG, "unbind backup agent for null app");
10806            return;
10807        }
10808
10809        synchronized(this) {
10810            if (mBackupAppName == null) {
10811                Slog.w(TAG, "Unbinding backup agent with no active backup");
10812                return;
10813            }
10814
10815            if (!mBackupAppName.equals(appInfo.packageName)) {
10816                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
10817                return;
10818            }
10819
10820            ProcessRecord proc = mBackupTarget.app;
10821            mBackupTarget = null;
10822            mBackupAppName = null;
10823
10824            // Not backing this app up any more; reset its OOM adjustment
10825            updateOomAdjLocked(proc);
10826
10827            // If the app crashed during backup, 'thread' will be null here
10828            if (proc.thread != null) {
10829                try {
10830                    proc.thread.scheduleDestroyBackupAgent(appInfo,
10831                            compatibilityInfoForPackageLocked(appInfo));
10832                } catch (Exception e) {
10833                    Slog.e(TAG, "Exception when unbinding backup agent:");
10834                    e.printStackTrace();
10835                }
10836            }
10837        }
10838    }
10839    // =========================================================
10840    // BROADCASTS
10841    // =========================================================
10842
10843    private final List getStickiesLocked(String action, IntentFilter filter,
10844            List cur) {
10845        final ContentResolver resolver = mContext.getContentResolver();
10846        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10847        if (list == null) {
10848            return cur;
10849        }
10850        int N = list.size();
10851        for (int i=0; i<N; i++) {
10852            Intent intent = list.get(i);
10853            if (filter.match(resolver, intent, true, TAG) >= 0) {
10854                if (cur == null) {
10855                    cur = new ArrayList<Intent>();
10856                }
10857                cur.add(intent);
10858            }
10859        }
10860        return cur;
10861    }
10862
10863    boolean isPendingBroadcastProcessLocked(int pid) {
10864        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
10865                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
10866    }
10867
10868    void skipPendingBroadcastLocked(int pid) {
10869            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
10870            for (BroadcastQueue queue : mBroadcastQueues) {
10871                queue.skipPendingBroadcastLocked(pid);
10872            }
10873    }
10874
10875    // The app just attached; send any pending broadcasts that it should receive
10876    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
10877        boolean didSomething = false;
10878        for (BroadcastQueue queue : mBroadcastQueues) {
10879            didSomething |= queue.sendPendingBroadcastsLocked(app);
10880        }
10881        return didSomething;
10882    }
10883
10884    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
10885            IIntentReceiver receiver, IntentFilter filter, String permission) {
10886        enforceNotIsolatedCaller("registerReceiver");
10887        int callingUid;
10888        synchronized(this) {
10889            ProcessRecord callerApp = null;
10890            if (caller != null) {
10891                callerApp = getRecordForAppLocked(caller);
10892                if (callerApp == null) {
10893                    throw new SecurityException(
10894                            "Unable to find app for caller " + caller
10895                            + " (pid=" + Binder.getCallingPid()
10896                            + ") when registering receiver " + receiver);
10897                }
10898                if (callerApp.info.uid != Process.SYSTEM_UID &&
10899                        !callerApp.pkgList.contains(callerPackage)) {
10900                    throw new SecurityException("Given caller package " + callerPackage
10901                            + " is not running in process " + callerApp);
10902                }
10903                callingUid = callerApp.info.uid;
10904            } else {
10905                callerPackage = null;
10906                callingUid = Binder.getCallingUid();
10907            }
10908
10909            List allSticky = null;
10910
10911            // Look for any matching sticky broadcasts...
10912            Iterator actions = filter.actionsIterator();
10913            if (actions != null) {
10914                while (actions.hasNext()) {
10915                    String action = (String)actions.next();
10916                    allSticky = getStickiesLocked(action, filter, allSticky);
10917                }
10918            } else {
10919                allSticky = getStickiesLocked(null, filter, allSticky);
10920            }
10921
10922            // The first sticky in the list is returned directly back to
10923            // the client.
10924            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10925
10926            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
10927                    + ": " + sticky);
10928
10929            if (receiver == null) {
10930                return sticky;
10931            }
10932
10933            ReceiverList rl
10934                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10935            if (rl == null) {
10936                rl = new ReceiverList(this, callerApp,
10937                        Binder.getCallingPid(),
10938                        Binder.getCallingUid(), receiver);
10939                if (rl.app != null) {
10940                    rl.app.receivers.add(rl);
10941                } else {
10942                    try {
10943                        receiver.asBinder().linkToDeath(rl, 0);
10944                    } catch (RemoteException e) {
10945                        return sticky;
10946                    }
10947                    rl.linkedToDeath = true;
10948                }
10949                mRegisteredReceivers.put(receiver.asBinder(), rl);
10950            }
10951            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
10952                    permission, callingUid);
10953            rl.add(bf);
10954            if (!bf.debugCheck()) {
10955                Slog.w(TAG, "==> For Dynamic broadast");
10956            }
10957            mReceiverResolver.addFilter(bf);
10958
10959            // Enqueue broadcasts for all existing stickies that match
10960            // this filter.
10961            if (allSticky != null) {
10962                ArrayList receivers = new ArrayList();
10963                receivers.add(bf);
10964
10965                int N = allSticky.size();
10966                for (int i=0; i<N; i++) {
10967                    Intent intent = (Intent)allSticky.get(i);
10968                    BroadcastQueue queue = broadcastQueueForIntent(intent);
10969                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
10970                            null, -1, -1, null, receivers, null, 0, null, null,
10971                            false, true, true, false);
10972                    queue.enqueueParallelBroadcastLocked(r);
10973                    queue.scheduleBroadcastsLocked();
10974                }
10975            }
10976
10977            return sticky;
10978        }
10979    }
10980
10981    public void unregisterReceiver(IIntentReceiver receiver) {
10982        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
10983
10984        final long origId = Binder.clearCallingIdentity();
10985        try {
10986            boolean doTrim = false;
10987
10988            synchronized(this) {
10989                ReceiverList rl
10990                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10991                if (rl != null) {
10992                    if (rl.curBroadcast != null) {
10993                        BroadcastRecord r = rl.curBroadcast;
10994                        final boolean doNext = finishReceiverLocked(
10995                                receiver.asBinder(), r.resultCode, r.resultData,
10996                                r.resultExtras, r.resultAbort, true);
10997                        if (doNext) {
10998                            doTrim = true;
10999                            r.queue.processNextBroadcast(false);
11000                        }
11001                    }
11002
11003                    if (rl.app != null) {
11004                        rl.app.receivers.remove(rl);
11005                    }
11006                    removeReceiverLocked(rl);
11007                    if (rl.linkedToDeath) {
11008                        rl.linkedToDeath = false;
11009                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11010                    }
11011                }
11012            }
11013
11014            // If we actually concluded any broadcasts, we might now be able
11015            // to trim the recipients' apps from our working set
11016            if (doTrim) {
11017                trimApplications();
11018                return;
11019            }
11020
11021        } finally {
11022            Binder.restoreCallingIdentity(origId);
11023        }
11024    }
11025
11026    void removeReceiverLocked(ReceiverList rl) {
11027        mRegisteredReceivers.remove(rl.receiver.asBinder());
11028        int N = rl.size();
11029        for (int i=0; i<N; i++) {
11030            mReceiverResolver.removeFilter(rl.get(i));
11031        }
11032    }
11033
11034    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11035        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11036            ProcessRecord r = mLruProcesses.get(i);
11037            if (r.thread != null) {
11038                try {
11039                    r.thread.dispatchPackageBroadcast(cmd, packages);
11040                } catch (RemoteException ex) {
11041                }
11042            }
11043        }
11044    }
11045
11046    private final int broadcastIntentLocked(ProcessRecord callerApp,
11047            String callerPackage, Intent intent, String resolvedType,
11048            IIntentReceiver resultTo, int resultCode, String resultData,
11049            Bundle map, String requiredPermission,
11050            boolean ordered, boolean sticky, int callingPid, int callingUid,
11051            int userId) {
11052        intent = new Intent(intent);
11053
11054        // By default broadcasts do not go to stopped apps.
11055        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11056
11057        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11058            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11059            + " ordered=" + ordered + " userid=" + userId);
11060        if ((resultTo != null) && !ordered) {
11061            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11062        }
11063
11064        boolean onlySendToCaller = false;
11065
11066        // If the caller is trying to send this broadcast to a different
11067        // user, verify that is allowed.
11068        if (UserHandle.getUserId(callingUid) != userId) {
11069            if (checkComponentPermission(
11070                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
11071                    callingPid, callingUid, -1, true)
11072                    != PackageManager.PERMISSION_GRANTED) {
11073                if (checkComponentPermission(
11074                        android.Manifest.permission.INTERACT_ACROSS_USERS,
11075                        callingPid, callingUid, -1, true)
11076                        == PackageManager.PERMISSION_GRANTED) {
11077                    onlySendToCaller = true;
11078                } else {
11079                    String msg = "Permission Denial: " + intent.getAction()
11080                            + " broadcast from " + callerPackage
11081                            + " asks to send as user " + userId
11082                            + " but is calling from user " + UserHandle.getUserId(callingUid)
11083                            + "; this requires "
11084                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
11085                    Slog.w(TAG, msg);
11086                    throw new SecurityException(msg);
11087                }
11088            }
11089        }
11090
11091        // Handle special intents: if this broadcast is from the package
11092        // manager about a package being removed, we need to remove all of
11093        // its activities from the history stack.
11094        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11095                intent.getAction());
11096        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11097                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11098                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11099                || uidRemoved) {
11100            if (checkComponentPermission(
11101                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11102                    callingPid, callingUid, -1, true)
11103                    == PackageManager.PERMISSION_GRANTED) {
11104                if (uidRemoved) {
11105                    final Bundle intentExtras = intent.getExtras();
11106                    final int uid = intentExtras != null
11107                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11108                    if (uid >= 0) {
11109                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11110                        synchronized (bs) {
11111                            bs.removeUidStatsLocked(uid);
11112                        }
11113                    }
11114                } else {
11115                    // If resources are unvailble just force stop all
11116                    // those packages and flush the attribute cache as well.
11117                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11118                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11119                        if (list != null && (list.length > 0)) {
11120                            for (String pkg : list) {
11121                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11122                            }
11123                            sendPackageBroadcastLocked(
11124                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
11125                        }
11126                    } else {
11127                        Uri data = intent.getData();
11128                        String ssp;
11129                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11130                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11131                                forceStopPackageLocked(ssp,
11132                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11133                                        false, userId);
11134                            }
11135                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11136                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11137                                        new String[] {ssp});
11138                            }
11139                        }
11140                    }
11141                }
11142            } else {
11143                String msg = "Permission Denial: " + intent.getAction()
11144                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11145                        + ", uid=" + callingUid + ")"
11146                        + " requires "
11147                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11148                Slog.w(TAG, msg);
11149                throw new SecurityException(msg);
11150            }
11151
11152        // Special case for adding a package: by default turn on compatibility
11153        // mode.
11154        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11155            Uri data = intent.getData();
11156            String ssp;
11157            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11158                mCompatModePackages.handlePackageAddedLocked(ssp,
11159                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11160            }
11161        }
11162
11163        /*
11164         * If this is the time zone changed action, queue up a message that will reset the timezone
11165         * of all currently running processes. This message will get queued up before the broadcast
11166         * happens.
11167         */
11168        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11169            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11170        }
11171
11172        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11173            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11174        }
11175
11176        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11177            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11178            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11179        }
11180
11181        /*
11182         * Prevent non-system code (defined here to be non-persistent
11183         * processes) from sending protected broadcasts.
11184         */
11185        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11186            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11187            callingUid == 0) {
11188            // Always okay.
11189        } else if (callerApp == null || !callerApp.persistent) {
11190            try {
11191                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11192                        intent.getAction())) {
11193                    String msg = "Permission Denial: not allowed to send broadcast "
11194                            + intent.getAction() + " from pid="
11195                            + callingPid + ", uid=" + callingUid;
11196                    Slog.w(TAG, msg);
11197                    throw new SecurityException(msg);
11198                }
11199            } catch (RemoteException e) {
11200                Slog.w(TAG, "Remote exception", e);
11201                return ActivityManager.BROADCAST_SUCCESS;
11202            }
11203        }
11204
11205        // Add to the sticky list if requested.
11206        if (sticky) {
11207            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11208                    callingPid, callingUid)
11209                    != PackageManager.PERMISSION_GRANTED) {
11210                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11211                        + callingPid + ", uid=" + callingUid
11212                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11213                Slog.w(TAG, msg);
11214                throw new SecurityException(msg);
11215            }
11216            if (requiredPermission != null) {
11217                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11218                        + " and enforce permission " + requiredPermission);
11219                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11220            }
11221            if (intent.getComponent() != null) {
11222                throw new SecurityException(
11223                        "Sticky broadcasts can't target a specific component");
11224            }
11225            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11226            if (list == null) {
11227                list = new ArrayList<Intent>();
11228                mStickyBroadcasts.put(intent.getAction(), list);
11229            }
11230            int N = list.size();
11231            int i;
11232            for (i=0; i<N; i++) {
11233                if (intent.filterEquals(list.get(i))) {
11234                    // This sticky already exists, replace it.
11235                    list.set(i, new Intent(intent));
11236                    break;
11237                }
11238            }
11239            if (i >= N) {
11240                list.add(new Intent(intent));
11241            }
11242        }
11243
11244        // Figure out who all will receive this broadcast.
11245        List receivers = null;
11246        List<BroadcastFilter> registeredReceivers = null;
11247        try {
11248            // Need to resolve the intent to interested receivers...
11249            if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11250                     == 0) {
11251                receivers = AppGlobals.getPackageManager().queryIntentReceivers(
11252                        intent, resolvedType, STOCK_PM_FLAGS, userId);
11253            }
11254            if (intent.getComponent() == null) {
11255                registeredReceivers = mReceiverResolver.queryIntent(intent,
11256                        resolvedType, false, userId);
11257            }
11258        } catch (RemoteException ex) {
11259            // pm is in same process, this will never happen.
11260        }
11261
11262        final boolean replacePending =
11263                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11264
11265        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11266                + " replacePending=" + replacePending);
11267
11268        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11269        if (!ordered && NR > 0) {
11270            // If we are not serializing this broadcast, then send the
11271            // registered receivers separately so they don't wait for the
11272            // components to be launched.
11273            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11274            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11275                    callerPackage, callingPid, callingUid, requiredPermission,
11276                    registeredReceivers, resultTo, resultCode, resultData, map,
11277                    ordered, sticky, false, onlySendToCaller);
11278            if (DEBUG_BROADCAST) Slog.v(
11279                    TAG, "Enqueueing parallel broadcast " + r);
11280            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11281            if (!replaced) {
11282                queue.enqueueParallelBroadcastLocked(r);
11283                queue.scheduleBroadcastsLocked();
11284            }
11285            registeredReceivers = null;
11286            NR = 0;
11287        }
11288
11289        // Merge into one list.
11290        int ir = 0;
11291        if (receivers != null) {
11292            // A special case for PACKAGE_ADDED: do not allow the package
11293            // being added to see this broadcast.  This prevents them from
11294            // using this as a back door to get run as soon as they are
11295            // installed.  Maybe in the future we want to have a special install
11296            // broadcast or such for apps, but we'd like to deliberately make
11297            // this decision.
11298            String skipPackages[] = null;
11299            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11300                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11301                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11302                Uri data = intent.getData();
11303                if (data != null) {
11304                    String pkgName = data.getSchemeSpecificPart();
11305                    if (pkgName != null) {
11306                        skipPackages = new String[] { pkgName };
11307                    }
11308                }
11309            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11310                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11311            }
11312            if (skipPackages != null && (skipPackages.length > 0)) {
11313                for (String skipPackage : skipPackages) {
11314                    if (skipPackage != null) {
11315                        int NT = receivers.size();
11316                        for (int it=0; it<NT; it++) {
11317                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11318                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11319                                receivers.remove(it);
11320                                it--;
11321                                NT--;
11322                            }
11323                        }
11324                    }
11325                }
11326            }
11327
11328            int NT = receivers != null ? receivers.size() : 0;
11329            int it = 0;
11330            ResolveInfo curt = null;
11331            BroadcastFilter curr = null;
11332            while (it < NT && ir < NR) {
11333                if (curt == null) {
11334                    curt = (ResolveInfo)receivers.get(it);
11335                }
11336                if (curr == null) {
11337                    curr = registeredReceivers.get(ir);
11338                }
11339                if (curr.getPriority() >= curt.priority) {
11340                    // Insert this broadcast record into the final list.
11341                    receivers.add(it, curr);
11342                    ir++;
11343                    curr = null;
11344                    it++;
11345                    NT++;
11346                } else {
11347                    // Skip to the next ResolveInfo in the final list.
11348                    it++;
11349                    curt = null;
11350                }
11351            }
11352        }
11353        while (ir < NR) {
11354            if (receivers == null) {
11355                receivers = new ArrayList();
11356            }
11357            receivers.add(registeredReceivers.get(ir));
11358            ir++;
11359        }
11360
11361        if ((receivers != null && receivers.size() > 0)
11362                || resultTo != null) {
11363            BroadcastQueue queue = broadcastQueueForIntent(intent);
11364            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11365                    callerPackage, callingPid, callingUid, requiredPermission,
11366                    receivers, resultTo, resultCode, resultData, map, ordered,
11367                    sticky, false, onlySendToCaller);
11368            if (DEBUG_BROADCAST) Slog.v(
11369                    TAG, "Enqueueing ordered broadcast " + r
11370                    + ": prev had " + queue.mOrderedBroadcasts.size());
11371            if (DEBUG_BROADCAST) {
11372                int seq = r.intent.getIntExtra("seq", -1);
11373                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11374            }
11375            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11376            if (!replaced) {
11377                queue.enqueueOrderedBroadcastLocked(r);
11378                queue.scheduleBroadcastsLocked();
11379            }
11380        }
11381
11382        return ActivityManager.BROADCAST_SUCCESS;
11383    }
11384
11385    final Intent verifyBroadcastLocked(Intent intent) {
11386        // Refuse possible leaked file descriptors
11387        if (intent != null && intent.hasFileDescriptors() == true) {
11388            throw new IllegalArgumentException("File descriptors passed in Intent");
11389        }
11390
11391        int flags = intent.getFlags();
11392
11393        if (!mProcessesReady) {
11394            // if the caller really truly claims to know what they're doing, go
11395            // ahead and allow the broadcast without launching any receivers
11396            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11397                intent = new Intent(intent);
11398                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11399            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11400                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11401                        + " before boot completion");
11402                throw new IllegalStateException("Cannot broadcast before boot completed");
11403            }
11404        }
11405
11406        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11407            throw new IllegalArgumentException(
11408                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11409        }
11410
11411        return intent;
11412    }
11413
11414    public final int broadcastIntent(IApplicationThread caller,
11415            Intent intent, String resolvedType, IIntentReceiver resultTo,
11416            int resultCode, String resultData, Bundle map,
11417            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11418        enforceNotIsolatedCaller("broadcastIntent");
11419        synchronized(this) {
11420            intent = verifyBroadcastLocked(intent);
11421
11422            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11423            final int callingPid = Binder.getCallingPid();
11424            final int callingUid = Binder.getCallingUid();
11425            final long origId = Binder.clearCallingIdentity();
11426            int res = broadcastIntentLocked(callerApp,
11427                    callerApp != null ? callerApp.info.packageName : null,
11428                    intent, resolvedType, resultTo,
11429                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11430                    callingPid, callingUid, userId);
11431            Binder.restoreCallingIdentity(origId);
11432            return res;
11433        }
11434    }
11435
11436    int broadcastIntentInPackage(String packageName, int uid,
11437            Intent intent, String resolvedType, IIntentReceiver resultTo,
11438            int resultCode, String resultData, Bundle map,
11439            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11440        synchronized(this) {
11441            intent = verifyBroadcastLocked(intent);
11442
11443            final long origId = Binder.clearCallingIdentity();
11444            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11445                    resultTo, resultCode, resultData, map, requiredPermission,
11446                    serialized, sticky, -1, uid, userId);
11447            Binder.restoreCallingIdentity(origId);
11448            return res;
11449        }
11450    }
11451
11452    // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
11453    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11454        // Refuse possible leaked file descriptors
11455        if (intent != null && intent.hasFileDescriptors() == true) {
11456            throw new IllegalArgumentException("File descriptors passed in Intent");
11457        }
11458
11459        synchronized(this) {
11460            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11461                    != PackageManager.PERMISSION_GRANTED) {
11462                String msg = "Permission Denial: unbroadcastIntent() from pid="
11463                        + Binder.getCallingPid()
11464                        + ", uid=" + Binder.getCallingUid()
11465                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11466                Slog.w(TAG, msg);
11467                throw new SecurityException(msg);
11468            }
11469            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11470            if (list != null) {
11471                int N = list.size();
11472                int i;
11473                for (i=0; i<N; i++) {
11474                    if (intent.filterEquals(list.get(i))) {
11475                        list.remove(i);
11476                        break;
11477                    }
11478                }
11479            }
11480        }
11481    }
11482
11483    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11484            String resultData, Bundle resultExtras, boolean resultAbort,
11485            boolean explicit) {
11486        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11487        if (r == null) {
11488            Slog.w(TAG, "finishReceiver called but not found on queue");
11489            return false;
11490        }
11491
11492        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11493                explicit);
11494    }
11495
11496    public void finishReceiver(IBinder who, int resultCode, String resultData,
11497            Bundle resultExtras, boolean resultAbort) {
11498        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11499
11500        // Refuse possible leaked file descriptors
11501        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11502            throw new IllegalArgumentException("File descriptors passed in Bundle");
11503        }
11504
11505        final long origId = Binder.clearCallingIdentity();
11506        try {
11507            boolean doNext = false;
11508            BroadcastRecord r = null;
11509
11510            synchronized(this) {
11511                r = broadcastRecordForReceiverLocked(who);
11512                if (r != null) {
11513                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11514                        resultData, resultExtras, resultAbort, true);
11515                }
11516            }
11517
11518            if (doNext) {
11519                r.queue.processNextBroadcast(false);
11520            }
11521            trimApplications();
11522        } finally {
11523            Binder.restoreCallingIdentity(origId);
11524        }
11525    }
11526
11527    // =========================================================
11528    // INSTRUMENTATION
11529    // =========================================================
11530
11531    public boolean startInstrumentation(ComponentName className,
11532            String profileFile, int flags, Bundle arguments,
11533            IInstrumentationWatcher watcher) {
11534        enforceNotIsolatedCaller("startInstrumentation");
11535        // Refuse possible leaked file descriptors
11536        if (arguments != null && arguments.hasFileDescriptors()) {
11537            throw new IllegalArgumentException("File descriptors passed in Bundle");
11538        }
11539
11540        synchronized(this) {
11541            InstrumentationInfo ii = null;
11542            ApplicationInfo ai = null;
11543            try {
11544                ii = mContext.getPackageManager().getInstrumentationInfo(
11545                    className, STOCK_PM_FLAGS);
11546                ai = mContext.getPackageManager().getApplicationInfo(
11547                        ii.targetPackage, STOCK_PM_FLAGS);
11548            } catch (PackageManager.NameNotFoundException e) {
11549            }
11550            if (ii == null) {
11551                reportStartInstrumentationFailure(watcher, className,
11552                        "Unable to find instrumentation info for: " + className);
11553                return false;
11554            }
11555            if (ai == null) {
11556                reportStartInstrumentationFailure(watcher, className,
11557                        "Unable to find instrumentation target package: " + ii.targetPackage);
11558                return false;
11559            }
11560
11561            int match = mContext.getPackageManager().checkSignatures(
11562                    ii.targetPackage, ii.packageName);
11563            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11564                String msg = "Permission Denial: starting instrumentation "
11565                        + className + " from pid="
11566                        + Binder.getCallingPid()
11567                        + ", uid=" + Binder.getCallingPid()
11568                        + " not allowed because package " + ii.packageName
11569                        + " does not have a signature matching the target "
11570                        + ii.targetPackage;
11571                reportStartInstrumentationFailure(watcher, className, msg);
11572                throw new SecurityException(msg);
11573            }
11574
11575            int userId = UserHandle.getCallingUserId();
11576            final long origId = Binder.clearCallingIdentity();
11577            // Instrumentation can kill and relaunch even persistent processes
11578            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
11579            ProcessRecord app = addAppLocked(ai, false);
11580            app.instrumentationClass = className;
11581            app.instrumentationInfo = ai;
11582            app.instrumentationProfileFile = profileFile;
11583            app.instrumentationArguments = arguments;
11584            app.instrumentationWatcher = watcher;
11585            app.instrumentationResultClass = className;
11586            Binder.restoreCallingIdentity(origId);
11587        }
11588
11589        return true;
11590    }
11591
11592    /**
11593     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11594     * error to the logs, but if somebody is watching, send the report there too.  This enables
11595     * the "am" command to report errors with more information.
11596     *
11597     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11598     * @param cn The component name of the instrumentation.
11599     * @param report The error report.
11600     */
11601    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11602            ComponentName cn, String report) {
11603        Slog.w(TAG, report);
11604        try {
11605            if (watcher != null) {
11606                Bundle results = new Bundle();
11607                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11608                results.putString("Error", report);
11609                watcher.instrumentationStatus(cn, -1, results);
11610            }
11611        } catch (RemoteException e) {
11612            Slog.w(TAG, e);
11613        }
11614    }
11615
11616    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11617        if (app.instrumentationWatcher != null) {
11618            try {
11619                // NOTE:  IInstrumentationWatcher *must* be oneway here
11620                app.instrumentationWatcher.instrumentationFinished(
11621                    app.instrumentationClass,
11622                    resultCode,
11623                    results);
11624            } catch (RemoteException e) {
11625            }
11626        }
11627        app.instrumentationWatcher = null;
11628        app.instrumentationClass = null;
11629        app.instrumentationInfo = null;
11630        app.instrumentationProfileFile = null;
11631        app.instrumentationArguments = null;
11632
11633        forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId);
11634    }
11635
11636    public void finishInstrumentation(IApplicationThread target,
11637            int resultCode, Bundle results) {
11638        int userId = UserHandle.getCallingUserId();
11639        // Refuse possible leaked file descriptors
11640        if (results != null && results.hasFileDescriptors()) {
11641            throw new IllegalArgumentException("File descriptors passed in Intent");
11642        }
11643
11644        synchronized(this) {
11645            ProcessRecord app = getRecordForAppLocked(target);
11646            if (app == null) {
11647                Slog.w(TAG, "finishInstrumentation: no app for " + target);
11648                return;
11649            }
11650            final long origId = Binder.clearCallingIdentity();
11651            finishInstrumentationLocked(app, resultCode, results);
11652            Binder.restoreCallingIdentity(origId);
11653        }
11654    }
11655
11656    // =========================================================
11657    // CONFIGURATION
11658    // =========================================================
11659
11660    public ConfigurationInfo getDeviceConfigurationInfo() {
11661        ConfigurationInfo config = new ConfigurationInfo();
11662        synchronized (this) {
11663            config.reqTouchScreen = mConfiguration.touchscreen;
11664            config.reqKeyboardType = mConfiguration.keyboard;
11665            config.reqNavigation = mConfiguration.navigation;
11666            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11667                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
11668                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11669            }
11670            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11671                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
11672                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11673            }
11674            config.reqGlEsVersion = GL_ES_VERSION;
11675        }
11676        return config;
11677    }
11678
11679    public Configuration getConfiguration() {
11680        Configuration ci;
11681        synchronized(this) {
11682            ci = new Configuration(mConfiguration);
11683        }
11684        return ci;
11685    }
11686
11687    public void updatePersistentConfiguration(Configuration values) {
11688        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11689                "updateConfiguration()");
11690        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
11691                "updateConfiguration()");
11692        if (values == null) {
11693            throw new NullPointerException("Configuration must not be null");
11694        }
11695
11696        synchronized(this) {
11697            final long origId = Binder.clearCallingIdentity();
11698            updateConfigurationLocked(values, null, true, false);
11699            Binder.restoreCallingIdentity(origId);
11700        }
11701    }
11702
11703    public void updateConfiguration(Configuration values) {
11704        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11705                "updateConfiguration()");
11706
11707        synchronized(this) {
11708            if (values == null && mWindowManager != null) {
11709                // sentinel: fetch the current configuration from the window manager
11710                values = mWindowManager.computeNewConfiguration();
11711            }
11712
11713            if (mWindowManager != null) {
11714                mProcessList.applyDisplaySize(mWindowManager);
11715            }
11716
11717            final long origId = Binder.clearCallingIdentity();
11718            if (values != null) {
11719                Settings.System.clearConfiguration(values);
11720            }
11721            updateConfigurationLocked(values, null, false, false);
11722            Binder.restoreCallingIdentity(origId);
11723        }
11724    }
11725
11726    /**
11727     * Do either or both things: (1) change the current configuration, and (2)
11728     * make sure the given activity is running with the (now) current
11729     * configuration.  Returns true if the activity has been left running, or
11730     * false if <var>starting</var> is being destroyed to match the new
11731     * configuration.
11732     * @param persistent TODO
11733     */
11734    boolean updateConfigurationLocked(Configuration values,
11735            ActivityRecord starting, boolean persistent, boolean initLocale) {
11736        // do nothing if we are headless
11737        if (mHeadless) return true;
11738
11739        int changes = 0;
11740
11741        boolean kept = true;
11742
11743        if (values != null) {
11744            Configuration newConfig = new Configuration(mConfiguration);
11745            changes = newConfig.updateFrom(values);
11746            if (changes != 0) {
11747                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
11748                    Slog.i(TAG, "Updating configuration to: " + values);
11749                }
11750
11751                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
11752
11753                if (values.locale != null && !initLocale) {
11754                    saveLocaleLocked(values.locale,
11755                                     !values.locale.equals(mConfiguration.locale),
11756                                     values.userSetLocale);
11757                }
11758
11759                mConfigurationSeq++;
11760                if (mConfigurationSeq <= 0) {
11761                    mConfigurationSeq = 1;
11762                }
11763                newConfig.seq = mConfigurationSeq;
11764                mConfiguration = newConfig;
11765                Slog.i(TAG, "Config changed: " + newConfig);
11766
11767                final Configuration configCopy = new Configuration(mConfiguration);
11768
11769                // TODO: If our config changes, should we auto dismiss any currently
11770                // showing dialogs?
11771                mShowDialogs = shouldShowDialogs(newConfig);
11772
11773                AttributeCache ac = AttributeCache.instance();
11774                if (ac != null) {
11775                    ac.updateConfiguration(configCopy);
11776                }
11777
11778                // Make sure all resources in our process are updated
11779                // right now, so that anyone who is going to retrieve
11780                // resource values after we return will be sure to get
11781                // the new ones.  This is especially important during
11782                // boot, where the first config change needs to guarantee
11783                // all resources have that config before following boot
11784                // code is executed.
11785                mSystemThread.applyConfigurationToResources(configCopy);
11786
11787                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
11788                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11789                    msg.obj = new Configuration(configCopy);
11790                    mHandler.sendMessage(msg);
11791                }
11792
11793                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11794                    ProcessRecord app = mLruProcesses.get(i);
11795                    try {
11796                        if (app.thread != null) {
11797                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
11798                                    + app.processName + " new config " + mConfiguration);
11799                            app.thread.scheduleConfigurationChanged(configCopy);
11800                        }
11801                    } catch (Exception e) {
11802                    }
11803                }
11804                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
11805                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11806                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
11807                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11808                        null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11809                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
11810                    broadcastIntentLocked(null, null,
11811                            new Intent(Intent.ACTION_LOCALE_CHANGED),
11812                            null, null, 0, null, null,
11813                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11814                }
11815            }
11816        }
11817
11818        if (changes != 0 && starting == null) {
11819            // If the configuration changed, and the caller is not already
11820            // in the process of starting an activity, then find the top
11821            // activity to check if its configuration needs to change.
11822            starting = mMainStack.topRunningActivityLocked(null);
11823        }
11824
11825        if (starting != null) {
11826            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
11827            // And we need to make sure at this point that all other activities
11828            // are made visible with the correct configuration.
11829            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
11830        }
11831
11832        if (values != null && mWindowManager != null) {
11833            mWindowManager.setNewConfiguration(mConfiguration);
11834        }
11835
11836        return kept;
11837    }
11838
11839    /**
11840     * Decide based on the configuration whether we should shouw the ANR,
11841     * crash, etc dialogs.  The idea is that if there is no affordnace to
11842     * press the on-screen buttons, we shouldn't show the dialog.
11843     *
11844     * A thought: SystemUI might also want to get told about this, the Power
11845     * dialog / global actions also might want different behaviors.
11846     */
11847    private static final boolean shouldShowDialogs(Configuration config) {
11848        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
11849                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
11850    }
11851
11852    /**
11853     * Save the locale.  You must be inside a synchronized (this) block.
11854     */
11855    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
11856        if(isDiff) {
11857            SystemProperties.set("user.language", l.getLanguage());
11858            SystemProperties.set("user.region", l.getCountry());
11859        }
11860
11861        if(isPersist) {
11862            SystemProperties.set("persist.sys.language", l.getLanguage());
11863            SystemProperties.set("persist.sys.country", l.getCountry());
11864            SystemProperties.set("persist.sys.localevar", l.getVariant());
11865        }
11866    }
11867
11868    @Override
11869    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
11870        ActivityRecord srec = ActivityRecord.forToken(token);
11871        return srec != null && srec.task.affinity != null &&
11872                srec.task.affinity.equals(destAffinity);
11873    }
11874
11875    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
11876            Intent resultData) {
11877        ComponentName dest = destIntent.getComponent();
11878
11879        synchronized (this) {
11880            ActivityRecord srec = ActivityRecord.forToken(token);
11881            if (srec == null) {
11882                return false;
11883            }
11884            ArrayList<ActivityRecord> history = srec.stack.mHistory;
11885            final int start = history.indexOf(srec);
11886            if (start < 0) {
11887                // Current activity is not in history stack; do nothing.
11888                return false;
11889            }
11890            int finishTo = start - 1;
11891            ActivityRecord parent = null;
11892            boolean foundParentInTask = false;
11893            if (dest != null) {
11894                TaskRecord tr = srec.task;
11895                for (int i = start - 1; i >= 0; i--) {
11896                    ActivityRecord r = history.get(i);
11897                    if (tr != r.task) {
11898                        // Couldn't find parent in the same task; stop at the one above this.
11899                        // (Root of current task; in-app "home" behavior)
11900                        // Always at least finish the current activity.
11901                        finishTo = Math.min(start - 1, i + 1);
11902                        parent = history.get(finishTo);
11903                        break;
11904                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
11905                            r.info.name.equals(dest.getClassName())) {
11906                        finishTo = i;
11907                        parent = r;
11908                        foundParentInTask = true;
11909                        break;
11910                    }
11911                }
11912            }
11913
11914            if (mController != null) {
11915                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
11916                if (next != null) {
11917                    // ask watcher if this is allowed
11918                    boolean resumeOK = true;
11919                    try {
11920                        resumeOK = mController.activityResuming(next.packageName);
11921                    } catch (RemoteException e) {
11922                        mController = null;
11923                    }
11924
11925                    if (!resumeOK) {
11926                        return false;
11927                    }
11928                }
11929            }
11930            final long origId = Binder.clearCallingIdentity();
11931            for (int i = start; i > finishTo; i--) {
11932                ActivityRecord r = history.get(i);
11933                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
11934                        "navigate-up");
11935                // Only return the supplied result for the first activity finished
11936                resultCode = Activity.RESULT_CANCELED;
11937                resultData = null;
11938            }
11939
11940            if (parent != null && foundParentInTask) {
11941                final int parentLaunchMode = parent.info.launchMode;
11942                final int destIntentFlags = destIntent.getFlags();
11943                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
11944                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
11945                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
11946                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
11947                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
11948                } else {
11949                    try {
11950                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
11951                                destIntent.getComponent(), 0, UserHandle.getCallingUserId());
11952                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
11953                                null, aInfo, parent.appToken, null,
11954                                0, -1, parent.launchedFromUid, 0, null, true, null);
11955                        foundParentInTask = res == ActivityManager.START_SUCCESS;
11956                    } catch (RemoteException e) {
11957                        foundParentInTask = false;
11958                    }
11959                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
11960                            resultData, "navigate-up");
11961                }
11962            }
11963            Binder.restoreCallingIdentity(origId);
11964            return foundParentInTask;
11965        }
11966    }
11967
11968    public int getLaunchedFromUid(IBinder activityToken) {
11969        ActivityRecord srec = ActivityRecord.forToken(activityToken);
11970        if (srec == null) {
11971            return -1;
11972        }
11973        return srec.launchedFromUid;
11974    }
11975
11976    // =========================================================
11977    // LIFETIME MANAGEMENT
11978    // =========================================================
11979
11980    // Returns which broadcast queue the app is the current [or imminent] receiver
11981    // on, or 'null' if the app is not an active broadcast recipient.
11982    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
11983        BroadcastRecord r = app.curReceiver;
11984        if (r != null) {
11985            return r.queue;
11986        }
11987
11988        // It's not the current receiver, but it might be starting up to become one
11989        synchronized (this) {
11990            for (BroadcastQueue queue : mBroadcastQueues) {
11991                r = queue.mPendingBroadcast;
11992                if (r != null && r.curApp == app) {
11993                    // found it; report which queue it's in
11994                    return queue;
11995                }
11996            }
11997        }
11998
11999        return null;
12000    }
12001
12002    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12003            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12004        if (mAdjSeq == app.adjSeq) {
12005            // This adjustment has already been computed.  If we are calling
12006            // from the top, we may have already computed our adjustment with
12007            // an earlier hidden adjustment that isn't really for us... if
12008            // so, use the new hidden adjustment.
12009            if (!recursed && app.hidden) {
12010                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12011                        app.hasActivities ? hiddenAdj : emptyAdj;
12012            }
12013            return app.curRawAdj;
12014        }
12015
12016        if (app.thread == null) {
12017            app.adjSeq = mAdjSeq;
12018            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12019            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12020        }
12021
12022        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12023        app.adjSource = null;
12024        app.adjTarget = null;
12025        app.empty = false;
12026        app.hidden = false;
12027
12028        final int activitiesSize = app.activities.size();
12029
12030        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12031            // The max adjustment doesn't allow this app to be anything
12032            // below foreground, so it is not worth doing work for it.
12033            app.adjType = "fixed";
12034            app.adjSeq = mAdjSeq;
12035            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12036            app.hasActivities = false;
12037            app.foregroundActivities = false;
12038            app.keeping = true;
12039            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12040            // System process can do UI, and when they do we want to have
12041            // them trim their memory after the user leaves the UI.  To
12042            // facilitate this, here we need to determine whether or not it
12043            // is currently showing UI.
12044            app.systemNoUi = true;
12045            if (app == TOP_APP) {
12046                app.systemNoUi = false;
12047                app.hasActivities = true;
12048            } else if (activitiesSize > 0) {
12049                for (int j = 0; j < activitiesSize; j++) {
12050                    final ActivityRecord r = app.activities.get(j);
12051                    if (r.visible) {
12052                        app.systemNoUi = false;
12053                    }
12054                    if (r.app == app) {
12055                        app.hasActivities = true;
12056                    }
12057                }
12058            }
12059            return (app.curAdj=app.maxAdj);
12060        }
12061
12062        app.keeping = false;
12063        app.systemNoUi = false;
12064        app.hasActivities = false;
12065
12066        // Determine the importance of the process, starting with most
12067        // important to least, and assign an appropriate OOM adjustment.
12068        int adj;
12069        int schedGroup;
12070        boolean foregroundActivities = false;
12071        boolean interesting = false;
12072        BroadcastQueue queue;
12073        if (app == TOP_APP) {
12074            // The last app on the list is the foreground app.
12075            adj = ProcessList.FOREGROUND_APP_ADJ;
12076            schedGroup = Process.THREAD_GROUP_DEFAULT;
12077            app.adjType = "top-activity";
12078            foregroundActivities = true;
12079            interesting = true;
12080            app.hasActivities = true;
12081        } else if (app.instrumentationClass != null) {
12082            // Don't want to kill running instrumentation.
12083            adj = ProcessList.FOREGROUND_APP_ADJ;
12084            schedGroup = Process.THREAD_GROUP_DEFAULT;
12085            app.adjType = "instrumentation";
12086            interesting = true;
12087        } else if ((queue = isReceivingBroadcast(app)) != null) {
12088            // An app that is currently receiving a broadcast also
12089            // counts as being in the foreground for OOM killer purposes.
12090            // It's placed in a sched group based on the nature of the
12091            // broadcast as reflected by which queue it's active in.
12092            adj = ProcessList.FOREGROUND_APP_ADJ;
12093            schedGroup = (queue == mFgBroadcastQueue)
12094                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12095            app.adjType = "broadcast";
12096        } else if (app.executingServices.size() > 0) {
12097            // An app that is currently executing a service callback also
12098            // counts as being in the foreground.
12099            adj = ProcessList.FOREGROUND_APP_ADJ;
12100            schedGroup = Process.THREAD_GROUP_DEFAULT;
12101            app.adjType = "exec-service";
12102        } else {
12103            // Assume process is hidden (has activities); we will correct
12104            // later if this is not the case.
12105            adj = hiddenAdj;
12106            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12107            app.hidden = true;
12108            app.adjType = "bg-activities";
12109        }
12110
12111        boolean hasStoppingActivities = false;
12112
12113        // Examine all activities if not already foreground.
12114        if (!foregroundActivities && activitiesSize > 0) {
12115            for (int j = 0; j < activitiesSize; j++) {
12116                final ActivityRecord r = app.activities.get(j);
12117                if (r.visible) {
12118                    // App has a visible activity; only upgrade adjustment.
12119                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12120                        adj = ProcessList.VISIBLE_APP_ADJ;
12121                        app.adjType = "visible";
12122                    }
12123                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12124                    app.hidden = false;
12125                    app.hasActivities = true;
12126                    foregroundActivities = true;
12127                    break;
12128                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12129                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12130                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12131                        app.adjType = "pausing";
12132                    }
12133                    app.hidden = false;
12134                    foregroundActivities = true;
12135                } else if (r.state == ActivityState.STOPPING) {
12136                    // We will apply the actual adjustment later, because
12137                    // we want to allow this process to immediately go through
12138                    // any memory trimming that is in effect.
12139                    app.hidden = false;
12140                    foregroundActivities = true;
12141                    hasStoppingActivities = true;
12142                }
12143                if (r.app == app) {
12144                    app.hasActivities = true;
12145                }
12146            }
12147        }
12148
12149        if (adj == hiddenAdj && !app.hasActivities) {
12150            // Whoops, this process is completely empty as far as we know
12151            // at this point.
12152            adj = emptyAdj;
12153            app.empty = true;
12154            app.adjType = "bg-empty";
12155        }
12156
12157        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12158            if (app.foregroundServices) {
12159                // The user is aware of this app, so make it visible.
12160                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12161                app.hidden = false;
12162                app.adjType = "foreground-service";
12163                schedGroup = Process.THREAD_GROUP_DEFAULT;
12164            } else if (app.forcingToForeground != null) {
12165                // The user is aware of this app, so make it visible.
12166                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12167                app.hidden = false;
12168                app.adjType = "force-foreground";
12169                app.adjSource = app.forcingToForeground;
12170                schedGroup = Process.THREAD_GROUP_DEFAULT;
12171            }
12172        }
12173
12174        if (app.foregroundServices) {
12175            interesting = true;
12176        }
12177
12178        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12179            // We don't want to kill the current heavy-weight process.
12180            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12181            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12182            app.hidden = false;
12183            app.adjType = "heavy";
12184        }
12185
12186        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12187            // This process is hosting what we currently consider to be the
12188            // home app, so we don't want to let it go into the background.
12189            adj = ProcessList.HOME_APP_ADJ;
12190            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12191            app.hidden = false;
12192            app.adjType = "home";
12193        }
12194
12195        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12196                && app.activities.size() > 0) {
12197            // This was the previous process that showed UI to the user.
12198            // We want to try to keep it around more aggressively, to give
12199            // a good experience around switching between two apps.
12200            adj = ProcessList.PREVIOUS_APP_ADJ;
12201            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12202            app.hidden = false;
12203            app.adjType = "previous";
12204        }
12205
12206        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12207                + " reason=" + app.adjType);
12208
12209        // By default, we use the computed adjustment.  It may be changed if
12210        // there are applications dependent on our services or providers, but
12211        // this gives us a baseline and makes sure we don't get into an
12212        // infinite recursion.
12213        app.adjSeq = mAdjSeq;
12214        app.curRawAdj = app.nonStoppingAdj = adj;
12215
12216        if (mBackupTarget != null && app == mBackupTarget.app) {
12217            // If possible we want to avoid killing apps while they're being backed up
12218            if (adj > ProcessList.BACKUP_APP_ADJ) {
12219                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12220                adj = ProcessList.BACKUP_APP_ADJ;
12221                app.adjType = "backup";
12222                app.hidden = false;
12223            }
12224        }
12225
12226        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12227                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12228            final long now = SystemClock.uptimeMillis();
12229            // This process is more important if the top activity is
12230            // bound to the service.
12231            Iterator<ServiceRecord> jt = app.services.iterator();
12232            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12233                ServiceRecord s = jt.next();
12234                if (s.startRequested) {
12235                    if (app.hasShownUi && app != mHomeProcess) {
12236                        // If this process has shown some UI, let it immediately
12237                        // go to the LRU list because it may be pretty heavy with
12238                        // UI stuff.  We'll tag it with a label just to help
12239                        // debug and understand what is going on.
12240                        if (adj > ProcessList.SERVICE_ADJ) {
12241                            app.adjType = "started-bg-ui-services";
12242                        }
12243                    } else {
12244                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12245                            // This service has seen some activity within
12246                            // recent memory, so we will keep its process ahead
12247                            // of the background processes.
12248                            if (adj > ProcessList.SERVICE_ADJ) {
12249                                adj = ProcessList.SERVICE_ADJ;
12250                                app.adjType = "started-services";
12251                                app.hidden = false;
12252                            }
12253                        }
12254                        // If we have let the service slide into the background
12255                        // state, still have some text describing what it is doing
12256                        // even though the service no longer has an impact.
12257                        if (adj > ProcessList.SERVICE_ADJ) {
12258                            app.adjType = "started-bg-services";
12259                        }
12260                    }
12261                    // Don't kill this process because it is doing work; it
12262                    // has said it is doing work.
12263                    app.keeping = true;
12264                }
12265                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12266                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12267                    Iterator<ArrayList<ConnectionRecord>> kt
12268                            = s.connections.values().iterator();
12269                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12270                        ArrayList<ConnectionRecord> clist = kt.next();
12271                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12272                            // XXX should compute this based on the max of
12273                            // all connected clients.
12274                            ConnectionRecord cr = clist.get(i);
12275                            if (cr.binding.client == app) {
12276                                // Binding to ourself is not interesting.
12277                                continue;
12278                            }
12279                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12280                                ProcessRecord client = cr.binding.client;
12281                                int clientAdj = adj;
12282                                int myHiddenAdj = hiddenAdj;
12283                                if (myHiddenAdj > client.hiddenAdj) {
12284                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12285                                        myHiddenAdj = client.hiddenAdj;
12286                                    } else {
12287                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12288                                    }
12289                                }
12290                                int myEmptyAdj = emptyAdj;
12291                                if (myEmptyAdj > client.emptyAdj) {
12292                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12293                                        myEmptyAdj = client.emptyAdj;
12294                                    } else {
12295                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12296                                    }
12297                                }
12298                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12299                                        myEmptyAdj, TOP_APP, true, doingAll);
12300                                String adjType = null;
12301                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12302                                    // Not doing bind OOM management, so treat
12303                                    // this guy more like a started service.
12304                                    if (app.hasShownUi && app != mHomeProcess) {
12305                                        // If this process has shown some UI, let it immediately
12306                                        // go to the LRU list because it may be pretty heavy with
12307                                        // UI stuff.  We'll tag it with a label just to help
12308                                        // debug and understand what is going on.
12309                                        if (adj > clientAdj) {
12310                                            adjType = "bound-bg-ui-services";
12311                                        }
12312                                        app.hidden = false;
12313                                        clientAdj = adj;
12314                                    } else {
12315                                        if (now >= (s.lastActivity
12316                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12317                                            // This service has not seen activity within
12318                                            // recent memory, so allow it to drop to the
12319                                            // LRU list if there is no other reason to keep
12320                                            // it around.  We'll also tag it with a label just
12321                                            // to help debug and undertand what is going on.
12322                                            if (adj > clientAdj) {
12323                                                adjType = "bound-bg-services";
12324                                            }
12325                                            clientAdj = adj;
12326                                        }
12327                                    }
12328                                }
12329                                if (adj > clientAdj) {
12330                                    // If this process has recently shown UI, and
12331                                    // the process that is binding to it is less
12332                                    // important than being visible, then we don't
12333                                    // care about the binding as much as we care
12334                                    // about letting this process get into the LRU
12335                                    // list to be killed and restarted if needed for
12336                                    // memory.
12337                                    if (app.hasShownUi && app != mHomeProcess
12338                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12339                                        adjType = "bound-bg-ui-services";
12340                                    } else {
12341                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12342                                                |Context.BIND_IMPORTANT)) != 0) {
12343                                            adj = clientAdj;
12344                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12345                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12346                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12347                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12348                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12349                                            adj = clientAdj;
12350                                        } else {
12351                                            app.pendingUiClean = true;
12352                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12353                                                adj = ProcessList.VISIBLE_APP_ADJ;
12354                                            }
12355                                        }
12356                                        if (!client.hidden) {
12357                                            app.hidden = false;
12358                                        }
12359                                        if (client.keeping) {
12360                                            app.keeping = true;
12361                                        }
12362                                        adjType = "service";
12363                                    }
12364                                }
12365                                if (adjType != null) {
12366                                    app.adjType = adjType;
12367                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12368                                            .REASON_SERVICE_IN_USE;
12369                                    app.adjSource = cr.binding.client;
12370                                    app.adjSourceOom = clientAdj;
12371                                    app.adjTarget = s.name;
12372                                }
12373                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12374                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12375                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12376                                    }
12377                                }
12378                            }
12379                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12380                                ActivityRecord a = cr.activity;
12381                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12382                                        (a.visible || a.state == ActivityState.RESUMED
12383                                         || a.state == ActivityState.PAUSING)) {
12384                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12385                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12386                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12387                                    }
12388                                    app.hidden = false;
12389                                    app.adjType = "service";
12390                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12391                                            .REASON_SERVICE_IN_USE;
12392                                    app.adjSource = a;
12393                                    app.adjSourceOom = adj;
12394                                    app.adjTarget = s.name;
12395                                }
12396                            }
12397                        }
12398                    }
12399                }
12400            }
12401
12402            // Finally, if this process has active services running in it, we
12403            // would like to avoid killing it unless it would prevent the current
12404            // application from running.  By default we put the process in
12405            // with the rest of the background processes; as we scan through
12406            // its services we may bump it up from there.
12407            if (adj > hiddenAdj) {
12408                adj = hiddenAdj;
12409                app.hidden = false;
12410                app.adjType = "bg-services";
12411            }
12412        }
12413
12414        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12415                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12416            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12417            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12418                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12419                ContentProviderRecord cpr = jt.next();
12420                for (int i = cpr.connections.size()-1;
12421                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12422                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12423                        i--) {
12424                    ContentProviderConnection conn = cpr.connections.get(i);
12425                    ProcessRecord client = conn.client;
12426                    if (client == app) {
12427                        // Being our own client is not interesting.
12428                        continue;
12429                    }
12430                    int myHiddenAdj = hiddenAdj;
12431                    if (myHiddenAdj > client.hiddenAdj) {
12432                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12433                            myHiddenAdj = client.hiddenAdj;
12434                        } else {
12435                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12436                        }
12437                    }
12438                    int myEmptyAdj = emptyAdj;
12439                    if (myEmptyAdj > client.emptyAdj) {
12440                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12441                            myEmptyAdj = client.emptyAdj;
12442                        } else {
12443                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12444                        }
12445                    }
12446                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12447                            myEmptyAdj, TOP_APP, true, doingAll);
12448                    if (adj > clientAdj) {
12449                        if (app.hasShownUi && app != mHomeProcess
12450                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12451                            app.adjType = "bg-ui-provider";
12452                        } else {
12453                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12454                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12455                            app.adjType = "provider";
12456                        }
12457                        if (!client.hidden) {
12458                            app.hidden = false;
12459                        }
12460                        if (client.keeping) {
12461                            app.keeping = true;
12462                        }
12463                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12464                                .REASON_PROVIDER_IN_USE;
12465                        app.adjSource = client;
12466                        app.adjSourceOom = clientAdj;
12467                        app.adjTarget = cpr.name;
12468                    }
12469                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12470                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12471                    }
12472                }
12473                // If the provider has external (non-framework) process
12474                // dependencies, ensure that its adjustment is at least
12475                // FOREGROUND_APP_ADJ.
12476                if (cpr.hasExternalProcessHandles()) {
12477                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12478                        adj = ProcessList.FOREGROUND_APP_ADJ;
12479                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12480                        app.hidden = false;
12481                        app.keeping = true;
12482                        app.adjType = "provider";
12483                        app.adjTarget = cpr.name;
12484                    }
12485                }
12486            }
12487        }
12488
12489        if (adj == ProcessList.SERVICE_ADJ) {
12490            if (doingAll) {
12491                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12492                mNewNumServiceProcs++;
12493            }
12494            if (app.serviceb) {
12495                adj = ProcessList.SERVICE_B_ADJ;
12496            }
12497        } else {
12498            app.serviceb = false;
12499        }
12500
12501        app.nonStoppingAdj = adj;
12502
12503        if (hasStoppingActivities) {
12504            // Only upgrade adjustment.
12505            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12506                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12507                app.adjType = "stopping";
12508            }
12509        }
12510
12511        app.curRawAdj = adj;
12512
12513        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12514        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12515        if (adj > app.maxAdj) {
12516            adj = app.maxAdj;
12517            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12518                schedGroup = Process.THREAD_GROUP_DEFAULT;
12519            }
12520        }
12521        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12522            app.keeping = true;
12523        }
12524
12525        if (app.hasAboveClient) {
12526            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12527            // then we need to drop its adjustment to be lower than the service's
12528            // in order to honor the request.  We want to drop it by one adjustment
12529            // level...  but there is special meaning applied to various levels so
12530            // we will skip some of them.
12531            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12532                // System process will not get dropped, ever
12533            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12534                adj = ProcessList.VISIBLE_APP_ADJ;
12535            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12536                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12537            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12538                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12539            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12540                adj++;
12541            }
12542        }
12543
12544        int importance = app.memImportance;
12545        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12546            app.curAdj = adj;
12547            app.curSchedGroup = schedGroup;
12548            if (!interesting) {
12549                // For this reporting, if there is not something explicitly
12550                // interesting in this process then we will push it to the
12551                // background importance.
12552                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12553            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12554                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12555            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12556                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12557            } else if (adj >= ProcessList.HOME_APP_ADJ) {
12558                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12559            } else if (adj >= ProcessList.SERVICE_ADJ) {
12560                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12561            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12562                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12563            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12564                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12565            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12566                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12567            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12568                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12569            } else {
12570                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12571            }
12572        }
12573
12574        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12575        if (foregroundActivities != app.foregroundActivities) {
12576            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12577        }
12578        if (changes != 0) {
12579            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12580            app.memImportance = importance;
12581            app.foregroundActivities = foregroundActivities;
12582            int i = mPendingProcessChanges.size()-1;
12583            ProcessChangeItem item = null;
12584            while (i >= 0) {
12585                item = mPendingProcessChanges.get(i);
12586                if (item.pid == app.pid) {
12587                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12588                    break;
12589                }
12590                i--;
12591            }
12592            if (i < 0) {
12593                // No existing item in pending changes; need a new one.
12594                final int NA = mAvailProcessChanges.size();
12595                if (NA > 0) {
12596                    item = mAvailProcessChanges.remove(NA-1);
12597                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12598                } else {
12599                    item = new ProcessChangeItem();
12600                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
12601                }
12602                item.changes = 0;
12603                item.pid = app.pid;
12604                item.uid = app.info.uid;
12605                if (mPendingProcessChanges.size() == 0) {
12606                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
12607                            "*** Enqueueing dispatch processes changed!");
12608                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
12609                }
12610                mPendingProcessChanges.add(item);
12611            }
12612            item.changes |= changes;
12613            item.importance = importance;
12614            item.foregroundActivities = foregroundActivities;
12615            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
12616                    + Integer.toHexString(System.identityHashCode(item))
12617                    + " " + app.toShortString() + ": changes=" + item.changes
12618                    + " importance=" + item.importance
12619                    + " foreground=" + item.foregroundActivities
12620                    + " type=" + app.adjType + " source=" + app.adjSource
12621                    + " target=" + app.adjTarget);
12622        }
12623
12624        return app.curRawAdj;
12625    }
12626
12627    /**
12628     * Ask a given process to GC right now.
12629     */
12630    final void performAppGcLocked(ProcessRecord app) {
12631        try {
12632            app.lastRequestedGc = SystemClock.uptimeMillis();
12633            if (app.thread != null) {
12634                if (app.reportLowMemory) {
12635                    app.reportLowMemory = false;
12636                    app.thread.scheduleLowMemory();
12637                } else {
12638                    app.thread.processInBackground();
12639                }
12640            }
12641        } catch (Exception e) {
12642            // whatever.
12643        }
12644    }
12645
12646    /**
12647     * Returns true if things are idle enough to perform GCs.
12648     */
12649    private final boolean canGcNowLocked() {
12650        boolean processingBroadcasts = false;
12651        for (BroadcastQueue q : mBroadcastQueues) {
12652            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
12653                processingBroadcasts = true;
12654            }
12655        }
12656        return !processingBroadcasts
12657                && (mSleeping || (mMainStack.mResumedActivity != null &&
12658                        mMainStack.mResumedActivity.idle));
12659    }
12660
12661    /**
12662     * Perform GCs on all processes that are waiting for it, but only
12663     * if things are idle.
12664     */
12665    final void performAppGcsLocked() {
12666        final int N = mProcessesToGc.size();
12667        if (N <= 0) {
12668            return;
12669        }
12670        if (canGcNowLocked()) {
12671            while (mProcessesToGc.size() > 0) {
12672                ProcessRecord proc = mProcessesToGc.remove(0);
12673                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
12674                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12675                            <= SystemClock.uptimeMillis()) {
12676                        // To avoid spamming the system, we will GC processes one
12677                        // at a time, waiting a few seconds between each.
12678                        performAppGcLocked(proc);
12679                        scheduleAppGcsLocked();
12680                        return;
12681                    } else {
12682                        // It hasn't been long enough since we last GCed this
12683                        // process...  put it in the list to wait for its time.
12684                        addProcessToGcListLocked(proc);
12685                        break;
12686                    }
12687                }
12688            }
12689
12690            scheduleAppGcsLocked();
12691        }
12692    }
12693
12694    /**
12695     * If all looks good, perform GCs on all processes waiting for them.
12696     */
12697    final void performAppGcsIfAppropriateLocked() {
12698        if (canGcNowLocked()) {
12699            performAppGcsLocked();
12700            return;
12701        }
12702        // Still not idle, wait some more.
12703        scheduleAppGcsLocked();
12704    }
12705
12706    /**
12707     * Schedule the execution of all pending app GCs.
12708     */
12709    final void scheduleAppGcsLocked() {
12710        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
12711
12712        if (mProcessesToGc.size() > 0) {
12713            // Schedule a GC for the time to the next process.
12714            ProcessRecord proc = mProcessesToGc.get(0);
12715            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12716
12717            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
12718            long now = SystemClock.uptimeMillis();
12719            if (when < (now+GC_TIMEOUT)) {
12720                when = now + GC_TIMEOUT;
12721            }
12722            mHandler.sendMessageAtTime(msg, when);
12723        }
12724    }
12725
12726    /**
12727     * Add a process to the array of processes waiting to be GCed.  Keeps the
12728     * list in sorted order by the last GC time.  The process can't already be
12729     * on the list.
12730     */
12731    final void addProcessToGcListLocked(ProcessRecord proc) {
12732        boolean added = false;
12733        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12734            if (mProcessesToGc.get(i).lastRequestedGc <
12735                    proc.lastRequestedGc) {
12736                added = true;
12737                mProcessesToGc.add(i+1, proc);
12738                break;
12739            }
12740        }
12741        if (!added) {
12742            mProcessesToGc.add(0, proc);
12743        }
12744    }
12745
12746    /**
12747     * Set up to ask a process to GC itself.  This will either do it
12748     * immediately, or put it on the list of processes to gc the next
12749     * time things are idle.
12750     */
12751    final void scheduleAppGcLocked(ProcessRecord app) {
12752        long now = SystemClock.uptimeMillis();
12753        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
12754            return;
12755        }
12756        if (!mProcessesToGc.contains(app)) {
12757            addProcessToGcListLocked(app);
12758            scheduleAppGcsLocked();
12759        }
12760    }
12761
12762    final void checkExcessivePowerUsageLocked(boolean doKills) {
12763        updateCpuStatsNow();
12764
12765        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12766        boolean doWakeKills = doKills;
12767        boolean doCpuKills = doKills;
12768        if (mLastPowerCheckRealtime == 0) {
12769            doWakeKills = false;
12770        }
12771        if (mLastPowerCheckUptime == 0) {
12772            doCpuKills = false;
12773        }
12774        if (stats.isScreenOn()) {
12775            doWakeKills = false;
12776        }
12777        final long curRealtime = SystemClock.elapsedRealtime();
12778        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12779        final long curUptime = SystemClock.uptimeMillis();
12780        final long uptimeSince = curUptime - mLastPowerCheckUptime;
12781        mLastPowerCheckRealtime = curRealtime;
12782        mLastPowerCheckUptime = curUptime;
12783        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12784            doWakeKills = false;
12785        }
12786        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12787            doCpuKills = false;
12788        }
12789        int i = mLruProcesses.size();
12790        while (i > 0) {
12791            i--;
12792            ProcessRecord app = mLruProcesses.get(i);
12793            if (!app.keeping) {
12794                long wtime;
12795                synchronized (stats) {
12796                    wtime = stats.getProcessWakeTime(app.info.uid,
12797                            app.pid, curRealtime);
12798                }
12799                long wtimeUsed = wtime - app.lastWakeTime;
12800                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12801                if (DEBUG_POWER) {
12802                    StringBuilder sb = new StringBuilder(128);
12803                    sb.append("Wake for ");
12804                    app.toShortString(sb);
12805                    sb.append(": over ");
12806                    TimeUtils.formatDuration(realtimeSince, sb);
12807                    sb.append(" used ");
12808                    TimeUtils.formatDuration(wtimeUsed, sb);
12809                    sb.append(" (");
12810                    sb.append((wtimeUsed*100)/realtimeSince);
12811                    sb.append("%)");
12812                    Slog.i(TAG, sb.toString());
12813                    sb.setLength(0);
12814                    sb.append("CPU for ");
12815                    app.toShortString(sb);
12816                    sb.append(": over ");
12817                    TimeUtils.formatDuration(uptimeSince, sb);
12818                    sb.append(" used ");
12819                    TimeUtils.formatDuration(cputimeUsed, sb);
12820                    sb.append(" (");
12821                    sb.append((cputimeUsed*100)/uptimeSince);
12822                    sb.append("%)");
12823                    Slog.i(TAG, sb.toString());
12824                }
12825                // If a process has held a wake lock for more
12826                // than 50% of the time during this period,
12827                // that sounds bad.  Kill!
12828                if (doWakeKills && realtimeSince > 0
12829                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
12830                    synchronized (stats) {
12831                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12832                                realtimeSince, wtimeUsed);
12833                    }
12834                    Slog.w(TAG, "Excessive wake lock in " + app.processName
12835                            + " (pid " + app.pid + "): held " + wtimeUsed
12836                            + " during " + realtimeSince);
12837                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12838                            app.processName, app.setAdj, "excessive wake lock");
12839                    Process.killProcessQuiet(app.pid);
12840                } else if (doCpuKills && uptimeSince > 0
12841                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
12842                    synchronized (stats) {
12843                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12844                                uptimeSince, cputimeUsed);
12845                    }
12846                    Slog.w(TAG, "Excessive CPU in " + app.processName
12847                            + " (pid " + app.pid + "): used " + cputimeUsed
12848                            + " during " + uptimeSince);
12849                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12850                            app.processName, app.setAdj, "excessive cpu");
12851                    Process.killProcessQuiet(app.pid);
12852                } else {
12853                    app.lastWakeTime = wtime;
12854                    app.lastCpuTime = app.curCpuTime;
12855                }
12856            }
12857        }
12858    }
12859
12860    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
12861            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
12862        app.hiddenAdj = hiddenAdj;
12863        app.emptyAdj = emptyAdj;
12864
12865        if (app.thread == null) {
12866            return false;
12867        }
12868
12869        final boolean wasKeeping = app.keeping;
12870
12871        boolean success = true;
12872
12873        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
12874
12875        if (app.curRawAdj != app.setRawAdj) {
12876            if (wasKeeping && !app.keeping) {
12877                // This app is no longer something we want to keep.  Note
12878                // its current wake lock time to later know to kill it if
12879                // it is not behaving well.
12880                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12881                synchronized (stats) {
12882                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12883                            app.pid, SystemClock.elapsedRealtime());
12884                }
12885                app.lastCpuTime = app.curCpuTime;
12886            }
12887
12888            app.setRawAdj = app.curRawAdj;
12889        }
12890
12891        if (app.curAdj != app.setAdj) {
12892            if (Process.setOomAdj(app.pid, app.curAdj)) {
12893                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
12894                    TAG, "Set " + app.pid + " " + app.processName +
12895                    " adj " + app.curAdj + ": " + app.adjType);
12896                app.setAdj = app.curAdj;
12897            } else {
12898                success = false;
12899                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
12900            }
12901        }
12902        if (app.setSchedGroup != app.curSchedGroup) {
12903            app.setSchedGroup = app.curSchedGroup;
12904            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
12905                    "Setting process group of " + app.processName
12906                    + " to " + app.curSchedGroup);
12907            if (app.waitingToKill != null &&
12908                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
12909                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
12910                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12911                        app.processName, app.setAdj, app.waitingToKill);
12912                app.killedBackground = true;
12913                Process.killProcessQuiet(app.pid);
12914                success = false;
12915            } else {
12916                if (true) {
12917                    long oldId = Binder.clearCallingIdentity();
12918                    try {
12919                        Process.setProcessGroup(app.pid, app.curSchedGroup);
12920                    } catch (Exception e) {
12921                        Slog.w(TAG, "Failed setting process group of " + app.pid
12922                                + " to " + app.curSchedGroup);
12923                        e.printStackTrace();
12924                    } finally {
12925                        Binder.restoreCallingIdentity(oldId);
12926                    }
12927                } else {
12928                    if (app.thread != null) {
12929                        try {
12930                            app.thread.setSchedulingGroup(app.curSchedGroup);
12931                        } catch (RemoteException e) {
12932                        }
12933                    }
12934                }
12935            }
12936        }
12937        return success;
12938    }
12939
12940    private final ActivityRecord resumedAppLocked() {
12941        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
12942        if (resumedActivity == null || resumedActivity.app == null) {
12943            resumedActivity = mMainStack.mPausingActivity;
12944            if (resumedActivity == null || resumedActivity.app == null) {
12945                resumedActivity = mMainStack.topRunningActivityLocked(null);
12946            }
12947        }
12948        return resumedActivity;
12949    }
12950
12951    final boolean updateOomAdjLocked(ProcessRecord app) {
12952        final ActivityRecord TOP_ACT = resumedAppLocked();
12953        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12954        int curAdj = app.curAdj;
12955        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12956            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12957
12958        mAdjSeq++;
12959
12960        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
12961                TOP_APP, false);
12962        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12963            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12964        if (nowHidden != wasHidden) {
12965            // Changed to/from hidden state, so apps after it in the LRU
12966            // list may also be changed.
12967            updateOomAdjLocked();
12968        }
12969        return success;
12970    }
12971
12972    final void updateOomAdjLocked() {
12973        final ActivityRecord TOP_ACT = resumedAppLocked();
12974        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12975
12976        if (false) {
12977            RuntimeException e = new RuntimeException();
12978            e.fillInStackTrace();
12979            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
12980        }
12981
12982        mAdjSeq++;
12983        mNewNumServiceProcs = 0;
12984
12985        // Let's determine how many processes we have running vs.
12986        // how many slots we have for background processes; we may want
12987        // to put multiple processes in a slot of there are enough of
12988        // them.
12989        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
12990                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
12991        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
12992        if (emptyFactor < 1) emptyFactor = 1;
12993        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
12994        if (hiddenFactor < 1) hiddenFactor = 1;
12995        int stepHidden = 0;
12996        int stepEmpty = 0;
12997        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
12998        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
12999        int numHidden = 0;
13000        int numEmpty = 0;
13001        int numTrimming = 0;
13002
13003        mNumNonHiddenProcs = 0;
13004        mNumHiddenProcs = 0;
13005
13006        // First update the OOM adjustment for each of the
13007        // application processes based on their current state.
13008        int i = mLruProcesses.size();
13009        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13010        int nextHiddenAdj = curHiddenAdj+1;
13011        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13012        int nextEmptyAdj = curEmptyAdj+2;
13013        while (i > 0) {
13014            i--;
13015            ProcessRecord app = mLruProcesses.get(i);
13016            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13017            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
13018            if (!app.killedBackground) {
13019                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13020                    // This process was assigned as a hidden process...  step the
13021                    // hidden level.
13022                    mNumHiddenProcs++;
13023                    if (curHiddenAdj != nextHiddenAdj) {
13024                        stepHidden++;
13025                        if (stepHidden >= hiddenFactor) {
13026                            stepHidden = 0;
13027                            curHiddenAdj = nextHiddenAdj;
13028                            nextHiddenAdj += 2;
13029                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13030                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13031                            }
13032                        }
13033                    }
13034                    numHidden++;
13035                    if (numHidden > hiddenProcessLimit) {
13036                        Slog.i(TAG, "No longer want " + app.processName
13037                                + " (pid " + app.pid + "): hidden #" + numHidden);
13038                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13039                                app.processName, app.setAdj, "too many background");
13040                        app.killedBackground = true;
13041                        Process.killProcessQuiet(app.pid);
13042                    }
13043                } else {
13044                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13045                        // This process was assigned as an empty process...  step the
13046                        // empty level.
13047                        if (curEmptyAdj != nextEmptyAdj) {
13048                            stepEmpty++;
13049                            if (stepEmpty >= emptyFactor) {
13050                                stepEmpty = 0;
13051                                curEmptyAdj = nextEmptyAdj;
13052                                nextEmptyAdj += 2;
13053                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13054                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13055                                }
13056                            }
13057                        }
13058                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13059                        mNumNonHiddenProcs++;
13060                    }
13061                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13062                        numEmpty++;
13063                        if (numEmpty > emptyProcessLimit) {
13064                            Slog.i(TAG, "No longer want " + app.processName
13065                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13066                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13067                                    app.processName, app.setAdj, "too many background");
13068                            app.killedBackground = true;
13069                            Process.killProcessQuiet(app.pid);
13070                        }
13071                    }
13072                }
13073                if (app.isolated && app.services.size() <= 0) {
13074                    // If this is an isolated process, and there are no
13075                    // services running in it, then the process is no longer
13076                    // needed.  We agressively kill these because we can by
13077                    // definition not re-use the same process again, and it is
13078                    // good to avoid having whatever code was running in them
13079                    // left sitting around after no longer needed.
13080                    Slog.i(TAG, "Isolated process " + app.processName
13081                            + " (pid " + app.pid + ") no longer needed");
13082                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13083                            app.processName, app.setAdj, "isolated not needed");
13084                    app.killedBackground = true;
13085                    Process.killProcessQuiet(app.pid);
13086                }
13087                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13088                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13089                        && !app.killedBackground) {
13090                    numTrimming++;
13091                }
13092            }
13093        }
13094
13095        mNumServiceProcs = mNewNumServiceProcs;
13096
13097        // Now determine the memory trimming level of background processes.
13098        // Unfortunately we need to start at the back of the list to do this
13099        // properly.  We only do this if the number of background apps we
13100        // are managing to keep around is less than half the maximum we desire;
13101        // if we are keeping a good number around, we'll let them use whatever
13102        // memory they want.
13103        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13104                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13105            final int numHiddenAndEmpty = numHidden + numEmpty;
13106            final int N = mLruProcesses.size();
13107            int factor = numTrimming/3;
13108            int minFactor = 2;
13109            if (mHomeProcess != null) minFactor++;
13110            if (mPreviousProcess != null) minFactor++;
13111            if (factor < minFactor) factor = minFactor;
13112            int step = 0;
13113            int fgTrimLevel;
13114            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13115                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13116            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13117                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13118            } else {
13119                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13120            }
13121            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13122            for (i=0; i<N; i++) {
13123                ProcessRecord app = mLruProcesses.get(i);
13124                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13125                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13126                        && !app.killedBackground) {
13127                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13128                        try {
13129                            app.thread.scheduleTrimMemory(curLevel);
13130                        } catch (RemoteException e) {
13131                        }
13132                        if (false) {
13133                            // For now we won't do this; our memory trimming seems
13134                            // to be good enough at this point that destroying
13135                            // activities causes more harm than good.
13136                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13137                                    && app != mHomeProcess && app != mPreviousProcess) {
13138                                // Need to do this on its own message because the stack may not
13139                                // be in a consistent state at this point.
13140                                // For these apps we will also finish their activities
13141                                // to help them free memory.
13142                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13143                            }
13144                        }
13145                    }
13146                    app.trimMemoryLevel = curLevel;
13147                    step++;
13148                    if (step >= factor) {
13149                        step = 0;
13150                        switch (curLevel) {
13151                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13152                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13153                                break;
13154                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13155                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13156                                break;
13157                        }
13158                    }
13159                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13160                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13161                            && app.thread != null) {
13162                        try {
13163                            app.thread.scheduleTrimMemory(
13164                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13165                        } catch (RemoteException e) {
13166                        }
13167                    }
13168                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13169                } else {
13170                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13171                            && app.pendingUiClean) {
13172                        // If this application is now in the background and it
13173                        // had done UI, then give it the special trim level to
13174                        // have it free UI resources.
13175                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13176                        if (app.trimMemoryLevel < level && app.thread != null) {
13177                            try {
13178                                app.thread.scheduleTrimMemory(level);
13179                            } catch (RemoteException e) {
13180                            }
13181                        }
13182                        app.pendingUiClean = false;
13183                    }
13184                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13185                        try {
13186                            app.thread.scheduleTrimMemory(fgTrimLevel);
13187                        } catch (RemoteException e) {
13188                        }
13189                    }
13190                    app.trimMemoryLevel = fgTrimLevel;
13191                }
13192            }
13193        } else {
13194            final int N = mLruProcesses.size();
13195            for (i=0; i<N; i++) {
13196                ProcessRecord app = mLruProcesses.get(i);
13197                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13198                        && app.pendingUiClean) {
13199                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13200                            && app.thread != null) {
13201                        try {
13202                            app.thread.scheduleTrimMemory(
13203                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13204                        } catch (RemoteException e) {
13205                        }
13206                    }
13207                    app.pendingUiClean = false;
13208                }
13209                app.trimMemoryLevel = 0;
13210            }
13211        }
13212
13213        if (mAlwaysFinishActivities) {
13214            // Need to do this on its own message because the stack may not
13215            // be in a consistent state at this point.
13216            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13217        }
13218    }
13219
13220    final void trimApplications() {
13221        synchronized (this) {
13222            int i;
13223
13224            // First remove any unused application processes whose package
13225            // has been removed.
13226            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13227                final ProcessRecord app = mRemovedProcesses.get(i);
13228                if (app.activities.size() == 0
13229                        && app.curReceiver == null && app.services.size() == 0) {
13230                    Slog.i(
13231                        TAG, "Exiting empty application process "
13232                        + app.processName + " ("
13233                        + (app.thread != null ? app.thread.asBinder() : null)
13234                        + ")\n");
13235                    if (app.pid > 0 && app.pid != MY_PID) {
13236                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13237                                app.processName, app.setAdj, "empty");
13238                        Process.killProcessQuiet(app.pid);
13239                    } else {
13240                        try {
13241                            app.thread.scheduleExit();
13242                        } catch (Exception e) {
13243                            // Ignore exceptions.
13244                        }
13245                    }
13246                    cleanUpApplicationRecordLocked(app, false, true, -1);
13247                    mRemovedProcesses.remove(i);
13248
13249                    if (app.persistent) {
13250                        if (app.persistent) {
13251                            addAppLocked(app.info, false);
13252                        }
13253                    }
13254                }
13255            }
13256
13257            // Now update the oom adj for all processes.
13258            updateOomAdjLocked();
13259        }
13260    }
13261
13262    /** This method sends the specified signal to each of the persistent apps */
13263    public void signalPersistentProcesses(int sig) throws RemoteException {
13264        if (sig != Process.SIGNAL_USR1) {
13265            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13266        }
13267
13268        synchronized (this) {
13269            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13270                    != PackageManager.PERMISSION_GRANTED) {
13271                throw new SecurityException("Requires permission "
13272                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13273            }
13274
13275            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13276                ProcessRecord r = mLruProcesses.get(i);
13277                if (r.thread != null && r.persistent) {
13278                    Process.sendSignal(r.pid, sig);
13279                }
13280            }
13281        }
13282    }
13283
13284    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13285        if (proc == null || proc == mProfileProc) {
13286            proc = mProfileProc;
13287            path = mProfileFile;
13288            profileType = mProfileType;
13289            clearProfilerLocked();
13290        }
13291        if (proc == null) {
13292            return;
13293        }
13294        try {
13295            proc.thread.profilerControl(false, path, null, profileType);
13296        } catch (RemoteException e) {
13297            throw new IllegalStateException("Process disappeared");
13298        }
13299    }
13300
13301    private void clearProfilerLocked() {
13302        if (mProfileFd != null) {
13303            try {
13304                mProfileFd.close();
13305            } catch (IOException e) {
13306            }
13307        }
13308        mProfileApp = null;
13309        mProfileProc = null;
13310        mProfileFile = null;
13311        mProfileType = 0;
13312        mAutoStopProfiler = false;
13313    }
13314
13315    public boolean profileControl(String process, boolean start,
13316            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13317
13318        try {
13319            synchronized (this) {
13320                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13321                // its own permission.
13322                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13323                        != PackageManager.PERMISSION_GRANTED) {
13324                    throw new SecurityException("Requires permission "
13325                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13326                }
13327
13328                if (start && fd == null) {
13329                    throw new IllegalArgumentException("null fd");
13330                }
13331
13332                ProcessRecord proc = null;
13333                if (process != null) {
13334                    try {
13335                        int pid = Integer.parseInt(process);
13336                        synchronized (mPidsSelfLocked) {
13337                            proc = mPidsSelfLocked.get(pid);
13338                        }
13339                    } catch (NumberFormatException e) {
13340                    }
13341
13342                    if (proc == null) {
13343                        HashMap<String, SparseArray<ProcessRecord>> all
13344                                = mProcessNames.getMap();
13345                        SparseArray<ProcessRecord> procs = all.get(process);
13346                        if (procs != null && procs.size() > 0) {
13347                            proc = procs.valueAt(0);
13348                        }
13349                    }
13350                }
13351
13352                if (start && (proc == null || proc.thread == null)) {
13353                    throw new IllegalArgumentException("Unknown process: " + process);
13354                }
13355
13356                if (start) {
13357                    stopProfilerLocked(null, null, 0);
13358                    setProfileApp(proc.info, proc.processName, path, fd, false);
13359                    mProfileProc = proc;
13360                    mProfileType = profileType;
13361                    try {
13362                        fd = fd.dup();
13363                    } catch (IOException e) {
13364                        fd = null;
13365                    }
13366                    proc.thread.profilerControl(start, path, fd, profileType);
13367                    fd = null;
13368                    mProfileFd = null;
13369                } else {
13370                    stopProfilerLocked(proc, path, profileType);
13371                    if (fd != null) {
13372                        try {
13373                            fd.close();
13374                        } catch (IOException e) {
13375                        }
13376                    }
13377                }
13378
13379                return true;
13380            }
13381        } catch (RemoteException e) {
13382            throw new IllegalStateException("Process disappeared");
13383        } finally {
13384            if (fd != null) {
13385                try {
13386                    fd.close();
13387                } catch (IOException e) {
13388                }
13389            }
13390        }
13391    }
13392
13393    public boolean dumpHeap(String process, boolean managed,
13394            String path, ParcelFileDescriptor fd) throws RemoteException {
13395
13396        try {
13397            synchronized (this) {
13398                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13399                // its own permission (same as profileControl).
13400                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13401                        != PackageManager.PERMISSION_GRANTED) {
13402                    throw new SecurityException("Requires permission "
13403                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13404                }
13405
13406                if (fd == null) {
13407                    throw new IllegalArgumentException("null fd");
13408                }
13409
13410                ProcessRecord proc = null;
13411                try {
13412                    int pid = Integer.parseInt(process);
13413                    synchronized (mPidsSelfLocked) {
13414                        proc = mPidsSelfLocked.get(pid);
13415                    }
13416                } catch (NumberFormatException e) {
13417                }
13418
13419                if (proc == null) {
13420                    HashMap<String, SparseArray<ProcessRecord>> all
13421                            = mProcessNames.getMap();
13422                    SparseArray<ProcessRecord> procs = all.get(process);
13423                    if (procs != null && procs.size() > 0) {
13424                        proc = procs.valueAt(0);
13425                    }
13426                }
13427
13428                if (proc == null || proc.thread == null) {
13429                    throw new IllegalArgumentException("Unknown process: " + process);
13430                }
13431
13432                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13433                if (!isDebuggable) {
13434                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13435                        throw new SecurityException("Process not debuggable: " + proc);
13436                    }
13437                }
13438
13439                proc.thread.dumpHeap(managed, path, fd);
13440                fd = null;
13441                return true;
13442            }
13443        } catch (RemoteException e) {
13444            throw new IllegalStateException("Process disappeared");
13445        } finally {
13446            if (fd != null) {
13447                try {
13448                    fd.close();
13449                } catch (IOException e) {
13450                }
13451            }
13452        }
13453    }
13454
13455    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13456    public void monitor() {
13457        synchronized (this) { }
13458    }
13459
13460    void onCoreSettingsChange(Bundle settings) {
13461        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13462            ProcessRecord processRecord = mLruProcesses.get(i);
13463            try {
13464                if (processRecord.thread != null) {
13465                    processRecord.thread.setCoreSettings(settings);
13466                }
13467            } catch (RemoteException re) {
13468                /* ignore */
13469            }
13470        }
13471    }
13472
13473    // Multi-user methods
13474
13475    public boolean switchUser(int userId) {
13476        final int callingUid = Binder.getCallingUid();
13477        if (callingUid != 0 && callingUid != Process.myUid()) {
13478            Slog.e(TAG, "Trying to switch user from unauthorized app");
13479            return false;
13480        }
13481        if (mCurrentUserId == userId)
13482            return true;
13483
13484        synchronized (this) {
13485            // Check if user is already logged in, otherwise check if user exists first before
13486            // adding to the list of logged in users.
13487            if (mLoggedInUsers.indexOfKey(userId) < 0) {
13488                if (!userExists(userId)) {
13489                    return false;
13490                }
13491                mLoggedInUsers.append(userId, userId);
13492            }
13493
13494            mCurrentUserId = userId;
13495            boolean haveActivities = mMainStack.switchUser(userId);
13496            if (!haveActivities) {
13497                startHomeActivityLocked(userId);
13498            }
13499
13500        }
13501
13502        // Inform of user switch
13503        Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13504        addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13505        mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_USERS);
13506
13507        return true;
13508    }
13509
13510    @Override
13511    public UserInfo getCurrentUser() throws RemoteException {
13512        final int callingUid = Binder.getCallingUid();
13513        if (callingUid != 0 && callingUid != Process.myUid()) {
13514            Slog.e(TAG, "Trying to get user from unauthorized app");
13515            return null;
13516        }
13517        return getUserManager().getUserInfo(mCurrentUserId);
13518    }
13519
13520    private void onUserRemoved(Intent intent) {
13521        int extraUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
13522        if (extraUserId < 1) return;
13523
13524        // Kill all the processes for the user
13525        ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>();
13526        synchronized (this) {
13527            HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap();
13528            for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
13529                SparseArray<ProcessRecord> uids = uidMap.getValue();
13530                for (int i = 0; i < uids.size(); i++) {
13531                    if (UserHandle.getUserId(uids.keyAt(i)) == extraUserId) {
13532                        pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
13533                    }
13534                }
13535            }
13536
13537            for (Pair<String,Integer> pkgAndUid : pkgAndUids) {
13538                forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second,
13539                        false, false, true, true, extraUserId);
13540            }
13541        }
13542    }
13543
13544    private boolean userExists(int userId) {
13545        UserInfo user = getUserManager().getUserInfo(userId);
13546        return user != null;
13547    }
13548
13549    UserManager getUserManager() {
13550        if (mUserManager == null) {
13551            mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
13552        }
13553        return mUserManager;
13554    }
13555
13556    private void checkValidCaller(int uid, int userId) {
13557        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
13558
13559        throw new SecurityException("Caller uid=" + uid
13560                + " is not privileged to communicate with user=" + userId);
13561    }
13562
13563    private int applyUserId(int uid, int userId) {
13564        return UserHandle.getUid(userId, uid);
13565    }
13566
13567    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
13568        if (info == null) return null;
13569        ApplicationInfo newInfo = new ApplicationInfo(info);
13570        newInfo.uid = applyUserId(info.uid, userId);
13571        newInfo.dataDir = USER_DATA_DIR + userId + "/"
13572                + info.packageName;
13573        return newInfo;
13574    }
13575
13576    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
13577        if (aInfo == null
13578                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
13579            return aInfo;
13580        }
13581
13582        ActivityInfo info = new ActivityInfo(aInfo);
13583        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
13584        return info;
13585    }
13586}
13587