ActivityManagerService.java revision 6ea0d0a2592395b8980c24304733daec628e947e
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.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
20import static android.content.pm.PackageManager.PERMISSION_GRANTED;
21import static com.android.internal.util.XmlUtils.readBooleanAttribute;
22import static com.android.internal.util.XmlUtils.readIntAttribute;
23import static com.android.internal.util.XmlUtils.readLongAttribute;
24import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
25import static com.android.internal.util.XmlUtils.writeIntAttribute;
26import static com.android.internal.util.XmlUtils.writeLongAttribute;
27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
29import static org.xmlpull.v1.XmlPullParser.START_TAG;
30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
31
32import android.Manifest;
33import android.app.AppOpsManager;
34import android.app.IActivityContainer;
35import android.app.IActivityContainerCallback;
36import android.app.IAppTask;
37import android.app.admin.DevicePolicyManager;
38import android.appwidget.AppWidgetManager;
39import android.graphics.Rect;
40import android.os.BatteryStats;
41import android.os.PersistableBundle;
42import android.service.voice.IVoiceInteractionSession;
43import android.util.ArrayMap;
44
45import com.android.internal.R;
46import com.android.internal.annotations.GuardedBy;
47import com.android.internal.app.IAppOpsService;
48import com.android.internal.app.IVoiceInteractor;
49import com.android.internal.app.ProcessMap;
50import com.android.internal.app.ProcessStats;
51import com.android.internal.content.PackageMonitor;
52import com.android.internal.os.BackgroundThread;
53import com.android.internal.os.BatteryStatsImpl;
54import com.android.internal.os.ProcessCpuTracker;
55import com.android.internal.os.TransferPipe;
56import com.android.internal.os.Zygote;
57import com.android.internal.util.FastPrintWriter;
58import com.android.internal.util.FastXmlSerializer;
59import com.android.internal.util.MemInfoReader;
60import com.android.internal.util.Preconditions;
61import com.android.server.AppOpsService;
62import com.android.server.AttributeCache;
63import com.android.server.IntentResolver;
64import com.android.server.LocalServices;
65import com.android.server.ServiceThread;
66import com.android.server.SystemService;
67import com.android.server.SystemServiceManager;
68import com.android.server.Watchdog;
69import com.android.server.am.ActivityStack.ActivityState;
70import com.android.server.firewall.IntentFirewall;
71import com.android.server.pm.UserManagerService;
72import com.android.server.wm.AppTransition;
73import com.android.server.wm.WindowManagerService;
74import com.google.android.collect.Lists;
75import com.google.android.collect.Maps;
76
77import libcore.io.IoUtils;
78
79import org.xmlpull.v1.XmlPullParser;
80import org.xmlpull.v1.XmlPullParserException;
81import org.xmlpull.v1.XmlSerializer;
82
83import android.app.Activity;
84import android.app.ActivityManager;
85import android.app.ActivityManager.RunningTaskInfo;
86import android.app.ActivityManager.StackInfo;
87import android.app.ActivityManagerInternal;
88import android.app.ActivityManagerNative;
89import android.app.ActivityOptions;
90import android.app.ActivityThread;
91import android.app.AlertDialog;
92import android.app.AppGlobals;
93import android.app.ApplicationErrorReport;
94import android.app.Dialog;
95import android.app.IActivityController;
96import android.app.IApplicationThread;
97import android.app.IInstrumentationWatcher;
98import android.app.INotificationManager;
99import android.app.IProcessObserver;
100import android.app.IServiceConnection;
101import android.app.IStopUserCallback;
102import android.app.IUiAutomationConnection;
103import android.app.IUserSwitchObserver;
104import android.app.Instrumentation;
105import android.app.Notification;
106import android.app.NotificationManager;
107import android.app.PendingIntent;
108import android.app.backup.IBackupManager;
109import android.content.ActivityNotFoundException;
110import android.content.BroadcastReceiver;
111import android.content.ClipData;
112import android.content.ComponentCallbacks2;
113import android.content.ComponentName;
114import android.content.ContentProvider;
115import android.content.ContentResolver;
116import android.content.Context;
117import android.content.DialogInterface;
118import android.content.IContentProvider;
119import android.content.IIntentReceiver;
120import android.content.IIntentSender;
121import android.content.Intent;
122import android.content.IntentFilter;
123import android.content.IntentSender;
124import android.content.pm.ActivityInfo;
125import android.content.pm.ApplicationInfo;
126import android.content.pm.ConfigurationInfo;
127import android.content.pm.IPackageDataObserver;
128import android.content.pm.IPackageManager;
129import android.content.pm.InstrumentationInfo;
130import android.content.pm.PackageInfo;
131import android.content.pm.PackageManager;
132import android.content.pm.ParceledListSlice;
133import android.content.pm.UserInfo;
134import android.content.pm.PackageManager.NameNotFoundException;
135import android.content.pm.PathPermission;
136import android.content.pm.ProviderInfo;
137import android.content.pm.ResolveInfo;
138import android.content.pm.ServiceInfo;
139import android.content.res.CompatibilityInfo;
140import android.content.res.Configuration;
141import android.graphics.Bitmap;
142import android.net.Proxy;
143import android.net.ProxyInfo;
144import android.net.Uri;
145import android.os.Binder;
146import android.os.Build;
147import android.os.Bundle;
148import android.os.Debug;
149import android.os.DropBoxManager;
150import android.os.Environment;
151import android.os.FactoryTest;
152import android.os.FileObserver;
153import android.os.FileUtils;
154import android.os.Handler;
155import android.os.IBinder;
156import android.os.IPermissionController;
157import android.os.IRemoteCallback;
158import android.os.IUserManager;
159import android.os.Looper;
160import android.os.Message;
161import android.os.Parcel;
162import android.os.ParcelFileDescriptor;
163import android.os.Process;
164import android.os.RemoteCallbackList;
165import android.os.RemoteException;
166import android.os.SELinux;
167import android.os.ServiceManager;
168import android.os.StrictMode;
169import android.os.SystemClock;
170import android.os.SystemProperties;
171import android.os.UpdateLock;
172import android.os.UserHandle;
173import android.provider.Settings;
174import android.text.format.DateUtils;
175import android.text.format.Time;
176import android.util.AtomicFile;
177import android.util.EventLog;
178import android.util.Log;
179import android.util.Pair;
180import android.util.PrintWriterPrinter;
181import android.util.Slog;
182import android.util.SparseArray;
183import android.util.TimeUtils;
184import android.util.Xml;
185import android.view.Gravity;
186import android.view.LayoutInflater;
187import android.view.View;
188import android.view.WindowManager;
189
190import java.io.BufferedInputStream;
191import java.io.BufferedOutputStream;
192import java.io.DataInputStream;
193import java.io.DataOutputStream;
194import java.io.File;
195import java.io.FileDescriptor;
196import java.io.FileInputStream;
197import java.io.FileNotFoundException;
198import java.io.FileOutputStream;
199import java.io.IOException;
200import java.io.InputStreamReader;
201import java.io.PrintWriter;
202import java.io.StringWriter;
203import java.lang.ref.WeakReference;
204import java.util.ArrayList;
205import java.util.Arrays;
206import java.util.Collections;
207import java.util.Comparator;
208import java.util.HashMap;
209import java.util.HashSet;
210import java.util.Iterator;
211import java.util.List;
212import java.util.Locale;
213import java.util.Map;
214import java.util.Set;
215import java.util.concurrent.atomic.AtomicBoolean;
216import java.util.concurrent.atomic.AtomicLong;
217
218public final class ActivityManagerService extends ActivityManagerNative
219        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
220    private static final String USER_DATA_DIR = "/data/user/";
221    static final String TAG = "ActivityManager";
222    static final String TAG_MU = "ActivityManagerServiceMU";
223    static final boolean DEBUG = false;
224    static final boolean localLOGV = DEBUG;
225    static final boolean DEBUG_BACKUP = localLOGV || false;
226    static final boolean DEBUG_BROADCAST = localLOGV || false;
227    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
228    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
229    static final boolean DEBUG_CLEANUP = localLOGV || false;
230    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
231    static final boolean DEBUG_FOCUS = false;
232    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
233    static final boolean DEBUG_MU = localLOGV || false;
234    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
235    static final boolean DEBUG_LRU = localLOGV || false;
236    static final boolean DEBUG_PAUSE = localLOGV || false;
237    static final boolean DEBUG_POWER = localLOGV || false;
238    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
239    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
240    static final boolean DEBUG_PROCESSES = localLOGV || false;
241    static final boolean DEBUG_PROVIDER = localLOGV || false;
242    static final boolean DEBUG_RESULTS = localLOGV || false;
243    static final boolean DEBUG_SERVICE = localLOGV || false;
244    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
245    static final boolean DEBUG_STACK = localLOGV || false;
246    static final boolean DEBUG_SWITCH = localLOGV || false;
247    static final boolean DEBUG_TASKS = localLOGV || false;
248    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
249    static final boolean DEBUG_TRANSITION = localLOGV || false;
250    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
251    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
252    static final boolean DEBUG_VISBILITY = localLOGV || false;
253    static final boolean DEBUG_PSS = localLOGV || false;
254    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
255    static final boolean VALIDATE_TOKENS = false;
256    static final boolean SHOW_ACTIVITY_START_TIME = true;
257
258    // Control over CPU and battery monitoring.
259    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
260    static final boolean MONITOR_CPU_USAGE = true;
261    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
262    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
263    static final boolean MONITOR_THREAD_CPU_USAGE = false;
264
265    // The flags that are set for all calls we make to the package manager.
266    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
267
268    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
269
270    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
271
272    // Maximum number of recent tasks that we can remember.
273    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
274
275    // Maximum number recent bitmaps to keep in memory.
276    static final int MAX_RECENT_BITMAPS = 5;
277
278    // Amount of time after a call to stopAppSwitches() during which we will
279    // prevent further untrusted switches from happening.
280    static final long APP_SWITCH_DELAY_TIME = 5*1000;
281
282    // How long we wait for a launched process to attach to the activity manager
283    // before we decide it's never going to come up for real.
284    static final int PROC_START_TIMEOUT = 10*1000;
285
286    // How long we wait for a launched process to attach to the activity manager
287    // before we decide it's never going to come up for real, when the process was
288    // started with a wrapper for instrumentation (such as Valgrind) because it
289    // could take much longer than usual.
290    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
291
292    // How long to wait after going idle before forcing apps to GC.
293    static final int GC_TIMEOUT = 5*1000;
294
295    // The minimum amount of time between successive GC requests for a process.
296    static final int GC_MIN_INTERVAL = 60*1000;
297
298    // The minimum amount of time between successive PSS requests for a process.
299    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
300
301    // The minimum amount of time between successive PSS requests for a process
302    // when the request is due to the memory state being lowered.
303    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
304
305    // The rate at which we check for apps using excessive power -- 15 mins.
306    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
307
308    // The minimum sample duration we will allow before deciding we have
309    // enough data on wake locks to start killing things.
310    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
311
312    // The minimum sample duration we will allow before deciding we have
313    // enough data on CPU usage to start killing things.
314    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
315
316    // How long we allow a receiver to run before giving up on it.
317    static final int BROADCAST_FG_TIMEOUT = 10*1000;
318    static final int BROADCAST_BG_TIMEOUT = 60*1000;
319
320    // How long we wait until we timeout on key dispatching.
321    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
322
323    // How long we wait until we timeout on key dispatching during instrumentation.
324    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
325
326    // Amount of time we wait for observers to handle a user switch before
327    // giving up on them and unfreezing the screen.
328    static final int USER_SWITCH_TIMEOUT = 2*1000;
329
330    // Maximum number of users we allow to be running at a time.
331    static final int MAX_RUNNING_USERS = 3;
332
333    // How long to wait in getAssistContextExtras for the activity and foreground services
334    // to respond with the result.
335    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
336
337    // Maximum number of persisted Uri grants a package is allowed
338    static final int MAX_PERSISTED_URI_GRANTS = 128;
339
340    static final int MY_PID = Process.myPid();
341
342    static final String[] EMPTY_STRING_ARRAY = new String[0];
343
344    // How many bytes to write into the dropbox log before truncating
345    static final int DROPBOX_MAX_SIZE = 256 * 1024;
346
347    /** All system services */
348    SystemServiceManager mSystemServiceManager;
349
350    /** Run all ActivityStacks through this */
351    ActivityStackSupervisor mStackSupervisor;
352
353    public IntentFirewall mIntentFirewall;
354
355    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
356    // default actuion automatically.  Important for devices without direct input
357    // devices.
358    private boolean mShowDialogs = true;
359
360    /**
361     * Description of a request to start a new activity, which has been held
362     * due to app switches being disabled.
363     */
364    static class PendingActivityLaunch {
365        final ActivityRecord r;
366        final ActivityRecord sourceRecord;
367        final int startFlags;
368        final ActivityStack stack;
369
370        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
371                int _startFlags, ActivityStack _stack) {
372            r = _r;
373            sourceRecord = _sourceRecord;
374            startFlags = _startFlags;
375            stack = _stack;
376        }
377    }
378
379    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
380            = new ArrayList<PendingActivityLaunch>();
381
382    BroadcastQueue mFgBroadcastQueue;
383    BroadcastQueue mBgBroadcastQueue;
384    // Convenient for easy iteration over the queues. Foreground is first
385    // so that dispatch of foreground broadcasts gets precedence.
386    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
387
388    BroadcastQueue broadcastQueueForIntent(Intent intent) {
389        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
390        if (DEBUG_BACKGROUND_BROADCAST) {
391            Slog.i(TAG, "Broadcast intent " + intent + " on "
392                    + (isFg ? "foreground" : "background")
393                    + " queue");
394        }
395        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
396    }
397
398    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
399        for (BroadcastQueue queue : mBroadcastQueues) {
400            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
401            if (r != null) {
402                return r;
403            }
404        }
405        return null;
406    }
407
408    /**
409     * Activity we have told the window manager to have key focus.
410     */
411    ActivityRecord mFocusedActivity = null;
412
413    /**
414     * List of intents that were used to start the most recent tasks.
415     */
416    ArrayList<TaskRecord> mRecentTasks;
417
418    public class PendingAssistExtras extends Binder implements Runnable {
419        public final ActivityRecord activity;
420        public boolean haveResult = false;
421        public Bundle result = null;
422        public PendingAssistExtras(ActivityRecord _activity) {
423            activity = _activity;
424        }
425        @Override
426        public void run() {
427            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
428            synchronized (this) {
429                haveResult = true;
430                notifyAll();
431            }
432        }
433    }
434
435    final ArrayList<PendingAssistExtras> mPendingAssistExtras
436            = new ArrayList<PendingAssistExtras>();
437
438    /**
439     * Process management.
440     */
441    final ProcessList mProcessList = new ProcessList();
442
443    /**
444     * All of the applications we currently have running organized by name.
445     * The keys are strings of the application package name (as
446     * returned by the package manager), and the keys are ApplicationRecord
447     * objects.
448     */
449    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
450
451    /**
452     * Tracking long-term execution of processes to look for abuse and other
453     * bad app behavior.
454     */
455    final ProcessStatsService mProcessStats;
456
457    /**
458     * The currently running isolated processes.
459     */
460    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
461
462    /**
463     * Counter for assigning isolated process uids, to avoid frequently reusing the
464     * same ones.
465     */
466    int mNextIsolatedProcessUid = 0;
467
468    /**
469     * The currently running heavy-weight process, if any.
470     */
471    ProcessRecord mHeavyWeightProcess = null;
472
473    /**
474     * The last time that various processes have crashed.
475     */
476    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
477
478    /**
479     * Information about a process that is currently marked as bad.
480     */
481    static final class BadProcessInfo {
482        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
483            this.time = time;
484            this.shortMsg = shortMsg;
485            this.longMsg = longMsg;
486            this.stack = stack;
487        }
488
489        final long time;
490        final String shortMsg;
491        final String longMsg;
492        final String stack;
493    }
494
495    /**
496     * Set of applications that we consider to be bad, and will reject
497     * incoming broadcasts from (which the user has no control over).
498     * Processes are added to this set when they have crashed twice within
499     * a minimum amount of time; they are removed from it when they are
500     * later restarted (hopefully due to some user action).  The value is the
501     * time it was added to the list.
502     */
503    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
504
505    /**
506     * All of the processes we currently have running organized by pid.
507     * The keys are the pid running the application.
508     *
509     * <p>NOTE: This object is protected by its own lock, NOT the global
510     * activity manager lock!
511     */
512    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
513
514    /**
515     * All of the processes that have been forced to be foreground.  The key
516     * is the pid of the caller who requested it (we hold a death
517     * link on it).
518     */
519    abstract class ForegroundToken implements IBinder.DeathRecipient {
520        int pid;
521        IBinder token;
522    }
523    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
524
525    /**
526     * List of records for processes that someone had tried to start before the
527     * system was ready.  We don't start them at that point, but ensure they
528     * are started by the time booting is complete.
529     */
530    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
531
532    /**
533     * List of persistent applications that are in the process
534     * of being started.
535     */
536    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * Processes that are being forcibly torn down.
540     */
541    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
542
543    /**
544     * List of running applications, sorted by recent usage.
545     * The first entry in the list is the least recently used.
546     */
547    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
548
549    /**
550     * Where in mLruProcesses that the processes hosting activities start.
551     */
552    int mLruProcessActivityStart = 0;
553
554    /**
555     * Where in mLruProcesses that the processes hosting services start.
556     * This is after (lower index) than mLruProcessesActivityStart.
557     */
558    int mLruProcessServiceStart = 0;
559
560    /**
561     * List of processes that should gc as soon as things are idle.
562     */
563    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
564
565    /**
566     * Processes we want to collect PSS data from.
567     */
568    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
569
570    /**
571     * Last time we requested PSS data of all processes.
572     */
573    long mLastFullPssTime = SystemClock.uptimeMillis();
574
575    /**
576     * If set, the next time we collect PSS data we should do a full collection
577     * with data from native processes and the kernel.
578     */
579    boolean mFullPssPending = false;
580
581    /**
582     * This is the process holding what we currently consider to be
583     * the "home" activity.
584     */
585    ProcessRecord mHomeProcess;
586
587    /**
588     * This is the process holding the activity the user last visited that
589     * is in a different process from the one they are currently in.
590     */
591    ProcessRecord mPreviousProcess;
592
593    /**
594     * The time at which the previous process was last visible.
595     */
596    long mPreviousProcessVisibleTime;
597
598    /**
599     * Which uses have been started, so are allowed to run code.
600     */
601    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
602
603    /**
604     * LRU list of history of current users.  Most recently current is at the end.
605     */
606    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
607
608    /**
609     * Constant array of the users that are currently started.
610     */
611    int[] mStartedUserArray = new int[] { 0 };
612
613    /**
614     * Registered observers of the user switching mechanics.
615     */
616    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
617            = new RemoteCallbackList<IUserSwitchObserver>();
618
619    /**
620     * Currently active user switch.
621     */
622    Object mCurUserSwitchCallback;
623
624    /**
625     * Packages that the user has asked to have run in screen size
626     * compatibility mode instead of filling the screen.
627     */
628    final CompatModePackages mCompatModePackages;
629
630    /**
631     * Set of IntentSenderRecord objects that are currently active.
632     */
633    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
634            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
635
636    /**
637     * Fingerprints (hashCode()) of stack traces that we've
638     * already logged DropBox entries for.  Guarded by itself.  If
639     * something (rogue user app) forces this over
640     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
641     */
642    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
643    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
644
645    /**
646     * Strict Mode background batched logging state.
647     *
648     * The string buffer is guarded by itself, and its lock is also
649     * used to determine if another batched write is already
650     * in-flight.
651     */
652    private final StringBuilder mStrictModeBuffer = new StringBuilder();
653
654    /**
655     * Keeps track of all IIntentReceivers that have been registered for
656     * broadcasts.  Hash keys are the receiver IBinder, hash value is
657     * a ReceiverList.
658     */
659    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
660            new HashMap<IBinder, ReceiverList>();
661
662    /**
663     * Resolver for broadcast intents to registered receivers.
664     * Holds BroadcastFilter (subclass of IntentFilter).
665     */
666    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
667            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
668        @Override
669        protected boolean allowFilterResult(
670                BroadcastFilter filter, List<BroadcastFilter> dest) {
671            IBinder target = filter.receiverList.receiver.asBinder();
672            for (int i=dest.size()-1; i>=0; i--) {
673                if (dest.get(i).receiverList.receiver.asBinder() == target) {
674                    return false;
675                }
676            }
677            return true;
678        }
679
680        @Override
681        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
682            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
683                    || userId == filter.owningUserId) {
684                return super.newResult(filter, match, userId);
685            }
686            return null;
687        }
688
689        @Override
690        protected BroadcastFilter[] newArray(int size) {
691            return new BroadcastFilter[size];
692        }
693
694        @Override
695        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
696            return packageName.equals(filter.packageName);
697        }
698    };
699
700    /**
701     * State of all active sticky broadcasts per user.  Keys are the action of the
702     * sticky Intent, values are an ArrayList of all broadcasted intents with
703     * that action (which should usually be one).  The SparseArray is keyed
704     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
705     * for stickies that are sent to all users.
706     */
707    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
708            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
709
710    final ActiveServices mServices;
711
712    /**
713     * Backup/restore process management
714     */
715    String mBackupAppName = null;
716    BackupRecord mBackupTarget = null;
717
718    final ProviderMap mProviderMap;
719
720    /**
721     * List of content providers who have clients waiting for them.  The
722     * application is currently being launched and the provider will be
723     * removed from this list once it is published.
724     */
725    final ArrayList<ContentProviderRecord> mLaunchingProviders
726            = new ArrayList<ContentProviderRecord>();
727
728    /**
729     * File storing persisted {@link #mGrantedUriPermissions}.
730     */
731    private final AtomicFile mGrantFile;
732
733    /** XML constants used in {@link #mGrantFile} */
734    private static final String TAG_URI_GRANTS = "uri-grants";
735    private static final String TAG_URI_GRANT = "uri-grant";
736    private static final String ATTR_USER_HANDLE = "userHandle";
737    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
738    private static final String ATTR_TARGET_USER_ID = "targetUserId";
739    private static final String ATTR_SOURCE_PKG = "sourcePkg";
740    private static final String ATTR_TARGET_PKG = "targetPkg";
741    private static final String ATTR_URI = "uri";
742    private static final String ATTR_MODE_FLAGS = "modeFlags";
743    private static final String ATTR_CREATED_TIME = "createdTime";
744    private static final String ATTR_PREFIX = "prefix";
745
746    /**
747     * Global set of specific {@link Uri} permissions that have been granted.
748     * This optimized lookup structure maps from {@link UriPermission#targetUid}
749     * to {@link UriPermission#uri} to {@link UriPermission}.
750     */
751    @GuardedBy("this")
752    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
753            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
754
755    public static class GrantUri {
756        public final int sourceUserId;
757        public final Uri uri;
758        public boolean prefix;
759
760        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
761            this.sourceUserId = sourceUserId;
762            this.uri = uri;
763            this.prefix = prefix;
764        }
765
766        @Override
767        public int hashCode() {
768            return toString().hashCode();
769        }
770
771        @Override
772        public boolean equals(Object o) {
773            if (o instanceof GrantUri) {
774                GrantUri other = (GrantUri) o;
775                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
776                        && prefix == other.prefix;
777            }
778            return false;
779        }
780
781        @Override
782        public String toString() {
783            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
784            if (prefix) result += " [prefix]";
785            return result;
786        }
787
788        public String toSafeString() {
789            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
790            if (prefix) result += " [prefix]";
791            return result;
792        }
793
794        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
795            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
796                    ContentProvider.getUriWithoutUserId(uri), false);
797        }
798    }
799
800    CoreSettingsObserver mCoreSettingsObserver;
801
802    /**
803     * Thread-local storage used to carry caller permissions over through
804     * indirect content-provider access.
805     */
806    private class Identity {
807        public int pid;
808        public int uid;
809
810        Identity(int _pid, int _uid) {
811            pid = _pid;
812            uid = _uid;
813        }
814    }
815
816    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
817
818    /**
819     * All information we have collected about the runtime performance of
820     * any user id that can impact battery performance.
821     */
822    final BatteryStatsService mBatteryStatsService;
823
824    /**
825     * Information about component usage
826     */
827    final UsageStatsService mUsageStatsService;
828
829    /**
830     * Information about and control over application operations
831     */
832    final AppOpsService mAppOpsService;
833
834    /**
835     * Save recent tasks information across reboots.
836     */
837    final TaskPersister mTaskPersister;
838
839    /**
840     * Current configuration information.  HistoryRecord objects are given
841     * a reference to this object to indicate which configuration they are
842     * currently running in, so this object must be kept immutable.
843     */
844    Configuration mConfiguration = new Configuration();
845
846    /**
847     * Current sequencing integer of the configuration, for skipping old
848     * configurations.
849     */
850    int mConfigurationSeq = 0;
851
852    /**
853     * Hardware-reported OpenGLES version.
854     */
855    final int GL_ES_VERSION;
856
857    /**
858     * List of initialization arguments to pass to all processes when binding applications to them.
859     * For example, references to the commonly used services.
860     */
861    HashMap<String, IBinder> mAppBindArgs;
862
863    /**
864     * Temporary to avoid allocations.  Protected by main lock.
865     */
866    final StringBuilder mStringBuilder = new StringBuilder(256);
867
868    /**
869     * Used to control how we initialize the service.
870     */
871    ComponentName mTopComponent;
872    String mTopAction = Intent.ACTION_MAIN;
873    String mTopData;
874    boolean mProcessesReady = false;
875    boolean mSystemReady = false;
876    boolean mBooting = false;
877    boolean mWaitingUpdate = false;
878    boolean mDidUpdate = false;
879    boolean mOnBattery = false;
880    boolean mLaunchWarningShown = false;
881
882    Context mContext;
883
884    int mFactoryTest;
885
886    boolean mCheckedForSetup;
887
888    /**
889     * The time at which we will allow normal application switches again,
890     * after a call to {@link #stopAppSwitches()}.
891     */
892    long mAppSwitchesAllowedTime;
893
894    /**
895     * This is set to true after the first switch after mAppSwitchesAllowedTime
896     * is set; any switches after that will clear the time.
897     */
898    boolean mDidAppSwitch;
899
900    /**
901     * Last time (in realtime) at which we checked for power usage.
902     */
903    long mLastPowerCheckRealtime;
904
905    /**
906     * Last time (in uptime) at which we checked for power usage.
907     */
908    long mLastPowerCheckUptime;
909
910    /**
911     * Set while we are wanting to sleep, to prevent any
912     * activities from being started/resumed.
913     */
914    private boolean mSleeping = false;
915
916    /**
917     * Set while we are running a voice interaction.  This overrides
918     * sleeping while it is active.
919     */
920    private boolean mRunningVoice = false;
921
922    /**
923     * State of external calls telling us if the device is asleep.
924     */
925    private boolean mWentToSleep = false;
926
927    /**
928     * State of external call telling us if the lock screen is shown.
929     */
930    private boolean mLockScreenShown = false;
931
932    /**
933     * Set if we are shutting down the system, similar to sleeping.
934     */
935    boolean mShuttingDown = false;
936
937    /**
938     * Current sequence id for oom_adj computation traversal.
939     */
940    int mAdjSeq = 0;
941
942    /**
943     * Current sequence id for process LRU updating.
944     */
945    int mLruSeq = 0;
946
947    /**
948     * Keep track of the non-cached/empty process we last found, to help
949     * determine how to distribute cached/empty processes next time.
950     */
951    int mNumNonCachedProcs = 0;
952
953    /**
954     * Keep track of the number of cached hidden procs, to balance oom adj
955     * distribution between those and empty procs.
956     */
957    int mNumCachedHiddenProcs = 0;
958
959    /**
960     * Keep track of the number of service processes we last found, to
961     * determine on the next iteration which should be B services.
962     */
963    int mNumServiceProcs = 0;
964    int mNewNumAServiceProcs = 0;
965    int mNewNumServiceProcs = 0;
966
967    /**
968     * Allow the current computed overall memory level of the system to go down?
969     * This is set to false when we are killing processes for reasons other than
970     * memory management, so that the now smaller process list will not be taken as
971     * an indication that memory is tighter.
972     */
973    boolean mAllowLowerMemLevel = false;
974
975    /**
976     * The last computed memory level, for holding when we are in a state that
977     * processes are going away for other reasons.
978     */
979    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
980
981    /**
982     * The last total number of process we have, to determine if changes actually look
983     * like a shrinking number of process due to lower RAM.
984     */
985    int mLastNumProcesses;
986
987    /**
988     * The uptime of the last time we performed idle maintenance.
989     */
990    long mLastIdleTime = SystemClock.uptimeMillis();
991
992    /**
993     * Total time spent with RAM that has been added in the past since the last idle time.
994     */
995    long mLowRamTimeSinceLastIdle = 0;
996
997    /**
998     * If RAM is currently low, when that horrible situation started.
999     */
1000    long mLowRamStartTime = 0;
1001
1002    /**
1003     * For reporting to battery stats the current top application.
1004     */
1005    private String mCurResumedPackage = null;
1006    private int mCurResumedUid = -1;
1007
1008    /**
1009     * For reporting to battery stats the apps currently running foreground
1010     * service.  The ProcessMap is package/uid tuples; each of these contain
1011     * an array of the currently foreground processes.
1012     */
1013    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1014            = new ProcessMap<ArrayList<ProcessRecord>>();
1015
1016    /**
1017     * This is set if we had to do a delayed dexopt of an app before launching
1018     * it, to increase the ANR timeouts in that case.
1019     */
1020    boolean mDidDexOpt;
1021
1022    /**
1023     * Set if the systemServer made a call to enterSafeMode.
1024     */
1025    boolean mSafeMode;
1026
1027    String mDebugApp = null;
1028    boolean mWaitForDebugger = false;
1029    boolean mDebugTransient = false;
1030    String mOrigDebugApp = null;
1031    boolean mOrigWaitForDebugger = false;
1032    boolean mAlwaysFinishActivities = false;
1033    IActivityController mController = null;
1034    String mProfileApp = null;
1035    ProcessRecord mProfileProc = null;
1036    String mProfileFile;
1037    ParcelFileDescriptor mProfileFd;
1038    int mProfileType = 0;
1039    boolean mAutoStopProfiler = false;
1040    String mOpenGlTraceApp = null;
1041
1042    static class ProcessChangeItem {
1043        static final int CHANGE_ACTIVITIES = 1<<0;
1044        static final int CHANGE_PROCESS_STATE = 1<<1;
1045        int changes;
1046        int uid;
1047        int pid;
1048        int processState;
1049        boolean foregroundActivities;
1050    }
1051
1052    final RemoteCallbackList<IProcessObserver> mProcessObservers
1053            = new RemoteCallbackList<IProcessObserver>();
1054    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1055
1056    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1057            = new ArrayList<ProcessChangeItem>();
1058    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1059            = new ArrayList<ProcessChangeItem>();
1060
1061    /**
1062     * Runtime CPU use collection thread.  This object's lock is used to
1063     * protect all related state.
1064     */
1065    final Thread mProcessCpuThread;
1066
1067    /**
1068     * Used to collect process stats when showing not responding dialog.
1069     * Protected by mProcessCpuThread.
1070     */
1071    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1072            MONITOR_THREAD_CPU_USAGE);
1073    final AtomicLong mLastCpuTime = new AtomicLong(0);
1074    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1075
1076    long mLastWriteTime = 0;
1077
1078    /**
1079     * Used to retain an update lock when the foreground activity is in
1080     * immersive mode.
1081     */
1082    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1083
1084    /**
1085     * Set to true after the system has finished booting.
1086     */
1087    boolean mBooted = false;
1088
1089    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1090    int mProcessLimitOverride = -1;
1091
1092    WindowManagerService mWindowManager;
1093
1094    final ActivityThread mSystemThread;
1095
1096    int mCurrentUserId = 0;
1097    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1098    private UserManagerService mUserManager;
1099
1100    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1101        final ProcessRecord mApp;
1102        final int mPid;
1103        final IApplicationThread mAppThread;
1104
1105        AppDeathRecipient(ProcessRecord app, int pid,
1106                IApplicationThread thread) {
1107            if (localLOGV) Slog.v(
1108                TAG, "New death recipient " + this
1109                + " for thread " + thread.asBinder());
1110            mApp = app;
1111            mPid = pid;
1112            mAppThread = thread;
1113        }
1114
1115        @Override
1116        public void binderDied() {
1117            if (localLOGV) Slog.v(
1118                TAG, "Death received in " + this
1119                + " for thread " + mAppThread.asBinder());
1120            synchronized(ActivityManagerService.this) {
1121                appDiedLocked(mApp, mPid, mAppThread);
1122            }
1123        }
1124    }
1125
1126    static final int SHOW_ERROR_MSG = 1;
1127    static final int SHOW_NOT_RESPONDING_MSG = 2;
1128    static final int SHOW_FACTORY_ERROR_MSG = 3;
1129    static final int UPDATE_CONFIGURATION_MSG = 4;
1130    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1131    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1132    static final int SERVICE_TIMEOUT_MSG = 12;
1133    static final int UPDATE_TIME_ZONE = 13;
1134    static final int SHOW_UID_ERROR_MSG = 14;
1135    static final int IM_FEELING_LUCKY_MSG = 15;
1136    static final int PROC_START_TIMEOUT_MSG = 20;
1137    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1138    static final int KILL_APPLICATION_MSG = 22;
1139    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1140    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1141    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1142    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1143    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1144    static final int CLEAR_DNS_CACHE_MSG = 28;
1145    static final int UPDATE_HTTP_PROXY_MSG = 29;
1146    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1147    static final int DISPATCH_PROCESSES_CHANGED = 31;
1148    static final int DISPATCH_PROCESS_DIED = 32;
1149    static final int REPORT_MEM_USAGE_MSG = 33;
1150    static final int REPORT_USER_SWITCH_MSG = 34;
1151    static final int CONTINUE_USER_SWITCH_MSG = 35;
1152    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1153    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1154    static final int PERSIST_URI_GRANTS_MSG = 38;
1155    static final int REQUEST_ALL_PSS_MSG = 39;
1156    static final int START_PROFILES_MSG = 40;
1157    static final int UPDATE_TIME = 41;
1158    static final int SYSTEM_USER_START_MSG = 42;
1159    static final int SYSTEM_USER_CURRENT_MSG = 43;
1160
1161    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1162    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1163    static final int FIRST_COMPAT_MODE_MSG = 300;
1164    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1165
1166    AlertDialog mUidAlert;
1167    CompatModeDialog mCompatModeDialog;
1168    long mLastMemUsageReportTime = 0;
1169
1170    private LockToAppRequestDialog mLockToAppRequest;
1171
1172    /**
1173     * Flag whether the current user is a "monkey", i.e. whether
1174     * the UI is driven by a UI automation tool.
1175     */
1176    private boolean mUserIsMonkey;
1177
1178    final ServiceThread mHandlerThread;
1179    final MainHandler mHandler;
1180
1181    final class MainHandler extends Handler {
1182        public MainHandler(Looper looper) {
1183            super(looper, null, true);
1184        }
1185
1186        @Override
1187        public void handleMessage(Message msg) {
1188            switch (msg.what) {
1189            case SHOW_ERROR_MSG: {
1190                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1191                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1192                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1193                synchronized (ActivityManagerService.this) {
1194                    ProcessRecord proc = (ProcessRecord)data.get("app");
1195                    AppErrorResult res = (AppErrorResult) data.get("result");
1196                    if (proc != null && proc.crashDialog != null) {
1197                        Slog.e(TAG, "App already has crash dialog: " + proc);
1198                        if (res != null) {
1199                            res.set(0);
1200                        }
1201                        return;
1202                    }
1203                    if (!showBackground && UserHandle.getAppId(proc.uid)
1204                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1205                            && proc.pid != MY_PID) {
1206                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1207                        if (res != null) {
1208                            res.set(0);
1209                        }
1210                        return;
1211                    }
1212                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1213                        Dialog d = new AppErrorDialog(mContext,
1214                                ActivityManagerService.this, res, proc);
1215                        d.show();
1216                        proc.crashDialog = d;
1217                    } else {
1218                        // The device is asleep, so just pretend that the user
1219                        // saw a crash dialog and hit "force quit".
1220                        if (res != null) {
1221                            res.set(0);
1222                        }
1223                    }
1224                }
1225
1226                ensureBootCompleted();
1227            } break;
1228            case SHOW_NOT_RESPONDING_MSG: {
1229                synchronized (ActivityManagerService.this) {
1230                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1231                    ProcessRecord proc = (ProcessRecord)data.get("app");
1232                    if (proc != null && proc.anrDialog != null) {
1233                        Slog.e(TAG, "App already has anr dialog: " + proc);
1234                        return;
1235                    }
1236
1237                    Intent intent = new Intent("android.intent.action.ANR");
1238                    if (!mProcessesReady) {
1239                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1240                                | Intent.FLAG_RECEIVER_FOREGROUND);
1241                    }
1242                    broadcastIntentLocked(null, null, intent,
1243                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1244                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1245
1246                    if (mShowDialogs) {
1247                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1248                                mContext, proc, (ActivityRecord)data.get("activity"),
1249                                msg.arg1 != 0);
1250                        d.show();
1251                        proc.anrDialog = d;
1252                    } else {
1253                        // Just kill the app if there is no dialog to be shown.
1254                        killAppAtUsersRequest(proc, null);
1255                    }
1256                }
1257
1258                ensureBootCompleted();
1259            } break;
1260            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1261                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1262                synchronized (ActivityManagerService.this) {
1263                    ProcessRecord proc = (ProcessRecord) data.get("app");
1264                    if (proc == null) {
1265                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1266                        break;
1267                    }
1268                    if (proc.crashDialog != null) {
1269                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1270                        return;
1271                    }
1272                    AppErrorResult res = (AppErrorResult) data.get("result");
1273                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1274                        Dialog d = new StrictModeViolationDialog(mContext,
1275                                ActivityManagerService.this, res, proc);
1276                        d.show();
1277                        proc.crashDialog = d;
1278                    } else {
1279                        // The device is asleep, so just pretend that the user
1280                        // saw a crash dialog and hit "force quit".
1281                        res.set(0);
1282                    }
1283                }
1284                ensureBootCompleted();
1285            } break;
1286            case SHOW_FACTORY_ERROR_MSG: {
1287                Dialog d = new FactoryErrorDialog(
1288                    mContext, msg.getData().getCharSequence("msg"));
1289                d.show();
1290                ensureBootCompleted();
1291            } break;
1292            case UPDATE_CONFIGURATION_MSG: {
1293                final ContentResolver resolver = mContext.getContentResolver();
1294                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1295            } break;
1296            case GC_BACKGROUND_PROCESSES_MSG: {
1297                synchronized (ActivityManagerService.this) {
1298                    performAppGcsIfAppropriateLocked();
1299                }
1300            } break;
1301            case WAIT_FOR_DEBUGGER_MSG: {
1302                synchronized (ActivityManagerService.this) {
1303                    ProcessRecord app = (ProcessRecord)msg.obj;
1304                    if (msg.arg1 != 0) {
1305                        if (!app.waitedForDebugger) {
1306                            Dialog d = new AppWaitingForDebuggerDialog(
1307                                    ActivityManagerService.this,
1308                                    mContext, app);
1309                            app.waitDialog = d;
1310                            app.waitedForDebugger = true;
1311                            d.show();
1312                        }
1313                    } else {
1314                        if (app.waitDialog != null) {
1315                            app.waitDialog.dismiss();
1316                            app.waitDialog = null;
1317                        }
1318                    }
1319                }
1320            } break;
1321            case SERVICE_TIMEOUT_MSG: {
1322                if (mDidDexOpt) {
1323                    mDidDexOpt = false;
1324                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1325                    nmsg.obj = msg.obj;
1326                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1327                    return;
1328                }
1329                mServices.serviceTimeout((ProcessRecord)msg.obj);
1330            } break;
1331            case UPDATE_TIME_ZONE: {
1332                synchronized (ActivityManagerService.this) {
1333                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1334                        ProcessRecord r = mLruProcesses.get(i);
1335                        if (r.thread != null) {
1336                            try {
1337                                r.thread.updateTimeZone();
1338                            } catch (RemoteException ex) {
1339                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1340                            }
1341                        }
1342                    }
1343                }
1344            } break;
1345            case CLEAR_DNS_CACHE_MSG: {
1346                synchronized (ActivityManagerService.this) {
1347                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1348                        ProcessRecord r = mLruProcesses.get(i);
1349                        if (r.thread != null) {
1350                            try {
1351                                r.thread.clearDnsCache();
1352                            } catch (RemoteException ex) {
1353                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1354                            }
1355                        }
1356                    }
1357                }
1358            } break;
1359            case UPDATE_HTTP_PROXY_MSG: {
1360                ProxyInfo proxy = (ProxyInfo)msg.obj;
1361                String host = "";
1362                String port = "";
1363                String exclList = "";
1364                Uri pacFileUrl = Uri.EMPTY;
1365                if (proxy != null) {
1366                    host = proxy.getHost();
1367                    port = Integer.toString(proxy.getPort());
1368                    exclList = proxy.getExclusionListAsString();
1369                    pacFileUrl = proxy.getPacFileUrl();
1370                }
1371                synchronized (ActivityManagerService.this) {
1372                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1373                        ProcessRecord r = mLruProcesses.get(i);
1374                        if (r.thread != null) {
1375                            try {
1376                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1377                            } catch (RemoteException ex) {
1378                                Slog.w(TAG, "Failed to update http proxy for: " +
1379                                        r.info.processName);
1380                            }
1381                        }
1382                    }
1383                }
1384            } break;
1385            case SHOW_UID_ERROR_MSG: {
1386                String title = "System UIDs Inconsistent";
1387                String text = "UIDs on the system are inconsistent, you need to wipe your"
1388                        + " data partition or your device will be unstable.";
1389                Log.e(TAG, title + ": " + text);
1390                if (mShowDialogs) {
1391                    // XXX This is a temporary dialog, no need to localize.
1392                    AlertDialog d = new BaseErrorDialog(mContext);
1393                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1394                    d.setCancelable(false);
1395                    d.setTitle(title);
1396                    d.setMessage(text);
1397                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1398                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1399                    mUidAlert = d;
1400                    d.show();
1401                }
1402            } break;
1403            case IM_FEELING_LUCKY_MSG: {
1404                if (mUidAlert != null) {
1405                    mUidAlert.dismiss();
1406                    mUidAlert = null;
1407                }
1408            } break;
1409            case PROC_START_TIMEOUT_MSG: {
1410                if (mDidDexOpt) {
1411                    mDidDexOpt = false;
1412                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1413                    nmsg.obj = msg.obj;
1414                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1415                    return;
1416                }
1417                ProcessRecord app = (ProcessRecord)msg.obj;
1418                synchronized (ActivityManagerService.this) {
1419                    processStartTimedOutLocked(app);
1420                }
1421            } break;
1422            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1423                synchronized (ActivityManagerService.this) {
1424                    doPendingActivityLaunchesLocked(true);
1425                }
1426            } break;
1427            case KILL_APPLICATION_MSG: {
1428                synchronized (ActivityManagerService.this) {
1429                    int appid = msg.arg1;
1430                    boolean restart = (msg.arg2 == 1);
1431                    Bundle bundle = (Bundle)msg.obj;
1432                    String pkg = bundle.getString("pkg");
1433                    String reason = bundle.getString("reason");
1434                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1435                            false, UserHandle.USER_ALL, reason);
1436                }
1437            } break;
1438            case FINALIZE_PENDING_INTENT_MSG: {
1439                ((PendingIntentRecord)msg.obj).completeFinalize();
1440            } break;
1441            case POST_HEAVY_NOTIFICATION_MSG: {
1442                INotificationManager inm = NotificationManager.getService();
1443                if (inm == null) {
1444                    return;
1445                }
1446
1447                ActivityRecord root = (ActivityRecord)msg.obj;
1448                ProcessRecord process = root.app;
1449                if (process == null) {
1450                    return;
1451                }
1452
1453                try {
1454                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1455                    String text = mContext.getString(R.string.heavy_weight_notification,
1456                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1457                    Notification notification = new Notification();
1458                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1459                    notification.when = 0;
1460                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1461                    notification.tickerText = text;
1462                    notification.defaults = 0; // please be quiet
1463                    notification.sound = null;
1464                    notification.vibrate = null;
1465                    notification.setLatestEventInfo(context, text,
1466                            mContext.getText(R.string.heavy_weight_notification_detail),
1467                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1468                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1469                                    new UserHandle(root.userId)));
1470
1471                    try {
1472                        int[] outId = new int[1];
1473                        inm.enqueueNotificationWithTag("android", "android", null,
1474                                R.string.heavy_weight_notification,
1475                                notification, outId, root.userId);
1476                    } catch (RuntimeException e) {
1477                        Slog.w(ActivityManagerService.TAG,
1478                                "Error showing notification for heavy-weight app", e);
1479                    } catch (RemoteException e) {
1480                    }
1481                } catch (NameNotFoundException e) {
1482                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1483                }
1484            } break;
1485            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1486                INotificationManager inm = NotificationManager.getService();
1487                if (inm == null) {
1488                    return;
1489                }
1490                try {
1491                    inm.cancelNotificationWithTag("android", null,
1492                            R.string.heavy_weight_notification,  msg.arg1);
1493                } catch (RuntimeException e) {
1494                    Slog.w(ActivityManagerService.TAG,
1495                            "Error canceling notification for service", e);
1496                } catch (RemoteException e) {
1497                }
1498            } break;
1499            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1500                synchronized (ActivityManagerService.this) {
1501                    checkExcessivePowerUsageLocked(true);
1502                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1503                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1504                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1505                }
1506            } break;
1507            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1508                synchronized (ActivityManagerService.this) {
1509                    ActivityRecord ar = (ActivityRecord)msg.obj;
1510                    if (mCompatModeDialog != null) {
1511                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1512                                ar.info.applicationInfo.packageName)) {
1513                            return;
1514                        }
1515                        mCompatModeDialog.dismiss();
1516                        mCompatModeDialog = null;
1517                    }
1518                    if (ar != null && false) {
1519                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1520                                ar.packageName)) {
1521                            int mode = mCompatModePackages.computeCompatModeLocked(
1522                                    ar.info.applicationInfo);
1523                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1524                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1525                                mCompatModeDialog = new CompatModeDialog(
1526                                        ActivityManagerService.this, mContext,
1527                                        ar.info.applicationInfo);
1528                                mCompatModeDialog.show();
1529                            }
1530                        }
1531                    }
1532                }
1533                break;
1534            }
1535            case DISPATCH_PROCESSES_CHANGED: {
1536                dispatchProcessesChanged();
1537                break;
1538            }
1539            case DISPATCH_PROCESS_DIED: {
1540                final int pid = msg.arg1;
1541                final int uid = msg.arg2;
1542                dispatchProcessDied(pid, uid);
1543                break;
1544            }
1545            case REPORT_MEM_USAGE_MSG: {
1546                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1547                Thread thread = new Thread() {
1548                    @Override public void run() {
1549                        final SparseArray<ProcessMemInfo> infoMap
1550                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1551                        for (int i=0, N=memInfos.size(); i<N; i++) {
1552                            ProcessMemInfo mi = memInfos.get(i);
1553                            infoMap.put(mi.pid, mi);
1554                        }
1555                        updateCpuStatsNow();
1556                        synchronized (mProcessCpuThread) {
1557                            final int N = mProcessCpuTracker.countStats();
1558                            for (int i=0; i<N; i++) {
1559                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1560                                if (st.vsize > 0) {
1561                                    long pss = Debug.getPss(st.pid, null);
1562                                    if (pss > 0) {
1563                                        if (infoMap.indexOfKey(st.pid) < 0) {
1564                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1565                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1566                                            mi.pss = pss;
1567                                            memInfos.add(mi);
1568                                        }
1569                                    }
1570                                }
1571                            }
1572                        }
1573
1574                        long totalPss = 0;
1575                        for (int i=0, N=memInfos.size(); i<N; i++) {
1576                            ProcessMemInfo mi = memInfos.get(i);
1577                            if (mi.pss == 0) {
1578                                mi.pss = Debug.getPss(mi.pid, null);
1579                            }
1580                            totalPss += mi.pss;
1581                        }
1582                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1583                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1584                                if (lhs.oomAdj != rhs.oomAdj) {
1585                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1586                                }
1587                                if (lhs.pss != rhs.pss) {
1588                                    return lhs.pss < rhs.pss ? 1 : -1;
1589                                }
1590                                return 0;
1591                            }
1592                        });
1593
1594                        StringBuilder tag = new StringBuilder(128);
1595                        StringBuilder stack = new StringBuilder(128);
1596                        tag.append("Low on memory -- ");
1597                        appendMemBucket(tag, totalPss, "total", false);
1598                        appendMemBucket(stack, totalPss, "total", true);
1599
1600                        StringBuilder logBuilder = new StringBuilder(1024);
1601                        logBuilder.append("Low on memory:\n");
1602
1603                        boolean firstLine = true;
1604                        int lastOomAdj = Integer.MIN_VALUE;
1605                        for (int i=0, N=memInfos.size(); i<N; i++) {
1606                            ProcessMemInfo mi = memInfos.get(i);
1607
1608                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1609                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1610                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1611                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1612                                if (lastOomAdj != mi.oomAdj) {
1613                                    lastOomAdj = mi.oomAdj;
1614                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1615                                        tag.append(" / ");
1616                                    }
1617                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1618                                        if (firstLine) {
1619                                            stack.append(":");
1620                                            firstLine = false;
1621                                        }
1622                                        stack.append("\n\t at ");
1623                                    } else {
1624                                        stack.append("$");
1625                                    }
1626                                } else {
1627                                    tag.append(" ");
1628                                    stack.append("$");
1629                                }
1630                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1631                                    appendMemBucket(tag, mi.pss, mi.name, false);
1632                                }
1633                                appendMemBucket(stack, mi.pss, mi.name, true);
1634                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1635                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1636                                    stack.append("(");
1637                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1638                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1639                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1640                                            stack.append(":");
1641                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1642                                        }
1643                                    }
1644                                    stack.append(")");
1645                                }
1646                            }
1647
1648                            logBuilder.append("  ");
1649                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1650                            logBuilder.append(' ');
1651                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1652                            logBuilder.append(' ');
1653                            ProcessList.appendRamKb(logBuilder, mi.pss);
1654                            logBuilder.append(" kB: ");
1655                            logBuilder.append(mi.name);
1656                            logBuilder.append(" (");
1657                            logBuilder.append(mi.pid);
1658                            logBuilder.append(") ");
1659                            logBuilder.append(mi.adjType);
1660                            logBuilder.append('\n');
1661                            if (mi.adjReason != null) {
1662                                logBuilder.append("                      ");
1663                                logBuilder.append(mi.adjReason);
1664                                logBuilder.append('\n');
1665                            }
1666                        }
1667
1668                        logBuilder.append("           ");
1669                        ProcessList.appendRamKb(logBuilder, totalPss);
1670                        logBuilder.append(" kB: TOTAL\n");
1671
1672                        long[] infos = new long[Debug.MEMINFO_COUNT];
1673                        Debug.getMemInfo(infos);
1674                        logBuilder.append("  MemInfo: ");
1675                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1676                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1677                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1678                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1679                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1680                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1681                            logBuilder.append("  ZRAM: ");
1682                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1683                            logBuilder.append(" kB RAM, ");
1684                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1685                            logBuilder.append(" kB swap total, ");
1686                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1687                            logBuilder.append(" kB swap free\n");
1688                        }
1689                        Slog.i(TAG, logBuilder.toString());
1690
1691                        StringBuilder dropBuilder = new StringBuilder(1024);
1692                        /*
1693                        StringWriter oomSw = new StringWriter();
1694                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1695                        StringWriter catSw = new StringWriter();
1696                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1697                        String[] emptyArgs = new String[] { };
1698                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1699                        oomPw.flush();
1700                        String oomString = oomSw.toString();
1701                        */
1702                        dropBuilder.append(stack);
1703                        dropBuilder.append('\n');
1704                        dropBuilder.append('\n');
1705                        dropBuilder.append(logBuilder);
1706                        dropBuilder.append('\n');
1707                        /*
1708                        dropBuilder.append(oomString);
1709                        dropBuilder.append('\n');
1710                        */
1711                        StringWriter catSw = new StringWriter();
1712                        synchronized (ActivityManagerService.this) {
1713                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1714                            String[] emptyArgs = new String[] { };
1715                            catPw.println();
1716                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1717                            catPw.println();
1718                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1719                                    false, false, null);
1720                            catPw.println();
1721                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1722                            catPw.flush();
1723                        }
1724                        dropBuilder.append(catSw.toString());
1725                        addErrorToDropBox("lowmem", null, "system_server", null,
1726                                null, tag.toString(), dropBuilder.toString(), null, null);
1727                        //Slog.i(TAG, "Sent to dropbox:");
1728                        //Slog.i(TAG, dropBuilder.toString());
1729                        synchronized (ActivityManagerService.this) {
1730                            long now = SystemClock.uptimeMillis();
1731                            if (mLastMemUsageReportTime < now) {
1732                                mLastMemUsageReportTime = now;
1733                            }
1734                        }
1735                    }
1736                };
1737                thread.start();
1738                break;
1739            }
1740            case REPORT_USER_SWITCH_MSG: {
1741                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1742                break;
1743            }
1744            case CONTINUE_USER_SWITCH_MSG: {
1745                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1746                break;
1747            }
1748            case USER_SWITCH_TIMEOUT_MSG: {
1749                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1750                break;
1751            }
1752            case IMMERSIVE_MODE_LOCK_MSG: {
1753                final boolean nextState = (msg.arg1 != 0);
1754                if (mUpdateLock.isHeld() != nextState) {
1755                    if (DEBUG_IMMERSIVE) {
1756                        final ActivityRecord r = (ActivityRecord) msg.obj;
1757                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1758                    }
1759                    if (nextState) {
1760                        mUpdateLock.acquire();
1761                    } else {
1762                        mUpdateLock.release();
1763                    }
1764                }
1765                break;
1766            }
1767            case PERSIST_URI_GRANTS_MSG: {
1768                writeGrantedUriPermissions();
1769                break;
1770            }
1771            case REQUEST_ALL_PSS_MSG: {
1772                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1773                break;
1774            }
1775            case START_PROFILES_MSG: {
1776                synchronized (ActivityManagerService.this) {
1777                    startProfilesLocked();
1778                }
1779                break;
1780            }
1781            case UPDATE_TIME: {
1782                synchronized (ActivityManagerService.this) {
1783                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1784                        ProcessRecord r = mLruProcesses.get(i);
1785                        if (r.thread != null) {
1786                            try {
1787                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1788                            } catch (RemoteException ex) {
1789                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1790                            }
1791                        }
1792                    }
1793                }
1794                break;
1795            }
1796            case SYSTEM_USER_START_MSG: {
1797                mSystemServiceManager.startUser(msg.arg1);
1798                break;
1799            }
1800            case SYSTEM_USER_CURRENT_MSG: {
1801                mSystemServiceManager.switchUser(msg.arg1);
1802                break;
1803            }
1804            }
1805        }
1806    };
1807
1808    static final int COLLECT_PSS_BG_MSG = 1;
1809
1810    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1811        @Override
1812        public void handleMessage(Message msg) {
1813            switch (msg.what) {
1814            case COLLECT_PSS_BG_MSG: {
1815                long start = SystemClock.uptimeMillis();
1816                MemInfoReader memInfo = null;
1817                synchronized (ActivityManagerService.this) {
1818                    if (mFullPssPending) {
1819                        mFullPssPending = false;
1820                        memInfo = new MemInfoReader();
1821                    }
1822                }
1823                if (memInfo != null) {
1824                    updateCpuStatsNow();
1825                    long nativeTotalPss = 0;
1826                    synchronized (mProcessCpuThread) {
1827                        final int N = mProcessCpuTracker.countStats();
1828                        for (int j=0; j<N; j++) {
1829                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1830                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1831                                // This is definitely an application process; skip it.
1832                                continue;
1833                            }
1834                            synchronized (mPidsSelfLocked) {
1835                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1836                                    // This is one of our own processes; skip it.
1837                                    continue;
1838                                }
1839                            }
1840                            nativeTotalPss += Debug.getPss(st.pid, null);
1841                        }
1842                    }
1843                    memInfo.readMemInfo();
1844                    synchronized (this) {
1845                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1846                                + (SystemClock.uptimeMillis()-start) + "ms");
1847                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1848                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1849                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1850                                        +memInfo.getSlabSizeKb(),
1851                                nativeTotalPss);
1852                    }
1853                }
1854
1855                int i=0, num=0;
1856                long[] tmp = new long[1];
1857                do {
1858                    ProcessRecord proc;
1859                    int procState;
1860                    int pid;
1861                    synchronized (ActivityManagerService.this) {
1862                        if (i >= mPendingPssProcesses.size()) {
1863                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1864                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1865                            mPendingPssProcesses.clear();
1866                            return;
1867                        }
1868                        proc = mPendingPssProcesses.get(i);
1869                        procState = proc.pssProcState;
1870                        if (proc.thread != null && procState == proc.setProcState) {
1871                            pid = proc.pid;
1872                        } else {
1873                            proc = null;
1874                            pid = 0;
1875                        }
1876                        i++;
1877                    }
1878                    if (proc != null) {
1879                        long pss = Debug.getPss(pid, tmp);
1880                        synchronized (ActivityManagerService.this) {
1881                            if (proc.thread != null && proc.setProcState == procState
1882                                    && proc.pid == pid) {
1883                                num++;
1884                                proc.lastPssTime = SystemClock.uptimeMillis();
1885                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1886                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1887                                        + ": " + pss + " lastPss=" + proc.lastPss
1888                                        + " state=" + ProcessList.makeProcStateString(procState));
1889                                if (proc.initialIdlePss == 0) {
1890                                    proc.initialIdlePss = pss;
1891                                }
1892                                proc.lastPss = pss;
1893                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1894                                    proc.lastCachedPss = pss;
1895                                }
1896                            }
1897                        }
1898                    }
1899                } while (true);
1900            }
1901            }
1902        }
1903    };
1904
1905    /**
1906     * Monitor for package changes and update our internal state.
1907     */
1908    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1909        @Override
1910        public void onPackageRemoved(String packageName, int uid) {
1911            // Remove all tasks with activities in the specified package from the list of recent tasks
1912            synchronized (ActivityManagerService.this) {
1913                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1914                    TaskRecord tr = mRecentTasks.get(i);
1915                    ComponentName cn = tr.intent.getComponent();
1916                    if (cn != null && cn.getPackageName().equals(packageName)) {
1917                        // If the package name matches, remove the task and kill the process
1918                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1919                    }
1920                }
1921            }
1922        }
1923
1924        @Override
1925        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1926            onPackageModified(packageName);
1927            return true;
1928        }
1929
1930        @Override
1931        public void onPackageModified(String packageName) {
1932            final PackageManager pm = mContext.getPackageManager();
1933            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1934                    new ArrayList<Pair<Intent, Integer>>();
1935            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1936            // Copy the list of recent tasks so that we don't hold onto the lock on
1937            // ActivityManagerService for long periods while checking if components exist.
1938            synchronized (ActivityManagerService.this) {
1939                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1940                    TaskRecord tr = mRecentTasks.get(i);
1941                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1942                }
1943            }
1944            // Check the recent tasks and filter out all tasks with components that no longer exist.
1945            Intent tmpI = new Intent();
1946            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1947                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1948                ComponentName cn = p.first.getComponent();
1949                if (cn != null && cn.getPackageName().equals(packageName)) {
1950                    try {
1951                        // Add the task to the list to remove if the component no longer exists
1952                        tmpI.setComponent(cn);
1953                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1954                            tasksToRemove.add(p.second);
1955                        }
1956                    } catch (Exception e) {}
1957                }
1958            }
1959            // Prune all the tasks with removed components from the list of recent tasks
1960            synchronized (ActivityManagerService.this) {
1961                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1962                    // Remove the task but don't kill the process (since other components in that
1963                    // package may still be running and in the background)
1964                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1965                }
1966            }
1967        }
1968
1969        @Override
1970        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1971            // Force stop the specified packages
1972            if (packages != null) {
1973                for (String pkg : packages) {
1974                    synchronized (ActivityManagerService.this) {
1975                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1976                                "finished booting")) {
1977                            return true;
1978                        }
1979                    }
1980                }
1981            }
1982            return false;
1983        }
1984    };
1985
1986    public void setSystemProcess() {
1987        try {
1988            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1989            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1990            ServiceManager.addService("meminfo", new MemBinder(this));
1991            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1992            ServiceManager.addService("dbinfo", new DbBinder(this));
1993            if (MONITOR_CPU_USAGE) {
1994                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1995            }
1996            ServiceManager.addService("permission", new PermissionController(this));
1997
1998            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1999                    "android", STOCK_PM_FLAGS);
2000            mSystemThread.installSystemApplicationInfo(info);
2001
2002            synchronized (this) {
2003                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2004                app.persistent = true;
2005                app.pid = MY_PID;
2006                app.maxAdj = ProcessList.SYSTEM_ADJ;
2007                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2008                mProcessNames.put(app.processName, app.uid, app);
2009                synchronized (mPidsSelfLocked) {
2010                    mPidsSelfLocked.put(app.pid, app);
2011                }
2012                updateLruProcessLocked(app, false, null);
2013                updateOomAdjLocked();
2014            }
2015        } catch (PackageManager.NameNotFoundException e) {
2016            throw new RuntimeException(
2017                    "Unable to find android system package", e);
2018        }
2019    }
2020
2021    public void setWindowManager(WindowManagerService wm) {
2022        mWindowManager = wm;
2023        mStackSupervisor.setWindowManager(wm);
2024    }
2025
2026    public void startObservingNativeCrashes() {
2027        final NativeCrashListener ncl = new NativeCrashListener(this);
2028        ncl.start();
2029    }
2030
2031    public IAppOpsService getAppOpsService() {
2032        return mAppOpsService;
2033    }
2034
2035    static class MemBinder extends Binder {
2036        ActivityManagerService mActivityManagerService;
2037        MemBinder(ActivityManagerService activityManagerService) {
2038            mActivityManagerService = activityManagerService;
2039        }
2040
2041        @Override
2042        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2043            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2044                    != PackageManager.PERMISSION_GRANTED) {
2045                pw.println("Permission Denial: can't dump meminfo from from pid="
2046                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2047                        + " without permission " + android.Manifest.permission.DUMP);
2048                return;
2049            }
2050
2051            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2052        }
2053    }
2054
2055    static class GraphicsBinder extends Binder {
2056        ActivityManagerService mActivityManagerService;
2057        GraphicsBinder(ActivityManagerService activityManagerService) {
2058            mActivityManagerService = activityManagerService;
2059        }
2060
2061        @Override
2062        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2063            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2064                    != PackageManager.PERMISSION_GRANTED) {
2065                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2066                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2067                        + " without permission " + android.Manifest.permission.DUMP);
2068                return;
2069            }
2070
2071            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2072        }
2073    }
2074
2075    static class DbBinder extends Binder {
2076        ActivityManagerService mActivityManagerService;
2077        DbBinder(ActivityManagerService activityManagerService) {
2078            mActivityManagerService = activityManagerService;
2079        }
2080
2081        @Override
2082        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2083            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2084                    != PackageManager.PERMISSION_GRANTED) {
2085                pw.println("Permission Denial: can't dump dbinfo from from pid="
2086                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2087                        + " without permission " + android.Manifest.permission.DUMP);
2088                return;
2089            }
2090
2091            mActivityManagerService.dumpDbInfo(fd, pw, args);
2092        }
2093    }
2094
2095    static class CpuBinder extends Binder {
2096        ActivityManagerService mActivityManagerService;
2097        CpuBinder(ActivityManagerService activityManagerService) {
2098            mActivityManagerService = activityManagerService;
2099        }
2100
2101        @Override
2102        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2103            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2104                    != PackageManager.PERMISSION_GRANTED) {
2105                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2106                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2107                        + " without permission " + android.Manifest.permission.DUMP);
2108                return;
2109            }
2110
2111            synchronized (mActivityManagerService.mProcessCpuThread) {
2112                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2113                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2114                        SystemClock.uptimeMillis()));
2115            }
2116        }
2117    }
2118
2119    public static final class Lifecycle extends SystemService {
2120        private final ActivityManagerService mService;
2121
2122        public Lifecycle(Context context) {
2123            super(context);
2124            mService = new ActivityManagerService(context);
2125        }
2126
2127        @Override
2128        public void onStart() {
2129            mService.start();
2130        }
2131
2132        public ActivityManagerService getService() {
2133            return mService;
2134        }
2135    }
2136
2137    // Note: This method is invoked on the main thread but may need to attach various
2138    // handlers to other threads.  So take care to be explicit about the looper.
2139    public ActivityManagerService(Context systemContext) {
2140        mContext = systemContext;
2141        mFactoryTest = FactoryTest.getMode();
2142        mSystemThread = ActivityThread.currentActivityThread();
2143
2144        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2145
2146        mHandlerThread = new ServiceThread(TAG,
2147                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2148        mHandlerThread.start();
2149        mHandler = new MainHandler(mHandlerThread.getLooper());
2150
2151        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2152                "foreground", BROADCAST_FG_TIMEOUT, false);
2153        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2154                "background", BROADCAST_BG_TIMEOUT, true);
2155        mBroadcastQueues[0] = mFgBroadcastQueue;
2156        mBroadcastQueues[1] = mBgBroadcastQueue;
2157
2158        mServices = new ActiveServices(this);
2159        mProviderMap = new ProviderMap(this);
2160
2161        // TODO: Move creation of battery stats service outside of activity manager service.
2162        File dataDir = Environment.getDataDirectory();
2163        File systemDir = new File(dataDir, "system");
2164        systemDir.mkdirs();
2165        mBatteryStatsService = new BatteryStatsService(new File(
2166                systemDir, "batterystats.bin").toString(), mHandler);
2167        mBatteryStatsService.getActiveStatistics().readLocked();
2168        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2169        mOnBattery = DEBUG_POWER ? true
2170                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2171        mBatteryStatsService.getActiveStatistics().setCallback(this);
2172
2173        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2174
2175        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2176        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2177
2178        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2179
2180        // User 0 is the first and only user that runs at boot.
2181        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2182        mUserLru.add(Integer.valueOf(0));
2183        updateStartedUserArrayLocked();
2184
2185        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2186            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2187
2188        mConfiguration.setToDefaults();
2189        mConfiguration.setLocale(Locale.getDefault());
2190
2191        mConfigurationSeq = mConfiguration.seq = 1;
2192        mProcessCpuTracker.init();
2193
2194        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2195        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2196        mStackSupervisor = new ActivityStackSupervisor(this);
2197        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2198
2199        mProcessCpuThread = new Thread("CpuTracker") {
2200            @Override
2201            public void run() {
2202                while (true) {
2203                    try {
2204                        try {
2205                            synchronized(this) {
2206                                final long now = SystemClock.uptimeMillis();
2207                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2208                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2209                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2210                                //        + ", write delay=" + nextWriteDelay);
2211                                if (nextWriteDelay < nextCpuDelay) {
2212                                    nextCpuDelay = nextWriteDelay;
2213                                }
2214                                if (nextCpuDelay > 0) {
2215                                    mProcessCpuMutexFree.set(true);
2216                                    this.wait(nextCpuDelay);
2217                                }
2218                            }
2219                        } catch (InterruptedException e) {
2220                        }
2221                        updateCpuStatsNow();
2222                    } catch (Exception e) {
2223                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2224                    }
2225                }
2226            }
2227        };
2228
2229        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2230
2231        Watchdog.getInstance().addMonitor(this);
2232        Watchdog.getInstance().addThread(mHandler);
2233    }
2234
2235    public void setSystemServiceManager(SystemServiceManager mgr) {
2236        mSystemServiceManager = mgr;
2237    }
2238
2239    private void start() {
2240        mProcessCpuThread.start();
2241
2242        mBatteryStatsService.publish(mContext);
2243        mUsageStatsService.publish(mContext);
2244        mAppOpsService.publish(mContext);
2245        Slog.d("AppOps", "AppOpsService published");
2246        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2247    }
2248
2249    public void initPowerManagement() {
2250        mStackSupervisor.initPowerManagement();
2251        mBatteryStatsService.initPowerManagement();
2252    }
2253
2254    @Override
2255    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2256            throws RemoteException {
2257        if (code == SYSPROPS_TRANSACTION) {
2258            // We need to tell all apps about the system property change.
2259            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2260            synchronized(this) {
2261                final int NP = mProcessNames.getMap().size();
2262                for (int ip=0; ip<NP; ip++) {
2263                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2264                    final int NA = apps.size();
2265                    for (int ia=0; ia<NA; ia++) {
2266                        ProcessRecord app = apps.valueAt(ia);
2267                        if (app.thread != null) {
2268                            procs.add(app.thread.asBinder());
2269                        }
2270                    }
2271                }
2272            }
2273
2274            int N = procs.size();
2275            for (int i=0; i<N; i++) {
2276                Parcel data2 = Parcel.obtain();
2277                try {
2278                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2279                } catch (RemoteException e) {
2280                }
2281                data2.recycle();
2282            }
2283        }
2284        try {
2285            return super.onTransact(code, data, reply, flags);
2286        } catch (RuntimeException e) {
2287            // The activity manager only throws security exceptions, so let's
2288            // log all others.
2289            if (!(e instanceof SecurityException)) {
2290                Slog.wtf(TAG, "Activity Manager Crash", e);
2291            }
2292            throw e;
2293        }
2294    }
2295
2296    void updateCpuStats() {
2297        final long now = SystemClock.uptimeMillis();
2298        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2299            return;
2300        }
2301        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2302            synchronized (mProcessCpuThread) {
2303                mProcessCpuThread.notify();
2304            }
2305        }
2306    }
2307
2308    void updateCpuStatsNow() {
2309        synchronized (mProcessCpuThread) {
2310            mProcessCpuMutexFree.set(false);
2311            final long now = SystemClock.uptimeMillis();
2312            boolean haveNewCpuStats = false;
2313
2314            if (MONITOR_CPU_USAGE &&
2315                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2316                mLastCpuTime.set(now);
2317                haveNewCpuStats = true;
2318                mProcessCpuTracker.update();
2319                //Slog.i(TAG, mProcessCpu.printCurrentState());
2320                //Slog.i(TAG, "Total CPU usage: "
2321                //        + mProcessCpu.getTotalCpuPercent() + "%");
2322
2323                // Slog the cpu usage if the property is set.
2324                if ("true".equals(SystemProperties.get("events.cpu"))) {
2325                    int user = mProcessCpuTracker.getLastUserTime();
2326                    int system = mProcessCpuTracker.getLastSystemTime();
2327                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2328                    int irq = mProcessCpuTracker.getLastIrqTime();
2329                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2330                    int idle = mProcessCpuTracker.getLastIdleTime();
2331
2332                    int total = user + system + iowait + irq + softIrq + idle;
2333                    if (total == 0) total = 1;
2334
2335                    EventLog.writeEvent(EventLogTags.CPU,
2336                            ((user+system+iowait+irq+softIrq) * 100) / total,
2337                            (user * 100) / total,
2338                            (system * 100) / total,
2339                            (iowait * 100) / total,
2340                            (irq * 100) / total,
2341                            (softIrq * 100) / total);
2342                }
2343            }
2344
2345            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2346            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2347            synchronized(bstats) {
2348                synchronized(mPidsSelfLocked) {
2349                    if (haveNewCpuStats) {
2350                        if (mOnBattery) {
2351                            int perc = bstats.startAddingCpuLocked();
2352                            int totalUTime = 0;
2353                            int totalSTime = 0;
2354                            final int N = mProcessCpuTracker.countStats();
2355                            for (int i=0; i<N; i++) {
2356                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2357                                if (!st.working) {
2358                                    continue;
2359                                }
2360                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2361                                int otherUTime = (st.rel_utime*perc)/100;
2362                                int otherSTime = (st.rel_stime*perc)/100;
2363                                totalUTime += otherUTime;
2364                                totalSTime += otherSTime;
2365                                if (pr != null) {
2366                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2367                                    if (ps == null || !ps.isActive()) {
2368                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2369                                                pr.info.uid, pr.processName);
2370                                    }
2371                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2372                                            st.rel_stime-otherSTime);
2373                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2374                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2375                                } else {
2376                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2377                                    if (ps == null || !ps.isActive()) {
2378                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2379                                                bstats.mapUid(st.uid), st.name);
2380                                    }
2381                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2382                                            st.rel_stime-otherSTime);
2383                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2384                                }
2385                            }
2386                            bstats.finishAddingCpuLocked(perc, totalUTime,
2387                                    totalSTime, cpuSpeedTimes);
2388                        }
2389                    }
2390                }
2391
2392                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2393                    mLastWriteTime = now;
2394                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2395                }
2396            }
2397        }
2398    }
2399
2400    @Override
2401    public void batteryNeedsCpuUpdate() {
2402        updateCpuStatsNow();
2403    }
2404
2405    @Override
2406    public void batteryPowerChanged(boolean onBattery) {
2407        // When plugging in, update the CPU stats first before changing
2408        // the plug state.
2409        updateCpuStatsNow();
2410        synchronized (this) {
2411            synchronized(mPidsSelfLocked) {
2412                mOnBattery = DEBUG_POWER ? true : onBattery;
2413            }
2414        }
2415    }
2416
2417    /**
2418     * Initialize the application bind args. These are passed to each
2419     * process when the bindApplication() IPC is sent to the process. They're
2420     * lazily setup to make sure the services are running when they're asked for.
2421     */
2422    private HashMap<String, IBinder> getCommonServicesLocked() {
2423        if (mAppBindArgs == null) {
2424            mAppBindArgs = new HashMap<String, IBinder>();
2425
2426            // Setup the application init args
2427            mAppBindArgs.put("package", ServiceManager.getService("package"));
2428            mAppBindArgs.put("window", ServiceManager.getService("window"));
2429            mAppBindArgs.put(Context.ALARM_SERVICE,
2430                    ServiceManager.getService(Context.ALARM_SERVICE));
2431        }
2432        return mAppBindArgs;
2433    }
2434
2435    final void setFocusedActivityLocked(ActivityRecord r) {
2436        if (mFocusedActivity != r) {
2437            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2438            mFocusedActivity = r;
2439            if (r.task != null && r.task.voiceInteractor != null) {
2440                startRunningVoiceLocked();
2441            } else {
2442                finishRunningVoiceLocked();
2443            }
2444            mStackSupervisor.setFocusedStack(r);
2445            if (r != null) {
2446                mWindowManager.setFocusedApp(r.appToken, true);
2447            }
2448            applyUpdateLockStateLocked(r);
2449        }
2450    }
2451
2452    final void clearFocusedActivity(ActivityRecord r) {
2453        if (mFocusedActivity == r) {
2454            mFocusedActivity = null;
2455        }
2456    }
2457
2458    @Override
2459    public void setFocusedStack(int stackId) {
2460        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2461        synchronized (ActivityManagerService.this) {
2462            ActivityStack stack = mStackSupervisor.getStack(stackId);
2463            if (stack != null) {
2464                ActivityRecord r = stack.topRunningActivityLocked(null);
2465                if (r != null) {
2466                    setFocusedActivityLocked(r);
2467                }
2468            }
2469        }
2470    }
2471
2472    @Override
2473    public void notifyActivityDrawn(IBinder token) {
2474        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2475        synchronized (this) {
2476            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2477            if (r != null) {
2478                r.task.stack.notifyActivityDrawnLocked(r);
2479            }
2480        }
2481    }
2482
2483    final void applyUpdateLockStateLocked(ActivityRecord r) {
2484        // Modifications to the UpdateLock state are done on our handler, outside
2485        // the activity manager's locks.  The new state is determined based on the
2486        // state *now* of the relevant activity record.  The object is passed to
2487        // the handler solely for logging detail, not to be consulted/modified.
2488        final boolean nextState = r != null && r.immersive;
2489        mHandler.sendMessage(
2490                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2491    }
2492
2493    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2494        Message msg = Message.obtain();
2495        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2496        msg.obj = r.task.askedCompatMode ? null : r;
2497        mHandler.sendMessage(msg);
2498    }
2499
2500    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2501            String what, Object obj, ProcessRecord srcApp) {
2502        app.lastActivityTime = now;
2503
2504        if (app.activities.size() > 0) {
2505            // Don't want to touch dependent processes that are hosting activities.
2506            return index;
2507        }
2508
2509        int lrui = mLruProcesses.lastIndexOf(app);
2510        if (lrui < 0) {
2511            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2512                    + what + " " + obj + " from " + srcApp);
2513            return index;
2514        }
2515
2516        if (lrui >= index) {
2517            // Don't want to cause this to move dependent processes *back* in the
2518            // list as if they were less frequently used.
2519            return index;
2520        }
2521
2522        if (lrui >= mLruProcessActivityStart) {
2523            // Don't want to touch dependent processes that are hosting activities.
2524            return index;
2525        }
2526
2527        mLruProcesses.remove(lrui);
2528        if (index > 0) {
2529            index--;
2530        }
2531        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2532                + " in LRU list: " + app);
2533        mLruProcesses.add(index, app);
2534        return index;
2535    }
2536
2537    final void removeLruProcessLocked(ProcessRecord app) {
2538        int lrui = mLruProcesses.lastIndexOf(app);
2539        if (lrui >= 0) {
2540            if (lrui <= mLruProcessActivityStart) {
2541                mLruProcessActivityStart--;
2542            }
2543            if (lrui <= mLruProcessServiceStart) {
2544                mLruProcessServiceStart--;
2545            }
2546            mLruProcesses.remove(lrui);
2547        }
2548    }
2549
2550    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2551            ProcessRecord client) {
2552        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2553                || app.treatLikeActivity;
2554        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2555        if (!activityChange && hasActivity) {
2556            // The process has activities, so we are only allowing activity-based adjustments
2557            // to move it.  It should be kept in the front of the list with other
2558            // processes that have activities, and we don't want those to change their
2559            // order except due to activity operations.
2560            return;
2561        }
2562
2563        mLruSeq++;
2564        final long now = SystemClock.uptimeMillis();
2565        app.lastActivityTime = now;
2566
2567        // First a quick reject: if the app is already at the position we will
2568        // put it, then there is nothing to do.
2569        if (hasActivity) {
2570            final int N = mLruProcesses.size();
2571            if (N > 0 && mLruProcesses.get(N-1) == app) {
2572                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2573                return;
2574            }
2575        } else {
2576            if (mLruProcessServiceStart > 0
2577                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2578                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2579                return;
2580            }
2581        }
2582
2583        int lrui = mLruProcesses.lastIndexOf(app);
2584
2585        if (app.persistent && lrui >= 0) {
2586            // We don't care about the position of persistent processes, as long as
2587            // they are in the list.
2588            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2589            return;
2590        }
2591
2592        /* In progress: compute new position first, so we can avoid doing work
2593           if the process is not actually going to move.  Not yet working.
2594        int addIndex;
2595        int nextIndex;
2596        boolean inActivity = false, inService = false;
2597        if (hasActivity) {
2598            // Process has activities, put it at the very tipsy-top.
2599            addIndex = mLruProcesses.size();
2600            nextIndex = mLruProcessServiceStart;
2601            inActivity = true;
2602        } else if (hasService) {
2603            // Process has services, put it at the top of the service list.
2604            addIndex = mLruProcessActivityStart;
2605            nextIndex = mLruProcessServiceStart;
2606            inActivity = true;
2607            inService = true;
2608        } else  {
2609            // Process not otherwise of interest, it goes to the top of the non-service area.
2610            addIndex = mLruProcessServiceStart;
2611            if (client != null) {
2612                int clientIndex = mLruProcesses.lastIndexOf(client);
2613                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2614                        + app);
2615                if (clientIndex >= 0 && addIndex > clientIndex) {
2616                    addIndex = clientIndex;
2617                }
2618            }
2619            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2620        }
2621
2622        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2623                + mLruProcessActivityStart + "): " + app);
2624        */
2625
2626        if (lrui >= 0) {
2627            if (lrui < mLruProcessActivityStart) {
2628                mLruProcessActivityStart--;
2629            }
2630            if (lrui < mLruProcessServiceStart) {
2631                mLruProcessServiceStart--;
2632            }
2633            /*
2634            if (addIndex > lrui) {
2635                addIndex--;
2636            }
2637            if (nextIndex > lrui) {
2638                nextIndex--;
2639            }
2640            */
2641            mLruProcesses.remove(lrui);
2642        }
2643
2644        /*
2645        mLruProcesses.add(addIndex, app);
2646        if (inActivity) {
2647            mLruProcessActivityStart++;
2648        }
2649        if (inService) {
2650            mLruProcessActivityStart++;
2651        }
2652        */
2653
2654        int nextIndex;
2655        if (hasActivity) {
2656            final int N = mLruProcesses.size();
2657            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2658                // Process doesn't have activities, but has clients with
2659                // activities...  move it up, but one below the top (the top
2660                // should always have a real activity).
2661                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2662                mLruProcesses.add(N-1, app);
2663                // To keep it from spamming the LRU list (by making a bunch of clients),
2664                // we will push down any other entries owned by the app.
2665                final int uid = app.info.uid;
2666                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2667                    ProcessRecord subProc = mLruProcesses.get(i);
2668                    if (subProc.info.uid == uid) {
2669                        // We want to push this one down the list.  If the process after
2670                        // it is for the same uid, however, don't do so, because we don't
2671                        // want them internally to be re-ordered.
2672                        if (mLruProcesses.get(i-1).info.uid != uid) {
2673                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2674                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2675                            ProcessRecord tmp = mLruProcesses.get(i);
2676                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2677                            mLruProcesses.set(i-1, tmp);
2678                            i--;
2679                        }
2680                    } else {
2681                        // A gap, we can stop here.
2682                        break;
2683                    }
2684                }
2685            } else {
2686                // Process has activities, put it at the very tipsy-top.
2687                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2688                mLruProcesses.add(app);
2689            }
2690            nextIndex = mLruProcessServiceStart;
2691        } else if (hasService) {
2692            // Process has services, put it at the top of the service list.
2693            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2694            mLruProcesses.add(mLruProcessActivityStart, app);
2695            nextIndex = mLruProcessServiceStart;
2696            mLruProcessActivityStart++;
2697        } else  {
2698            // Process not otherwise of interest, it goes to the top of the non-service area.
2699            int index = mLruProcessServiceStart;
2700            if (client != null) {
2701                // If there is a client, don't allow the process to be moved up higher
2702                // in the list than that client.
2703                int clientIndex = mLruProcesses.lastIndexOf(client);
2704                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2705                        + " when updating " + app);
2706                if (clientIndex <= lrui) {
2707                    // Don't allow the client index restriction to push it down farther in the
2708                    // list than it already is.
2709                    clientIndex = lrui;
2710                }
2711                if (clientIndex >= 0 && index > clientIndex) {
2712                    index = clientIndex;
2713                }
2714            }
2715            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2716            mLruProcesses.add(index, app);
2717            nextIndex = index-1;
2718            mLruProcessActivityStart++;
2719            mLruProcessServiceStart++;
2720        }
2721
2722        // If the app is currently using a content provider or service,
2723        // bump those processes as well.
2724        for (int j=app.connections.size()-1; j>=0; j--) {
2725            ConnectionRecord cr = app.connections.valueAt(j);
2726            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2727                    && cr.binding.service.app != null
2728                    && cr.binding.service.app.lruSeq != mLruSeq
2729                    && !cr.binding.service.app.persistent) {
2730                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2731                        "service connection", cr, app);
2732            }
2733        }
2734        for (int j=app.conProviders.size()-1; j>=0; j--) {
2735            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2736            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2737                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2738                        "provider reference", cpr, app);
2739            }
2740        }
2741    }
2742
2743    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2744        if (uid == Process.SYSTEM_UID) {
2745            // The system gets to run in any process.  If there are multiple
2746            // processes with the same uid, just pick the first (this
2747            // should never happen).
2748            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2749            if (procs == null) return null;
2750            final int N = procs.size();
2751            for (int i = 0; i < N; i++) {
2752                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2753            }
2754        }
2755        ProcessRecord proc = mProcessNames.get(processName, uid);
2756        if (false && proc != null && !keepIfLarge
2757                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2758                && proc.lastCachedPss >= 4000) {
2759            // Turn this condition on to cause killing to happen regularly, for testing.
2760            if (proc.baseProcessTracker != null) {
2761                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2762            }
2763            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2764                    + "k from cached");
2765        } else if (proc != null && !keepIfLarge
2766                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2767                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2768            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2769            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2770                if (proc.baseProcessTracker != null) {
2771                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2772                }
2773                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2774                        + "k from cached");
2775            }
2776        }
2777        return proc;
2778    }
2779
2780    void ensurePackageDexOpt(String packageName) {
2781        IPackageManager pm = AppGlobals.getPackageManager();
2782        try {
2783            if (pm.performDexOpt(packageName)) {
2784                mDidDexOpt = true;
2785            }
2786        } catch (RemoteException e) {
2787        }
2788    }
2789
2790    boolean isNextTransitionForward() {
2791        int transit = mWindowManager.getPendingAppTransition();
2792        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2793                || transit == AppTransition.TRANSIT_TASK_OPEN
2794                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2795    }
2796
2797    final ProcessRecord startProcessLocked(String processName,
2798            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2799            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2800            boolean isolated, boolean keepIfLarge) {
2801        ProcessRecord app;
2802        if (!isolated) {
2803            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2804        } else {
2805            // If this is an isolated process, it can't re-use an existing process.
2806            app = null;
2807        }
2808        // We don't have to do anything more if:
2809        // (1) There is an existing application record; and
2810        // (2) The caller doesn't think it is dead, OR there is no thread
2811        //     object attached to it so we know it couldn't have crashed; and
2812        // (3) There is a pid assigned to it, so it is either starting or
2813        //     already running.
2814        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2815                + " app=" + app + " knownToBeDead=" + knownToBeDead
2816                + " thread=" + (app != null ? app.thread : null)
2817                + " pid=" + (app != null ? app.pid : -1));
2818        if (app != null && app.pid > 0) {
2819            if (!knownToBeDead || app.thread == null) {
2820                // We already have the app running, or are waiting for it to
2821                // come up (we have a pid but not yet its thread), so keep it.
2822                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2823                // If this is a new package in the process, add the package to the list
2824                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2825                return app;
2826            }
2827
2828            // An application record is attached to a previous process,
2829            // clean it up now.
2830            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2831            handleAppDiedLocked(app, true, true);
2832        }
2833
2834        String hostingNameStr = hostingName != null
2835                ? hostingName.flattenToShortString() : null;
2836
2837        if (!isolated) {
2838            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2839                // If we are in the background, then check to see if this process
2840                // is bad.  If so, we will just silently fail.
2841                if (mBadProcesses.get(info.processName, info.uid) != null) {
2842                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2843                            + "/" + info.processName);
2844                    return null;
2845                }
2846            } else {
2847                // When the user is explicitly starting a process, then clear its
2848                // crash count so that we won't make it bad until they see at
2849                // least one crash dialog again, and make the process good again
2850                // if it had been bad.
2851                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2852                        + "/" + info.processName);
2853                mProcessCrashTimes.remove(info.processName, info.uid);
2854                if (mBadProcesses.get(info.processName, info.uid) != null) {
2855                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2856                            UserHandle.getUserId(info.uid), info.uid,
2857                            info.processName);
2858                    mBadProcesses.remove(info.processName, info.uid);
2859                    if (app != null) {
2860                        app.bad = false;
2861                    }
2862                }
2863            }
2864        }
2865
2866        if (app == null) {
2867            app = newProcessRecordLocked(info, processName, isolated);
2868            if (app == null) {
2869                Slog.w(TAG, "Failed making new process record for "
2870                        + processName + "/" + info.uid + " isolated=" + isolated);
2871                return null;
2872            }
2873            mProcessNames.put(processName, app.uid, app);
2874            if (isolated) {
2875                mIsolatedProcesses.put(app.uid, app);
2876            }
2877        } else {
2878            // If this is a new package in the process, add the package to the list
2879            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2880        }
2881
2882        // If the system is not ready yet, then hold off on starting this
2883        // process until it is.
2884        if (!mProcessesReady
2885                && !isAllowedWhileBooting(info)
2886                && !allowWhileBooting) {
2887            if (!mProcessesOnHold.contains(app)) {
2888                mProcessesOnHold.add(app);
2889            }
2890            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2891            return app;
2892        }
2893
2894        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2895        return (app.pid != 0) ? app : null;
2896    }
2897
2898    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2899        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2900    }
2901
2902    private final void startProcessLocked(ProcessRecord app,
2903            String hostingType, String hostingNameStr, String abiOverride) {
2904        if (app.pid > 0 && app.pid != MY_PID) {
2905            synchronized (mPidsSelfLocked) {
2906                mPidsSelfLocked.remove(app.pid);
2907                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2908            }
2909            app.setPid(0);
2910        }
2911
2912        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2913                "startProcessLocked removing on hold: " + app);
2914        mProcessesOnHold.remove(app);
2915
2916        updateCpuStats();
2917
2918        try {
2919            int uid = app.uid;
2920
2921            int[] gids = null;
2922            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2923            if (!app.isolated) {
2924                int[] permGids = null;
2925                try {
2926                    final PackageManager pm = mContext.getPackageManager();
2927                    permGids = pm.getPackageGids(app.info.packageName);
2928
2929                    if (Environment.isExternalStorageEmulated()) {
2930                        if (pm.checkPermission(
2931                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2932                                app.info.packageName) == PERMISSION_GRANTED) {
2933                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2934                        } else {
2935                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2936                        }
2937                    }
2938                } catch (PackageManager.NameNotFoundException e) {
2939                    Slog.w(TAG, "Unable to retrieve gids", e);
2940                }
2941
2942                /*
2943                 * Add shared application and profile GIDs so applications can share some
2944                 * resources like shared libraries and access user-wide resources
2945                 */
2946                if (permGids == null) {
2947                    gids = new int[2];
2948                } else {
2949                    gids = new int[permGids.length + 2];
2950                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2951                }
2952                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2953                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2954            }
2955            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2956                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2957                        && mTopComponent != null
2958                        && app.processName.equals(mTopComponent.getPackageName())) {
2959                    uid = 0;
2960                }
2961                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2962                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2963                    uid = 0;
2964                }
2965            }
2966            int debugFlags = 0;
2967            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2968                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2969                // Also turn on CheckJNI for debuggable apps. It's quite
2970                // awkward to turn on otherwise.
2971                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2972            }
2973            // Run the app in safe mode if its manifest requests so or the
2974            // system is booted in safe mode.
2975            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2976                mSafeMode == true) {
2977                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2978            }
2979            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2980                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2981            }
2982            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2983                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2984            }
2985            if ("1".equals(SystemProperties.get("debug.assert"))) {
2986                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2987            }
2988
2989            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
2990            if (requiredAbi == null) {
2991                requiredAbi = Build.SUPPORTED_ABIS[0];
2992            }
2993
2994            // Start the process.  It will either succeed and return a result containing
2995            // the PID of the new process, or else throw a RuntimeException.
2996            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2997                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2998                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2999
3000            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
3001            synchronized (bs) {
3002                if (bs.isOnBattery()) {
3003                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
3004                }
3005            }
3006
3007            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3008                    UserHandle.getUserId(uid), startResult.pid, uid,
3009                    app.processName, hostingType,
3010                    hostingNameStr != null ? hostingNameStr : "");
3011
3012            if (app.persistent) {
3013                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3014            }
3015
3016            StringBuilder buf = mStringBuilder;
3017            buf.setLength(0);
3018            buf.append("Start proc ");
3019            buf.append(app.processName);
3020            buf.append(" for ");
3021            buf.append(hostingType);
3022            if (hostingNameStr != null) {
3023                buf.append(" ");
3024                buf.append(hostingNameStr);
3025            }
3026            buf.append(": pid=");
3027            buf.append(startResult.pid);
3028            buf.append(" uid=");
3029            buf.append(uid);
3030            buf.append(" gids={");
3031            if (gids != null) {
3032                for (int gi=0; gi<gids.length; gi++) {
3033                    if (gi != 0) buf.append(", ");
3034                    buf.append(gids[gi]);
3035
3036                }
3037            }
3038            buf.append("}");
3039            if (requiredAbi != null) {
3040                buf.append(" abi=");
3041                buf.append(requiredAbi);
3042            }
3043            Slog.i(TAG, buf.toString());
3044            app.setPid(startResult.pid);
3045            app.usingWrapper = startResult.usingWrapper;
3046            app.removed = false;
3047            app.killedByAm = false;
3048            synchronized (mPidsSelfLocked) {
3049                this.mPidsSelfLocked.put(startResult.pid, app);
3050                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3051                msg.obj = app;
3052                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3053                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3054            }
3055            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
3056                    app.processName, app.info.uid);
3057            if (app.isolated) {
3058                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3059            }
3060        } catch (RuntimeException e) {
3061            // XXX do better error recovery.
3062            app.setPid(0);
3063            Slog.e(TAG, "Failure starting process " + app.processName, e);
3064        }
3065    }
3066
3067    void updateUsageStats(ActivityRecord component, boolean resumed) {
3068        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3069        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3070        if (resumed) {
3071            mUsageStatsService.noteResumeComponent(component.realActivity);
3072            synchronized (stats) {
3073                stats.noteActivityResumedLocked(component.app.uid);
3074            }
3075        } else {
3076            mUsageStatsService.notePauseComponent(component.realActivity);
3077            synchronized (stats) {
3078                stats.noteActivityPausedLocked(component.app.uid);
3079            }
3080        }
3081    }
3082
3083    Intent getHomeIntent() {
3084        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3085        intent.setComponent(mTopComponent);
3086        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3087            intent.addCategory(Intent.CATEGORY_HOME);
3088        }
3089        return intent;
3090    }
3091
3092    boolean startHomeActivityLocked(int userId) {
3093        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3094                && mTopAction == null) {
3095            // We are running in factory test mode, but unable to find
3096            // the factory test app, so just sit around displaying the
3097            // error message and don't try to start anything.
3098            return false;
3099        }
3100        Intent intent = getHomeIntent();
3101        ActivityInfo aInfo =
3102            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3103        if (aInfo != null) {
3104            intent.setComponent(new ComponentName(
3105                    aInfo.applicationInfo.packageName, aInfo.name));
3106            // Don't do this if the home app is currently being
3107            // instrumented.
3108            aInfo = new ActivityInfo(aInfo);
3109            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3110            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3111                    aInfo.applicationInfo.uid, true);
3112            if (app == null || app.instrumentationClass == null) {
3113                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3114                mStackSupervisor.startHomeActivity(intent, aInfo);
3115            }
3116        }
3117
3118        return true;
3119    }
3120
3121    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3122        ActivityInfo ai = null;
3123        ComponentName comp = intent.getComponent();
3124        try {
3125            if (comp != null) {
3126                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3127            } else {
3128                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3129                        intent,
3130                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3131                            flags, userId);
3132
3133                if (info != null) {
3134                    ai = info.activityInfo;
3135                }
3136            }
3137        } catch (RemoteException e) {
3138            // ignore
3139        }
3140
3141        return ai;
3142    }
3143
3144    /**
3145     * Starts the "new version setup screen" if appropriate.
3146     */
3147    void startSetupActivityLocked() {
3148        // Only do this once per boot.
3149        if (mCheckedForSetup) {
3150            return;
3151        }
3152
3153        // We will show this screen if the current one is a different
3154        // version than the last one shown, and we are not running in
3155        // low-level factory test mode.
3156        final ContentResolver resolver = mContext.getContentResolver();
3157        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3158                Settings.Global.getInt(resolver,
3159                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3160            mCheckedForSetup = true;
3161
3162            // See if we should be showing the platform update setup UI.
3163            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3164            List<ResolveInfo> ris = mContext.getPackageManager()
3165                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3166
3167            // We don't allow third party apps to replace this.
3168            ResolveInfo ri = null;
3169            for (int i=0; ris != null && i<ris.size(); i++) {
3170                if ((ris.get(i).activityInfo.applicationInfo.flags
3171                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3172                    ri = ris.get(i);
3173                    break;
3174                }
3175            }
3176
3177            if (ri != null) {
3178                String vers = ri.activityInfo.metaData != null
3179                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3180                        : null;
3181                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3182                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3183                            Intent.METADATA_SETUP_VERSION);
3184                }
3185                String lastVers = Settings.Secure.getString(
3186                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3187                if (vers != null && !vers.equals(lastVers)) {
3188                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3189                    intent.setComponent(new ComponentName(
3190                            ri.activityInfo.packageName, ri.activityInfo.name));
3191                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3192                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3193                }
3194            }
3195        }
3196    }
3197
3198    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3199        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3200    }
3201
3202    void enforceNotIsolatedCaller(String caller) {
3203        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3204            throw new SecurityException("Isolated process not allowed to call " + caller);
3205        }
3206    }
3207
3208    @Override
3209    public int getFrontActivityScreenCompatMode() {
3210        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3211        synchronized (this) {
3212            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3213        }
3214    }
3215
3216    @Override
3217    public void setFrontActivityScreenCompatMode(int mode) {
3218        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3219                "setFrontActivityScreenCompatMode");
3220        synchronized (this) {
3221            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3222        }
3223    }
3224
3225    @Override
3226    public int getPackageScreenCompatMode(String packageName) {
3227        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3228        synchronized (this) {
3229            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3230        }
3231    }
3232
3233    @Override
3234    public void setPackageScreenCompatMode(String packageName, int mode) {
3235        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3236                "setPackageScreenCompatMode");
3237        synchronized (this) {
3238            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3239        }
3240    }
3241
3242    @Override
3243    public boolean getPackageAskScreenCompat(String packageName) {
3244        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3245        synchronized (this) {
3246            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3247        }
3248    }
3249
3250    @Override
3251    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3252        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3253                "setPackageAskScreenCompat");
3254        synchronized (this) {
3255            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3256        }
3257    }
3258
3259    private void dispatchProcessesChanged() {
3260        int N;
3261        synchronized (this) {
3262            N = mPendingProcessChanges.size();
3263            if (mActiveProcessChanges.length < N) {
3264                mActiveProcessChanges = new ProcessChangeItem[N];
3265            }
3266            mPendingProcessChanges.toArray(mActiveProcessChanges);
3267            mAvailProcessChanges.addAll(mPendingProcessChanges);
3268            mPendingProcessChanges.clear();
3269            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3270        }
3271
3272        int i = mProcessObservers.beginBroadcast();
3273        while (i > 0) {
3274            i--;
3275            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3276            if (observer != null) {
3277                try {
3278                    for (int j=0; j<N; j++) {
3279                        ProcessChangeItem item = mActiveProcessChanges[j];
3280                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3281                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3282                                    + item.pid + " uid=" + item.uid + ": "
3283                                    + item.foregroundActivities);
3284                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3285                                    item.foregroundActivities);
3286                        }
3287                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3288                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3289                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3290                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3291                        }
3292                    }
3293                } catch (RemoteException e) {
3294                }
3295            }
3296        }
3297        mProcessObservers.finishBroadcast();
3298    }
3299
3300    private void dispatchProcessDied(int pid, int uid) {
3301        int i = mProcessObservers.beginBroadcast();
3302        while (i > 0) {
3303            i--;
3304            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3305            if (observer != null) {
3306                try {
3307                    observer.onProcessDied(pid, uid);
3308                } catch (RemoteException e) {
3309                }
3310            }
3311        }
3312        mProcessObservers.finishBroadcast();
3313    }
3314
3315    final void doPendingActivityLaunchesLocked(boolean doResume) {
3316        final int N = mPendingActivityLaunches.size();
3317        if (N <= 0) {
3318            return;
3319        }
3320        for (int i=0; i<N; i++) {
3321            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3322            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3323                    doResume && i == (N-1), null);
3324        }
3325        mPendingActivityLaunches.clear();
3326    }
3327
3328    @Override
3329    public final int startActivity(IApplicationThread caller, String callingPackage,
3330            Intent intent, String resolvedType, IBinder resultTo,
3331            String resultWho, int requestCode, int startFlags,
3332            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3333        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3334                resultWho, requestCode,
3335                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3336    }
3337
3338    @Override
3339    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3340            Intent intent, String resolvedType, IBinder resultTo,
3341            String resultWho, int requestCode, int startFlags,
3342            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3343        enforceNotIsolatedCaller("startActivity");
3344        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3345                false, true, "startActivity", null);
3346        // TODO: Switch to user app stacks here.
3347        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3348                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3349                null, null, options, userId, null);
3350    }
3351
3352    @Override
3353    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3354            Intent intent, String resolvedType, IBinder resultTo,
3355            String resultWho, int requestCode, int startFlags, String profileFile,
3356            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3357        enforceNotIsolatedCaller("startActivityAndWait");
3358        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3359                false, true, "startActivityAndWait", null);
3360        WaitResult res = new WaitResult();
3361        // TODO: Switch to user app stacks here.
3362        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3363                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3364                res, null, options, UserHandle.getCallingUserId(), null);
3365        return res;
3366    }
3367
3368    @Override
3369    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3370            Intent intent, String resolvedType, IBinder resultTo,
3371            String resultWho, int requestCode, int startFlags, Configuration config,
3372            Bundle options, int userId) {
3373        enforceNotIsolatedCaller("startActivityWithConfig");
3374        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3375                false, true, "startActivityWithConfig", null);
3376        // TODO: Switch to user app stacks here.
3377        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3378                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3379                null, null, null, config, options, userId, null);
3380        return ret;
3381    }
3382
3383    @Override
3384    public int startActivityIntentSender(IApplicationThread caller,
3385            IntentSender intent, Intent fillInIntent, String resolvedType,
3386            IBinder resultTo, String resultWho, int requestCode,
3387            int flagsMask, int flagsValues, Bundle options) {
3388        enforceNotIsolatedCaller("startActivityIntentSender");
3389        // Refuse possible leaked file descriptors
3390        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3391            throw new IllegalArgumentException("File descriptors passed in Intent");
3392        }
3393
3394        IIntentSender sender = intent.getTarget();
3395        if (!(sender instanceof PendingIntentRecord)) {
3396            throw new IllegalArgumentException("Bad PendingIntent object");
3397        }
3398
3399        PendingIntentRecord pir = (PendingIntentRecord)sender;
3400
3401        synchronized (this) {
3402            // If this is coming from the currently resumed activity, it is
3403            // effectively saying that app switches are allowed at this point.
3404            final ActivityStack stack = getFocusedStack();
3405            if (stack.mResumedActivity != null &&
3406                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3407                mAppSwitchesAllowedTime = 0;
3408            }
3409        }
3410        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3411                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3412        return ret;
3413    }
3414
3415    @Override
3416    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3417            Intent intent, String resolvedType, IVoiceInteractionSession session,
3418            IVoiceInteractor interactor, int startFlags, String profileFile,
3419            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3420        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3421                != PackageManager.PERMISSION_GRANTED) {
3422            String msg = "Permission Denial: startVoiceActivity() from pid="
3423                    + Binder.getCallingPid()
3424                    + ", uid=" + Binder.getCallingUid()
3425                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3426            Slog.w(TAG, msg);
3427            throw new SecurityException(msg);
3428        }
3429        if (session == null || interactor == null) {
3430            throw new NullPointerException("null session or interactor");
3431        }
3432        userId = handleIncomingUser(callingPid, callingUid, userId,
3433                false, true, "startVoiceActivity", null);
3434        // TODO: Switch to user app stacks here.
3435        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3436                resolvedType, session, interactor, null, null, 0, startFlags,
3437                profileFile, profileFd, null, null, options, userId, null);
3438    }
3439
3440    @Override
3441    public boolean startNextMatchingActivity(IBinder callingActivity,
3442            Intent intent, Bundle options) {
3443        // Refuse possible leaked file descriptors
3444        if (intent != null && intent.hasFileDescriptors() == true) {
3445            throw new IllegalArgumentException("File descriptors passed in Intent");
3446        }
3447
3448        synchronized (this) {
3449            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3450            if (r == null) {
3451                ActivityOptions.abort(options);
3452                return false;
3453            }
3454            if (r.app == null || r.app.thread == null) {
3455                // The caller is not running...  d'oh!
3456                ActivityOptions.abort(options);
3457                return false;
3458            }
3459            intent = new Intent(intent);
3460            // The caller is not allowed to change the data.
3461            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3462            // And we are resetting to find the next component...
3463            intent.setComponent(null);
3464
3465            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3466
3467            ActivityInfo aInfo = null;
3468            try {
3469                List<ResolveInfo> resolves =
3470                    AppGlobals.getPackageManager().queryIntentActivities(
3471                            intent, r.resolvedType,
3472                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3473                            UserHandle.getCallingUserId());
3474
3475                // Look for the original activity in the list...
3476                final int N = resolves != null ? resolves.size() : 0;
3477                for (int i=0; i<N; i++) {
3478                    ResolveInfo rInfo = resolves.get(i);
3479                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3480                            && rInfo.activityInfo.name.equals(r.info.name)) {
3481                        // We found the current one...  the next matching is
3482                        // after it.
3483                        i++;
3484                        if (i<N) {
3485                            aInfo = resolves.get(i).activityInfo;
3486                        }
3487                        if (debug) {
3488                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3489                                    + "/" + r.info.name);
3490                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3491                                    + "/" + aInfo.name);
3492                        }
3493                        break;
3494                    }
3495                }
3496            } catch (RemoteException e) {
3497            }
3498
3499            if (aInfo == null) {
3500                // Nobody who is next!
3501                ActivityOptions.abort(options);
3502                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3503                return false;
3504            }
3505
3506            intent.setComponent(new ComponentName(
3507                    aInfo.applicationInfo.packageName, aInfo.name));
3508            intent.setFlags(intent.getFlags()&~(
3509                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3510                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3511                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3512                    Intent.FLAG_ACTIVITY_NEW_TASK));
3513
3514            // Okay now we need to start the new activity, replacing the
3515            // currently running activity.  This is a little tricky because
3516            // we want to start the new one as if the current one is finished,
3517            // but not finish the current one first so that there is no flicker.
3518            // And thus...
3519            final boolean wasFinishing = r.finishing;
3520            r.finishing = true;
3521
3522            // Propagate reply information over to the new activity.
3523            final ActivityRecord resultTo = r.resultTo;
3524            final String resultWho = r.resultWho;
3525            final int requestCode = r.requestCode;
3526            r.resultTo = null;
3527            if (resultTo != null) {
3528                resultTo.removeResultsLocked(r, resultWho, requestCode);
3529            }
3530
3531            final long origId = Binder.clearCallingIdentity();
3532            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3533                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3534                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3535                    options, false, null, null);
3536            Binder.restoreCallingIdentity(origId);
3537
3538            r.finishing = wasFinishing;
3539            if (res != ActivityManager.START_SUCCESS) {
3540                return false;
3541            }
3542            return true;
3543        }
3544    }
3545
3546    final int startActivityInPackage(int uid, String callingPackage,
3547            Intent intent, String resolvedType, IBinder resultTo,
3548            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3549                    IActivityContainer container) {
3550
3551        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3552                false, true, "startActivityInPackage", null);
3553
3554        // TODO: Switch to user app stacks here.
3555        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3556                null, null, resultTo, resultWho, requestCode, startFlags,
3557                null, null, null, null, options, userId, container);
3558        return ret;
3559    }
3560
3561    @Override
3562    public final int startActivities(IApplicationThread caller, String callingPackage,
3563            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3564            int userId) {
3565        enforceNotIsolatedCaller("startActivities");
3566        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3567                false, true, "startActivity", null);
3568        // TODO: Switch to user app stacks here.
3569        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3570                resolvedTypes, resultTo, options, userId);
3571        return ret;
3572    }
3573
3574    final int startActivitiesInPackage(int uid, String callingPackage,
3575            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3576            Bundle options, int userId) {
3577
3578        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3579                false, true, "startActivityInPackage", null);
3580        // TODO: Switch to user app stacks here.
3581        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3582                resultTo, options, userId);
3583        return ret;
3584    }
3585
3586    final void addRecentTaskLocked(TaskRecord task) {
3587        int N = mRecentTasks.size();
3588        // Quick case: check if the top-most recent task is the same.
3589        if (N > 0 && mRecentTasks.get(0) == task) {
3590            return;
3591        }
3592        // Another quick case: never add voice sessions.
3593        if (task.voiceSession != null) {
3594            return;
3595        }
3596        // Remove any existing entries that are the same kind of task.
3597        final Intent intent = task.intent;
3598        final boolean document = intent != null && intent.isDocument();
3599        final ComponentName comp = intent.getComponent();
3600
3601        int maxRecents = task.maxRecents - 1;
3602        for (int i=0; i<N; i++) {
3603            TaskRecord tr = mRecentTasks.get(i);
3604            if (task != tr) {
3605                if (task.userId != tr.userId) {
3606                    continue;
3607                }
3608                if (i > MAX_RECENT_BITMAPS) {
3609                    tr.freeLastThumbnail();
3610                }
3611                final Intent trIntent = tr.intent;
3612                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3613                    (intent == null || !intent.filterEquals(trIntent))) {
3614                    continue;
3615                }
3616                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3617                if (document && trIsDocument) {
3618                    // These are the same document activity (not necessarily the same doc).
3619                    if (maxRecents > 0) {
3620                        --maxRecents;
3621                        continue;
3622                    }
3623                    // Hit the maximum number of documents for this task. Fall through
3624                    // and remove this document from recents.
3625                } else if (document || trIsDocument) {
3626                    // Only one of these is a document. Not the droid we're looking for.
3627                    continue;
3628                }
3629            }
3630
3631            // Either task and tr are the same or, their affinities match or their intents match
3632            // and neither of them is a document, or they are documents using the same activity
3633            // and their maxRecents has been reached.
3634            tr.disposeThumbnail();
3635            mRecentTasks.remove(i);
3636            i--;
3637            N--;
3638            if (task.intent == null) {
3639                // If the new recent task we are adding is not fully
3640                // specified, then replace it with the existing recent task.
3641                task = tr;
3642            }
3643            mTaskPersister.notify(tr, false);
3644        }
3645        if (N >= MAX_RECENT_TASKS) {
3646            mRecentTasks.remove(N-1).disposeThumbnail();
3647        }
3648        mRecentTasks.add(0, task);
3649    }
3650
3651    @Override
3652    public void reportActivityFullyDrawn(IBinder token) {
3653        synchronized (this) {
3654            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3655            if (r == null) {
3656                return;
3657            }
3658            r.reportFullyDrawnLocked();
3659        }
3660    }
3661
3662    @Override
3663    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3664        synchronized (this) {
3665            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3666            if (r == null) {
3667                return;
3668            }
3669            final long origId = Binder.clearCallingIdentity();
3670            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3671            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3672                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3673            if (config != null) {
3674                r.frozenBeforeDestroy = true;
3675                if (!updateConfigurationLocked(config, r, false, false)) {
3676                    mStackSupervisor.resumeTopActivitiesLocked();
3677                }
3678            }
3679            Binder.restoreCallingIdentity(origId);
3680        }
3681    }
3682
3683    @Override
3684    public int getRequestedOrientation(IBinder token) {
3685        synchronized (this) {
3686            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3687            if (r == null) {
3688                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3689            }
3690            return mWindowManager.getAppOrientation(r.appToken);
3691        }
3692    }
3693
3694    /**
3695     * This is the internal entry point for handling Activity.finish().
3696     *
3697     * @param token The Binder token referencing the Activity we want to finish.
3698     * @param resultCode Result code, if any, from this Activity.
3699     * @param resultData Result data (Intent), if any, from this Activity.
3700     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3701     *            the root Activity in the task.
3702     *
3703     * @return Returns true if the activity successfully finished, or false if it is still running.
3704     */
3705    @Override
3706    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3707            boolean finishTask) {
3708        // Refuse possible leaked file descriptors
3709        if (resultData != null && resultData.hasFileDescriptors() == true) {
3710            throw new IllegalArgumentException("File descriptors passed in Intent");
3711        }
3712
3713        synchronized(this) {
3714            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3715            if (r == null) {
3716                return true;
3717            }
3718            // Keep track of the root activity of the task before we finish it
3719            TaskRecord tr = r.task;
3720            ActivityRecord rootR = tr.getRootActivity();
3721            // Do not allow task to finish in Lock Task mode.
3722            if (tr == mStackSupervisor.mLockTaskModeTask) {
3723                if (rootR == r) {
3724                    mStackSupervisor.showLockTaskToast();
3725                    return false;
3726                }
3727            }
3728            if (mController != null) {
3729                // Find the first activity that is not finishing.
3730                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3731                if (next != null) {
3732                    // ask watcher if this is allowed
3733                    boolean resumeOK = true;
3734                    try {
3735                        resumeOK = mController.activityResuming(next.packageName);
3736                    } catch (RemoteException e) {
3737                        mController = null;
3738                        Watchdog.getInstance().setActivityController(null);
3739                    }
3740
3741                    if (!resumeOK) {
3742                        return false;
3743                    }
3744                }
3745            }
3746            final long origId = Binder.clearCallingIdentity();
3747            try {
3748                boolean res;
3749                if (finishTask && r == rootR) {
3750                    // If requested, remove the task that is associated to this activity only if it
3751                    // was the root activity in the task.  The result code and data is ignored because
3752                    // we don't support returning them across task boundaries.
3753                    res = removeTaskByIdLocked(tr.taskId, 0);
3754                } else {
3755                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3756                            resultData, "app-request", true);
3757                }
3758                return res;
3759            } finally {
3760                Binder.restoreCallingIdentity(origId);
3761            }
3762        }
3763    }
3764
3765    @Override
3766    public final void finishHeavyWeightApp() {
3767        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3768                != PackageManager.PERMISSION_GRANTED) {
3769            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3770                    + Binder.getCallingPid()
3771                    + ", uid=" + Binder.getCallingUid()
3772                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3773            Slog.w(TAG, msg);
3774            throw new SecurityException(msg);
3775        }
3776
3777        synchronized(this) {
3778            if (mHeavyWeightProcess == null) {
3779                return;
3780            }
3781
3782            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3783                    mHeavyWeightProcess.activities);
3784            for (int i=0; i<activities.size(); i++) {
3785                ActivityRecord r = activities.get(i);
3786                if (!r.finishing) {
3787                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3788                            null, "finish-heavy", true);
3789                }
3790            }
3791
3792            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3793                    mHeavyWeightProcess.userId, 0));
3794            mHeavyWeightProcess = null;
3795        }
3796    }
3797
3798    @Override
3799    public void crashApplication(int uid, int initialPid, String packageName,
3800            String message) {
3801        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3802                != PackageManager.PERMISSION_GRANTED) {
3803            String msg = "Permission Denial: crashApplication() from pid="
3804                    + Binder.getCallingPid()
3805                    + ", uid=" + Binder.getCallingUid()
3806                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3807            Slog.w(TAG, msg);
3808            throw new SecurityException(msg);
3809        }
3810
3811        synchronized(this) {
3812            ProcessRecord proc = null;
3813
3814            // Figure out which process to kill.  We don't trust that initialPid
3815            // still has any relation to current pids, so must scan through the
3816            // list.
3817            synchronized (mPidsSelfLocked) {
3818                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3819                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3820                    if (p.uid != uid) {
3821                        continue;
3822                    }
3823                    if (p.pid == initialPid) {
3824                        proc = p;
3825                        break;
3826                    }
3827                    if (p.pkgList.containsKey(packageName)) {
3828                        proc = p;
3829                    }
3830                }
3831            }
3832
3833            if (proc == null) {
3834                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3835                        + " initialPid=" + initialPid
3836                        + " packageName=" + packageName);
3837                return;
3838            }
3839
3840            if (proc.thread != null) {
3841                if (proc.pid == Process.myPid()) {
3842                    Log.w(TAG, "crashApplication: trying to crash self!");
3843                    return;
3844                }
3845                long ident = Binder.clearCallingIdentity();
3846                try {
3847                    proc.thread.scheduleCrash(message);
3848                } catch (RemoteException e) {
3849                }
3850                Binder.restoreCallingIdentity(ident);
3851            }
3852        }
3853    }
3854
3855    @Override
3856    public final void finishSubActivity(IBinder token, String resultWho,
3857            int requestCode) {
3858        synchronized(this) {
3859            final long origId = Binder.clearCallingIdentity();
3860            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3861            if (r != null) {
3862                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3863            }
3864            Binder.restoreCallingIdentity(origId);
3865        }
3866    }
3867
3868    @Override
3869    public boolean finishActivityAffinity(IBinder token) {
3870        synchronized(this) {
3871            final long origId = Binder.clearCallingIdentity();
3872            try {
3873                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3874
3875                ActivityRecord rootR = r.task.getRootActivity();
3876                // Do not allow task to finish in Lock Task mode.
3877                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3878                    if (rootR == r) {
3879                        mStackSupervisor.showLockTaskToast();
3880                        return false;
3881                    }
3882                }
3883                boolean res = false;
3884                if (r != null) {
3885                    res = r.task.stack.finishActivityAffinityLocked(r);
3886                }
3887                return res;
3888            } finally {
3889                Binder.restoreCallingIdentity(origId);
3890            }
3891        }
3892    }
3893
3894    @Override
3895    public void finishVoiceTask(IVoiceInteractionSession session) {
3896        synchronized(this) {
3897            final long origId = Binder.clearCallingIdentity();
3898            try {
3899                mStackSupervisor.finishVoiceTask(session);
3900            } finally {
3901                Binder.restoreCallingIdentity(origId);
3902            }
3903        }
3904
3905    }
3906
3907    @Override
3908    public boolean willActivityBeVisible(IBinder token) {
3909        synchronized(this) {
3910            ActivityStack stack = ActivityRecord.getStackLocked(token);
3911            if (stack != null) {
3912                return stack.willActivityBeVisibleLocked(token);
3913            }
3914            return false;
3915        }
3916    }
3917
3918    @Override
3919    public void overridePendingTransition(IBinder token, String packageName,
3920            int enterAnim, int exitAnim) {
3921        synchronized(this) {
3922            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3923            if (self == null) {
3924                return;
3925            }
3926
3927            final long origId = Binder.clearCallingIdentity();
3928
3929            if (self.state == ActivityState.RESUMED
3930                    || self.state == ActivityState.PAUSING) {
3931                mWindowManager.overridePendingAppTransition(packageName,
3932                        enterAnim, exitAnim, null);
3933            }
3934
3935            Binder.restoreCallingIdentity(origId);
3936        }
3937    }
3938
3939    /**
3940     * Main function for removing an existing process from the activity manager
3941     * as a result of that process going away.  Clears out all connections
3942     * to the process.
3943     */
3944    private final void handleAppDiedLocked(ProcessRecord app,
3945            boolean restarting, boolean allowRestart) {
3946        int pid = app.pid;
3947        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3948        if (!restarting) {
3949            removeLruProcessLocked(app);
3950            if (pid > 0) {
3951                ProcessList.remove(pid);
3952            }
3953        }
3954
3955        if (mProfileProc == app) {
3956            clearProfilerLocked();
3957        }
3958
3959        // Remove this application's activities from active lists.
3960        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3961
3962        app.activities.clear();
3963
3964        if (app.instrumentationClass != null) {
3965            Slog.w(TAG, "Crash of app " + app.processName
3966                  + " running instrumentation " + app.instrumentationClass);
3967            Bundle info = new Bundle();
3968            info.putString("shortMsg", "Process crashed.");
3969            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3970        }
3971
3972        if (!restarting) {
3973            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3974                // If there was nothing to resume, and we are not already
3975                // restarting this process, but there is a visible activity that
3976                // is hosted by the process...  then make sure all visible
3977                // activities are running, taking care of restarting this
3978                // process.
3979                if (hasVisibleActivities) {
3980                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3981                }
3982            }
3983        }
3984    }
3985
3986    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3987        IBinder threadBinder = thread.asBinder();
3988        // Find the application record.
3989        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3990            ProcessRecord rec = mLruProcesses.get(i);
3991            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3992                return i;
3993            }
3994        }
3995        return -1;
3996    }
3997
3998    final ProcessRecord getRecordForAppLocked(
3999            IApplicationThread thread) {
4000        if (thread == null) {
4001            return null;
4002        }
4003
4004        int appIndex = getLRURecordIndexForAppLocked(thread);
4005        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4006    }
4007
4008    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4009        // If there are no longer any background processes running,
4010        // and the app that died was not running instrumentation,
4011        // then tell everyone we are now low on memory.
4012        boolean haveBg = false;
4013        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4014            ProcessRecord rec = mLruProcesses.get(i);
4015            if (rec.thread != null
4016                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4017                haveBg = true;
4018                break;
4019            }
4020        }
4021
4022        if (!haveBg) {
4023            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4024            if (doReport) {
4025                long now = SystemClock.uptimeMillis();
4026                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4027                    doReport = false;
4028                } else {
4029                    mLastMemUsageReportTime = now;
4030                }
4031            }
4032            final ArrayList<ProcessMemInfo> memInfos
4033                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4034            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4035            long now = SystemClock.uptimeMillis();
4036            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4037                ProcessRecord rec = mLruProcesses.get(i);
4038                if (rec == dyingProc || rec.thread == null) {
4039                    continue;
4040                }
4041                if (doReport) {
4042                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4043                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4044                }
4045                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4046                    // The low memory report is overriding any current
4047                    // state for a GC request.  Make sure to do
4048                    // heavy/important/visible/foreground processes first.
4049                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4050                        rec.lastRequestedGc = 0;
4051                    } else {
4052                        rec.lastRequestedGc = rec.lastLowMemory;
4053                    }
4054                    rec.reportLowMemory = true;
4055                    rec.lastLowMemory = now;
4056                    mProcessesToGc.remove(rec);
4057                    addProcessToGcListLocked(rec);
4058                }
4059            }
4060            if (doReport) {
4061                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4062                mHandler.sendMessage(msg);
4063            }
4064            scheduleAppGcsLocked();
4065        }
4066    }
4067
4068    final void appDiedLocked(ProcessRecord app, int pid,
4069            IApplicationThread thread) {
4070
4071        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4072        synchronized (stats) {
4073            stats.noteProcessDiedLocked(app.info.uid, pid);
4074        }
4075
4076        // Clean up already done if the process has been re-started.
4077        if (app.pid == pid && app.thread != null &&
4078                app.thread.asBinder() == thread.asBinder()) {
4079            boolean doLowMem = app.instrumentationClass == null;
4080            boolean doOomAdj = doLowMem;
4081            if (!app.killedByAm) {
4082                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4083                        + ") has died.");
4084                mAllowLowerMemLevel = true;
4085            } else {
4086                // Note that we always want to do oom adj to update our state with the
4087                // new number of procs.
4088                mAllowLowerMemLevel = false;
4089                doLowMem = false;
4090            }
4091            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4092            if (DEBUG_CLEANUP) Slog.v(
4093                TAG, "Dying app: " + app + ", pid: " + pid
4094                + ", thread: " + thread.asBinder());
4095            handleAppDiedLocked(app, false, true);
4096
4097            if (doOomAdj) {
4098                updateOomAdjLocked();
4099            }
4100            if (doLowMem) {
4101                doLowMemReportIfNeededLocked(app);
4102            }
4103        } else if (app.pid != pid) {
4104            // A new process has already been started.
4105            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4106                    + ") has died and restarted (pid " + app.pid + ").");
4107            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4108        } else if (DEBUG_PROCESSES) {
4109            Slog.d(TAG, "Received spurious death notification for thread "
4110                    + thread.asBinder());
4111        }
4112    }
4113
4114    /**
4115     * If a stack trace dump file is configured, dump process stack traces.
4116     * @param clearTraces causes the dump file to be erased prior to the new
4117     *    traces being written, if true; when false, the new traces will be
4118     *    appended to any existing file content.
4119     * @param firstPids of dalvik VM processes to dump stack traces for first
4120     * @param lastPids of dalvik VM processes to dump stack traces for last
4121     * @param nativeProcs optional list of native process names to dump stack crawls
4122     * @return file containing stack traces, or null if no dump file is configured
4123     */
4124    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4125            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4126        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4127        if (tracesPath == null || tracesPath.length() == 0) {
4128            return null;
4129        }
4130
4131        File tracesFile = new File(tracesPath);
4132        try {
4133            File tracesDir = tracesFile.getParentFile();
4134            if (!tracesDir.exists()) {
4135                tracesFile.mkdirs();
4136                if (!SELinux.restorecon(tracesDir)) {
4137                    return null;
4138                }
4139            }
4140            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4141
4142            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4143            tracesFile.createNewFile();
4144            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4145        } catch (IOException e) {
4146            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4147            return null;
4148        }
4149
4150        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4151        return tracesFile;
4152    }
4153
4154    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4155            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4156        // Use a FileObserver to detect when traces finish writing.
4157        // The order of traces is considered important to maintain for legibility.
4158        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4159            @Override
4160            public synchronized void onEvent(int event, String path) { notify(); }
4161        };
4162
4163        try {
4164            observer.startWatching();
4165
4166            // First collect all of the stacks of the most important pids.
4167            if (firstPids != null) {
4168                try {
4169                    int num = firstPids.size();
4170                    for (int i = 0; i < num; i++) {
4171                        synchronized (observer) {
4172                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4173                            observer.wait(200);  // Wait for write-close, give up after 200msec
4174                        }
4175                    }
4176                } catch (InterruptedException e) {
4177                    Log.wtf(TAG, e);
4178                }
4179            }
4180
4181            // Next collect the stacks of the native pids
4182            if (nativeProcs != null) {
4183                int[] pids = Process.getPidsForCommands(nativeProcs);
4184                if (pids != null) {
4185                    for (int pid : pids) {
4186                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4187                    }
4188                }
4189            }
4190
4191            // Lastly, measure CPU usage.
4192            if (processCpuTracker != null) {
4193                processCpuTracker.init();
4194                System.gc();
4195                processCpuTracker.update();
4196                try {
4197                    synchronized (processCpuTracker) {
4198                        processCpuTracker.wait(500); // measure over 1/2 second.
4199                    }
4200                } catch (InterruptedException e) {
4201                }
4202                processCpuTracker.update();
4203
4204                // We'll take the stack crawls of just the top apps using CPU.
4205                final int N = processCpuTracker.countWorkingStats();
4206                int numProcs = 0;
4207                for (int i=0; i<N && numProcs<5; i++) {
4208                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4209                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4210                        numProcs++;
4211                        try {
4212                            synchronized (observer) {
4213                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4214                                observer.wait(200);  // Wait for write-close, give up after 200msec
4215                            }
4216                        } catch (InterruptedException e) {
4217                            Log.wtf(TAG, e);
4218                        }
4219
4220                    }
4221                }
4222            }
4223        } finally {
4224            observer.stopWatching();
4225        }
4226    }
4227
4228    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4229        if (true || IS_USER_BUILD) {
4230            return;
4231        }
4232        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4233        if (tracesPath == null || tracesPath.length() == 0) {
4234            return;
4235        }
4236
4237        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4238        StrictMode.allowThreadDiskWrites();
4239        try {
4240            final File tracesFile = new File(tracesPath);
4241            final File tracesDir = tracesFile.getParentFile();
4242            final File tracesTmp = new File(tracesDir, "__tmp__");
4243            try {
4244                if (!tracesDir.exists()) {
4245                    tracesFile.mkdirs();
4246                    if (!SELinux.restorecon(tracesDir.getPath())) {
4247                        return;
4248                    }
4249                }
4250                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4251
4252                if (tracesFile.exists()) {
4253                    tracesTmp.delete();
4254                    tracesFile.renameTo(tracesTmp);
4255                }
4256                StringBuilder sb = new StringBuilder();
4257                Time tobj = new Time();
4258                tobj.set(System.currentTimeMillis());
4259                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4260                sb.append(": ");
4261                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4262                sb.append(" since ");
4263                sb.append(msg);
4264                FileOutputStream fos = new FileOutputStream(tracesFile);
4265                fos.write(sb.toString().getBytes());
4266                if (app == null) {
4267                    fos.write("\n*** No application process!".getBytes());
4268                }
4269                fos.close();
4270                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4271            } catch (IOException e) {
4272                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4273                return;
4274            }
4275
4276            if (app != null) {
4277                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4278                firstPids.add(app.pid);
4279                dumpStackTraces(tracesPath, firstPids, null, null, null);
4280            }
4281
4282            File lastTracesFile = null;
4283            File curTracesFile = null;
4284            for (int i=9; i>=0; i--) {
4285                String name = String.format(Locale.US, "slow%02d.txt", i);
4286                curTracesFile = new File(tracesDir, name);
4287                if (curTracesFile.exists()) {
4288                    if (lastTracesFile != null) {
4289                        curTracesFile.renameTo(lastTracesFile);
4290                    } else {
4291                        curTracesFile.delete();
4292                    }
4293                }
4294                lastTracesFile = curTracesFile;
4295            }
4296            tracesFile.renameTo(curTracesFile);
4297            if (tracesTmp.exists()) {
4298                tracesTmp.renameTo(tracesFile);
4299            }
4300        } finally {
4301            StrictMode.setThreadPolicy(oldPolicy);
4302        }
4303    }
4304
4305    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4306            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4307        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4308        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4309
4310        if (mController != null) {
4311            try {
4312                // 0 == continue, -1 = kill process immediately
4313                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4314                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4315            } catch (RemoteException e) {
4316                mController = null;
4317                Watchdog.getInstance().setActivityController(null);
4318            }
4319        }
4320
4321        long anrTime = SystemClock.uptimeMillis();
4322        if (MONITOR_CPU_USAGE) {
4323            updateCpuStatsNow();
4324        }
4325
4326        synchronized (this) {
4327            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4328            if (mShuttingDown) {
4329                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4330                return;
4331            } else if (app.notResponding) {
4332                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4333                return;
4334            } else if (app.crashing) {
4335                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4336                return;
4337            }
4338
4339            // In case we come through here for the same app before completing
4340            // this one, mark as anring now so we will bail out.
4341            app.notResponding = true;
4342
4343            // Log the ANR to the event log.
4344            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4345                    app.processName, app.info.flags, annotation);
4346
4347            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4348            firstPids.add(app.pid);
4349
4350            int parentPid = app.pid;
4351            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4352            if (parentPid != app.pid) firstPids.add(parentPid);
4353
4354            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4355
4356            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4357                ProcessRecord r = mLruProcesses.get(i);
4358                if (r != null && r.thread != null) {
4359                    int pid = r.pid;
4360                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4361                        if (r.persistent) {
4362                            firstPids.add(pid);
4363                        } else {
4364                            lastPids.put(pid, Boolean.TRUE);
4365                        }
4366                    }
4367                }
4368            }
4369        }
4370
4371        // Log the ANR to the main log.
4372        StringBuilder info = new StringBuilder();
4373        info.setLength(0);
4374        info.append("ANR in ").append(app.processName);
4375        if (activity != null && activity.shortComponentName != null) {
4376            info.append(" (").append(activity.shortComponentName).append(")");
4377        }
4378        info.append("\n");
4379        info.append("PID: ").append(app.pid).append("\n");
4380        if (annotation != null) {
4381            info.append("Reason: ").append(annotation).append("\n");
4382        }
4383        if (parent != null && parent != activity) {
4384            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4385        }
4386
4387        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4388
4389        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4390                NATIVE_STACKS_OF_INTEREST);
4391
4392        String cpuInfo = null;
4393        if (MONITOR_CPU_USAGE) {
4394            updateCpuStatsNow();
4395            synchronized (mProcessCpuThread) {
4396                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4397            }
4398            info.append(processCpuTracker.printCurrentLoad());
4399            info.append(cpuInfo);
4400        }
4401
4402        info.append(processCpuTracker.printCurrentState(anrTime));
4403
4404        Slog.e(TAG, info.toString());
4405        if (tracesFile == null) {
4406            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4407            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4408        }
4409
4410        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4411                cpuInfo, tracesFile, null);
4412
4413        if (mController != null) {
4414            try {
4415                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4416                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4417                if (res != 0) {
4418                    if (res < 0 && app.pid != MY_PID) {
4419                        Process.killProcess(app.pid);
4420                    } else {
4421                        synchronized (this) {
4422                            mServices.scheduleServiceTimeoutLocked(app);
4423                        }
4424                    }
4425                    return;
4426                }
4427            } catch (RemoteException e) {
4428                mController = null;
4429                Watchdog.getInstance().setActivityController(null);
4430            }
4431        }
4432
4433        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4434        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4435                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4436
4437        synchronized (this) {
4438            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4439                killUnneededProcessLocked(app, "background ANR");
4440                return;
4441            }
4442
4443            // Set the app's notResponding state, and look up the errorReportReceiver
4444            makeAppNotRespondingLocked(app,
4445                    activity != null ? activity.shortComponentName : null,
4446                    annotation != null ? "ANR " + annotation : "ANR",
4447                    info.toString());
4448
4449            // Bring up the infamous App Not Responding dialog
4450            Message msg = Message.obtain();
4451            HashMap<String, Object> map = new HashMap<String, Object>();
4452            msg.what = SHOW_NOT_RESPONDING_MSG;
4453            msg.obj = map;
4454            msg.arg1 = aboveSystem ? 1 : 0;
4455            map.put("app", app);
4456            if (activity != null) {
4457                map.put("activity", activity);
4458            }
4459
4460            mHandler.sendMessage(msg);
4461        }
4462    }
4463
4464    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4465        if (!mLaunchWarningShown) {
4466            mLaunchWarningShown = true;
4467            mHandler.post(new Runnable() {
4468                @Override
4469                public void run() {
4470                    synchronized (ActivityManagerService.this) {
4471                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4472                        d.show();
4473                        mHandler.postDelayed(new Runnable() {
4474                            @Override
4475                            public void run() {
4476                                synchronized (ActivityManagerService.this) {
4477                                    d.dismiss();
4478                                    mLaunchWarningShown = false;
4479                                }
4480                            }
4481                        }, 4000);
4482                    }
4483                }
4484            });
4485        }
4486    }
4487
4488    @Override
4489    public boolean clearApplicationUserData(final String packageName,
4490            final IPackageDataObserver observer, int userId) {
4491        enforceNotIsolatedCaller("clearApplicationUserData");
4492        int uid = Binder.getCallingUid();
4493        int pid = Binder.getCallingPid();
4494        userId = handleIncomingUser(pid, uid,
4495                userId, false, true, "clearApplicationUserData", null);
4496        long callingId = Binder.clearCallingIdentity();
4497        try {
4498            IPackageManager pm = AppGlobals.getPackageManager();
4499            int pkgUid = -1;
4500            synchronized(this) {
4501                try {
4502                    pkgUid = pm.getPackageUid(packageName, userId);
4503                } catch (RemoteException e) {
4504                }
4505                if (pkgUid == -1) {
4506                    Slog.w(TAG, "Invalid packageName: " + packageName);
4507                    if (observer != null) {
4508                        try {
4509                            observer.onRemoveCompleted(packageName, false);
4510                        } catch (RemoteException e) {
4511                            Slog.i(TAG, "Observer no longer exists.");
4512                        }
4513                    }
4514                    return false;
4515                }
4516                if (uid == pkgUid || checkComponentPermission(
4517                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4518                        pid, uid, -1, true)
4519                        == PackageManager.PERMISSION_GRANTED) {
4520                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4521                } else {
4522                    throw new SecurityException("PID " + pid + " does not have permission "
4523                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4524                                    + " of package " + packageName);
4525                }
4526            }
4527
4528            try {
4529                // Clear application user data
4530                pm.clearApplicationUserData(packageName, observer, userId);
4531
4532                // Remove all permissions granted from/to this package
4533                removeUriPermissionsForPackageLocked(packageName, userId, true);
4534
4535                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4536                        Uri.fromParts("package", packageName, null));
4537                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4538                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4539                        null, null, 0, null, null, null, false, false, userId);
4540            } catch (RemoteException e) {
4541            }
4542        } finally {
4543            Binder.restoreCallingIdentity(callingId);
4544        }
4545        return true;
4546    }
4547
4548    @Override
4549    public void killBackgroundProcesses(final String packageName, int userId) {
4550        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4551                != PackageManager.PERMISSION_GRANTED &&
4552                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4553                        != PackageManager.PERMISSION_GRANTED) {
4554            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4555                    + Binder.getCallingPid()
4556                    + ", uid=" + Binder.getCallingUid()
4557                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4558            Slog.w(TAG, msg);
4559            throw new SecurityException(msg);
4560        }
4561
4562        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4563                userId, true, true, "killBackgroundProcesses", null);
4564        long callingId = Binder.clearCallingIdentity();
4565        try {
4566            IPackageManager pm = AppGlobals.getPackageManager();
4567            synchronized(this) {
4568                int appId = -1;
4569                try {
4570                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4571                } catch (RemoteException e) {
4572                }
4573                if (appId == -1) {
4574                    Slog.w(TAG, "Invalid packageName: " + packageName);
4575                    return;
4576                }
4577                killPackageProcessesLocked(packageName, appId, userId,
4578                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4579            }
4580        } finally {
4581            Binder.restoreCallingIdentity(callingId);
4582        }
4583    }
4584
4585    @Override
4586    public void killAllBackgroundProcesses() {
4587        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4588                != PackageManager.PERMISSION_GRANTED) {
4589            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4590                    + Binder.getCallingPid()
4591                    + ", uid=" + Binder.getCallingUid()
4592                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4593            Slog.w(TAG, msg);
4594            throw new SecurityException(msg);
4595        }
4596
4597        long callingId = Binder.clearCallingIdentity();
4598        try {
4599            synchronized(this) {
4600                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4601                final int NP = mProcessNames.getMap().size();
4602                for (int ip=0; ip<NP; ip++) {
4603                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4604                    final int NA = apps.size();
4605                    for (int ia=0; ia<NA; ia++) {
4606                        ProcessRecord app = apps.valueAt(ia);
4607                        if (app.persistent) {
4608                            // we don't kill persistent processes
4609                            continue;
4610                        }
4611                        if (app.removed) {
4612                            procs.add(app);
4613                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4614                            app.removed = true;
4615                            procs.add(app);
4616                        }
4617                    }
4618                }
4619
4620                int N = procs.size();
4621                for (int i=0; i<N; i++) {
4622                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4623                }
4624                mAllowLowerMemLevel = true;
4625                updateOomAdjLocked();
4626                doLowMemReportIfNeededLocked(null);
4627            }
4628        } finally {
4629            Binder.restoreCallingIdentity(callingId);
4630        }
4631    }
4632
4633    @Override
4634    public void forceStopPackage(final String packageName, int userId) {
4635        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4636                != PackageManager.PERMISSION_GRANTED) {
4637            String msg = "Permission Denial: forceStopPackage() from pid="
4638                    + Binder.getCallingPid()
4639                    + ", uid=" + Binder.getCallingUid()
4640                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4641            Slog.w(TAG, msg);
4642            throw new SecurityException(msg);
4643        }
4644        final int callingPid = Binder.getCallingPid();
4645        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4646                userId, true, true, "forceStopPackage", null);
4647        long callingId = Binder.clearCallingIdentity();
4648        try {
4649            IPackageManager pm = AppGlobals.getPackageManager();
4650            synchronized(this) {
4651                int[] users = userId == UserHandle.USER_ALL
4652                        ? getUsersLocked() : new int[] { userId };
4653                for (int user : users) {
4654                    int pkgUid = -1;
4655                    try {
4656                        pkgUid = pm.getPackageUid(packageName, user);
4657                    } catch (RemoteException e) {
4658                    }
4659                    if (pkgUid == -1) {
4660                        Slog.w(TAG, "Invalid packageName: " + packageName);
4661                        continue;
4662                    }
4663                    try {
4664                        pm.setPackageStoppedState(packageName, true, user);
4665                    } catch (RemoteException e) {
4666                    } catch (IllegalArgumentException e) {
4667                        Slog.w(TAG, "Failed trying to unstop package "
4668                                + packageName + ": " + e);
4669                    }
4670                    if (isUserRunningLocked(user, false)) {
4671                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4672                    }
4673                }
4674            }
4675        } finally {
4676            Binder.restoreCallingIdentity(callingId);
4677        }
4678    }
4679
4680    /*
4681     * The pkg name and app id have to be specified.
4682     */
4683    @Override
4684    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4685        if (pkg == null) {
4686            return;
4687        }
4688        // Make sure the uid is valid.
4689        if (appid < 0) {
4690            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4691            return;
4692        }
4693        int callerUid = Binder.getCallingUid();
4694        // Only the system server can kill an application
4695        if (callerUid == Process.SYSTEM_UID) {
4696            // Post an aysnc message to kill the application
4697            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4698            msg.arg1 = appid;
4699            msg.arg2 = 0;
4700            Bundle bundle = new Bundle();
4701            bundle.putString("pkg", pkg);
4702            bundle.putString("reason", reason);
4703            msg.obj = bundle;
4704            mHandler.sendMessage(msg);
4705        } else {
4706            throw new SecurityException(callerUid + " cannot kill pkg: " +
4707                    pkg);
4708        }
4709    }
4710
4711    @Override
4712    public void closeSystemDialogs(String reason) {
4713        enforceNotIsolatedCaller("closeSystemDialogs");
4714
4715        final int pid = Binder.getCallingPid();
4716        final int uid = Binder.getCallingUid();
4717        final long origId = Binder.clearCallingIdentity();
4718        try {
4719            synchronized (this) {
4720                // Only allow this from foreground processes, so that background
4721                // applications can't abuse it to prevent system UI from being shown.
4722                if (uid >= Process.FIRST_APPLICATION_UID) {
4723                    ProcessRecord proc;
4724                    synchronized (mPidsSelfLocked) {
4725                        proc = mPidsSelfLocked.get(pid);
4726                    }
4727                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4728                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4729                                + " from background process " + proc);
4730                        return;
4731                    }
4732                }
4733                closeSystemDialogsLocked(reason);
4734            }
4735        } finally {
4736            Binder.restoreCallingIdentity(origId);
4737        }
4738    }
4739
4740    void closeSystemDialogsLocked(String reason) {
4741        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4742        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4743                | Intent.FLAG_RECEIVER_FOREGROUND);
4744        if (reason != null) {
4745            intent.putExtra("reason", reason);
4746        }
4747        mWindowManager.closeSystemDialogs(reason);
4748
4749        mStackSupervisor.closeSystemDialogsLocked();
4750
4751        broadcastIntentLocked(null, null, intent, null,
4752                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4753                Process.SYSTEM_UID, UserHandle.USER_ALL);
4754    }
4755
4756    @Override
4757    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4758        enforceNotIsolatedCaller("getProcessMemoryInfo");
4759        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4760        for (int i=pids.length-1; i>=0; i--) {
4761            ProcessRecord proc;
4762            int oomAdj;
4763            synchronized (this) {
4764                synchronized (mPidsSelfLocked) {
4765                    proc = mPidsSelfLocked.get(pids[i]);
4766                    oomAdj = proc != null ? proc.setAdj : 0;
4767                }
4768            }
4769            infos[i] = new Debug.MemoryInfo();
4770            Debug.getMemoryInfo(pids[i], infos[i]);
4771            if (proc != null) {
4772                synchronized (this) {
4773                    if (proc.thread != null && proc.setAdj == oomAdj) {
4774                        // Record this for posterity if the process has been stable.
4775                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4776                                infos[i].getTotalUss(), false, proc.pkgList);
4777                    }
4778                }
4779            }
4780        }
4781        return infos;
4782    }
4783
4784    @Override
4785    public long[] getProcessPss(int[] pids) {
4786        enforceNotIsolatedCaller("getProcessPss");
4787        long[] pss = new long[pids.length];
4788        for (int i=pids.length-1; i>=0; i--) {
4789            ProcessRecord proc;
4790            int oomAdj;
4791            synchronized (this) {
4792                synchronized (mPidsSelfLocked) {
4793                    proc = mPidsSelfLocked.get(pids[i]);
4794                    oomAdj = proc != null ? proc.setAdj : 0;
4795                }
4796            }
4797            long[] tmpUss = new long[1];
4798            pss[i] = Debug.getPss(pids[i], tmpUss);
4799            if (proc != null) {
4800                synchronized (this) {
4801                    if (proc.thread != null && proc.setAdj == oomAdj) {
4802                        // Record this for posterity if the process has been stable.
4803                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4804                    }
4805                }
4806            }
4807        }
4808        return pss;
4809    }
4810
4811    @Override
4812    public void killApplicationProcess(String processName, int uid) {
4813        if (processName == null) {
4814            return;
4815        }
4816
4817        int callerUid = Binder.getCallingUid();
4818        // Only the system server can kill an application
4819        if (callerUid == Process.SYSTEM_UID) {
4820            synchronized (this) {
4821                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4822                if (app != null && app.thread != null) {
4823                    try {
4824                        app.thread.scheduleSuicide();
4825                    } catch (RemoteException e) {
4826                        // If the other end already died, then our work here is done.
4827                    }
4828                } else {
4829                    Slog.w(TAG, "Process/uid not found attempting kill of "
4830                            + processName + " / " + uid);
4831                }
4832            }
4833        } else {
4834            throw new SecurityException(callerUid + " cannot kill app process: " +
4835                    processName);
4836        }
4837    }
4838
4839    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4840        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4841                false, true, false, false, UserHandle.getUserId(uid), reason);
4842        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4843                Uri.fromParts("package", packageName, null));
4844        if (!mProcessesReady) {
4845            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4846                    | Intent.FLAG_RECEIVER_FOREGROUND);
4847        }
4848        intent.putExtra(Intent.EXTRA_UID, uid);
4849        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4850        broadcastIntentLocked(null, null, intent,
4851                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4852                false, false,
4853                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4854    }
4855
4856    private void forceStopUserLocked(int userId, String reason) {
4857        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4858        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4859        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4860                | Intent.FLAG_RECEIVER_FOREGROUND);
4861        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4862        broadcastIntentLocked(null, null, intent,
4863                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4864                false, false,
4865                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4866    }
4867
4868    private final boolean killPackageProcessesLocked(String packageName, int appId,
4869            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4870            boolean doit, boolean evenPersistent, String reason) {
4871        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4872
4873        // Remove all processes this package may have touched: all with the
4874        // same UID (except for the system or root user), and all whose name
4875        // matches the package name.
4876        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4877        final int NP = mProcessNames.getMap().size();
4878        for (int ip=0; ip<NP; ip++) {
4879            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4880            final int NA = apps.size();
4881            for (int ia=0; ia<NA; ia++) {
4882                ProcessRecord app = apps.valueAt(ia);
4883                if (app.persistent && !evenPersistent) {
4884                    // we don't kill persistent processes
4885                    continue;
4886                }
4887                if (app.removed) {
4888                    if (doit) {
4889                        procs.add(app);
4890                    }
4891                    continue;
4892                }
4893
4894                // Skip process if it doesn't meet our oom adj requirement.
4895                if (app.setAdj < minOomAdj) {
4896                    continue;
4897                }
4898
4899                // If no package is specified, we call all processes under the
4900                // give user id.
4901                if (packageName == null) {
4902                    if (app.userId != userId) {
4903                        continue;
4904                    }
4905                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4906                        continue;
4907                    }
4908                // Package has been specified, we want to hit all processes
4909                // that match it.  We need to qualify this by the processes
4910                // that are running under the specified app and user ID.
4911                } else {
4912                    if (UserHandle.getAppId(app.uid) != appId) {
4913                        continue;
4914                    }
4915                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4916                        continue;
4917                    }
4918                    if (!app.pkgList.containsKey(packageName)) {
4919                        continue;
4920                    }
4921                }
4922
4923                // Process has passed all conditions, kill it!
4924                if (!doit) {
4925                    return true;
4926                }
4927                app.removed = true;
4928                procs.add(app);
4929            }
4930        }
4931
4932        int N = procs.size();
4933        for (int i=0; i<N; i++) {
4934            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4935        }
4936        updateOomAdjLocked();
4937        return N > 0;
4938    }
4939
4940    private final boolean forceStopPackageLocked(String name, int appId,
4941            boolean callerWillRestart, boolean purgeCache, boolean doit,
4942            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4943        int i;
4944        int N;
4945
4946        if (userId == UserHandle.USER_ALL && name == null) {
4947            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4948        }
4949
4950        if (appId < 0 && name != null) {
4951            try {
4952                appId = UserHandle.getAppId(
4953                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4954            } catch (RemoteException e) {
4955            }
4956        }
4957
4958        if (doit) {
4959            if (name != null) {
4960                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4961                        + " user=" + userId + ": " + reason);
4962            } else {
4963                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4964            }
4965
4966            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4967            for (int ip=pmap.size()-1; ip>=0; ip--) {
4968                SparseArray<Long> ba = pmap.valueAt(ip);
4969                for (i=ba.size()-1; i>=0; i--) {
4970                    boolean remove = false;
4971                    final int entUid = ba.keyAt(i);
4972                    if (name != null) {
4973                        if (userId == UserHandle.USER_ALL) {
4974                            if (UserHandle.getAppId(entUid) == appId) {
4975                                remove = true;
4976                            }
4977                        } else {
4978                            if (entUid == UserHandle.getUid(userId, appId)) {
4979                                remove = true;
4980                            }
4981                        }
4982                    } else if (UserHandle.getUserId(entUid) == userId) {
4983                        remove = true;
4984                    }
4985                    if (remove) {
4986                        ba.removeAt(i);
4987                    }
4988                }
4989                if (ba.size() == 0) {
4990                    pmap.removeAt(ip);
4991                }
4992            }
4993        }
4994
4995        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4996                -100, callerWillRestart, true, doit, evenPersistent,
4997                name == null ? ("stop user " + userId) : ("stop " + name));
4998
4999        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5000            if (!doit) {
5001                return true;
5002            }
5003            didSomething = true;
5004        }
5005
5006        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5007            if (!doit) {
5008                return true;
5009            }
5010            didSomething = true;
5011        }
5012
5013        if (name == null) {
5014            // Remove all sticky broadcasts from this user.
5015            mStickyBroadcasts.remove(userId);
5016        }
5017
5018        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5019        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5020                userId, providers)) {
5021            if (!doit) {
5022                return true;
5023            }
5024            didSomething = true;
5025        }
5026        N = providers.size();
5027        for (i=0; i<N; i++) {
5028            removeDyingProviderLocked(null, providers.get(i), true);
5029        }
5030
5031        // Remove transient permissions granted from/to this package/user
5032        removeUriPermissionsForPackageLocked(name, userId, false);
5033
5034        if (name == null || uninstalling) {
5035            // Remove pending intents.  For now we only do this when force
5036            // stopping users, because we have some problems when doing this
5037            // for packages -- app widgets are not currently cleaned up for
5038            // such packages, so they can be left with bad pending intents.
5039            if (mIntentSenderRecords.size() > 0) {
5040                Iterator<WeakReference<PendingIntentRecord>> it
5041                        = mIntentSenderRecords.values().iterator();
5042                while (it.hasNext()) {
5043                    WeakReference<PendingIntentRecord> wpir = it.next();
5044                    if (wpir == null) {
5045                        it.remove();
5046                        continue;
5047                    }
5048                    PendingIntentRecord pir = wpir.get();
5049                    if (pir == null) {
5050                        it.remove();
5051                        continue;
5052                    }
5053                    if (name == null) {
5054                        // Stopping user, remove all objects for the user.
5055                        if (pir.key.userId != userId) {
5056                            // Not the same user, skip it.
5057                            continue;
5058                        }
5059                    } else {
5060                        if (UserHandle.getAppId(pir.uid) != appId) {
5061                            // Different app id, skip it.
5062                            continue;
5063                        }
5064                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5065                            // Different user, skip it.
5066                            continue;
5067                        }
5068                        if (!pir.key.packageName.equals(name)) {
5069                            // Different package, skip it.
5070                            continue;
5071                        }
5072                    }
5073                    if (!doit) {
5074                        return true;
5075                    }
5076                    didSomething = true;
5077                    it.remove();
5078                    pir.canceled = true;
5079                    if (pir.key.activity != null) {
5080                        pir.key.activity.pendingResults.remove(pir.ref);
5081                    }
5082                }
5083            }
5084        }
5085
5086        if (doit) {
5087            if (purgeCache && name != null) {
5088                AttributeCache ac = AttributeCache.instance();
5089                if (ac != null) {
5090                    ac.removePackage(name);
5091                }
5092            }
5093            if (mBooted) {
5094                mStackSupervisor.resumeTopActivitiesLocked();
5095                mStackSupervisor.scheduleIdleLocked();
5096            }
5097        }
5098
5099        return didSomething;
5100    }
5101
5102    private final boolean removeProcessLocked(ProcessRecord app,
5103            boolean callerWillRestart, boolean allowRestart, String reason) {
5104        final String name = app.processName;
5105        final int uid = app.uid;
5106        if (DEBUG_PROCESSES) Slog.d(
5107            TAG, "Force removing proc " + app.toShortString() + " (" + name
5108            + "/" + uid + ")");
5109
5110        mProcessNames.remove(name, uid);
5111        mIsolatedProcesses.remove(app.uid);
5112        if (mHeavyWeightProcess == app) {
5113            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5114                    mHeavyWeightProcess.userId, 0));
5115            mHeavyWeightProcess = null;
5116        }
5117        boolean needRestart = false;
5118        if (app.pid > 0 && app.pid != MY_PID) {
5119            int pid = app.pid;
5120            synchronized (mPidsSelfLocked) {
5121                mPidsSelfLocked.remove(pid);
5122                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5123            }
5124            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5125                    app.processName, app.info.uid);
5126            if (app.isolated) {
5127                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5128            }
5129            killUnneededProcessLocked(app, reason);
5130            handleAppDiedLocked(app, true, allowRestart);
5131            removeLruProcessLocked(app);
5132
5133            if (app.persistent && !app.isolated) {
5134                if (!callerWillRestart) {
5135                    addAppLocked(app.info, false, null /* ABI override */);
5136                } else {
5137                    needRestart = true;
5138                }
5139            }
5140        } else {
5141            mRemovedProcesses.add(app);
5142        }
5143
5144        return needRestart;
5145    }
5146
5147    private final void processStartTimedOutLocked(ProcessRecord app) {
5148        final int pid = app.pid;
5149        boolean gone = false;
5150        synchronized (mPidsSelfLocked) {
5151            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5152            if (knownApp != null && knownApp.thread == null) {
5153                mPidsSelfLocked.remove(pid);
5154                gone = true;
5155            }
5156        }
5157
5158        if (gone) {
5159            Slog.w(TAG, "Process " + app + " failed to attach");
5160            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5161                    pid, app.uid, app.processName);
5162            mProcessNames.remove(app.processName, app.uid);
5163            mIsolatedProcesses.remove(app.uid);
5164            if (mHeavyWeightProcess == app) {
5165                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5166                        mHeavyWeightProcess.userId, 0));
5167                mHeavyWeightProcess = null;
5168            }
5169            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5170                    app.processName, app.info.uid);
5171            if (app.isolated) {
5172                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5173            }
5174            // Take care of any launching providers waiting for this process.
5175            checkAppInLaunchingProvidersLocked(app, true);
5176            // Take care of any services that are waiting for the process.
5177            mServices.processStartTimedOutLocked(app);
5178            killUnneededProcessLocked(app, "start timeout");
5179            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5180                Slog.w(TAG, "Unattached app died before backup, skipping");
5181                try {
5182                    IBackupManager bm = IBackupManager.Stub.asInterface(
5183                            ServiceManager.getService(Context.BACKUP_SERVICE));
5184                    bm.agentDisconnected(app.info.packageName);
5185                } catch (RemoteException e) {
5186                    // Can't happen; the backup manager is local
5187                }
5188            }
5189            if (isPendingBroadcastProcessLocked(pid)) {
5190                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5191                skipPendingBroadcastLocked(pid);
5192            }
5193        } else {
5194            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5195        }
5196    }
5197
5198    private final boolean attachApplicationLocked(IApplicationThread thread,
5199            int pid) {
5200
5201        // Find the application record that is being attached...  either via
5202        // the pid if we are running in multiple processes, or just pull the
5203        // next app record if we are emulating process with anonymous threads.
5204        ProcessRecord app;
5205        if (pid != MY_PID && pid >= 0) {
5206            synchronized (mPidsSelfLocked) {
5207                app = mPidsSelfLocked.get(pid);
5208            }
5209        } else {
5210            app = null;
5211        }
5212
5213        if (app == null) {
5214            Slog.w(TAG, "No pending application record for pid " + pid
5215                    + " (IApplicationThread " + thread + "); dropping process");
5216            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5217            if (pid > 0 && pid != MY_PID) {
5218                Process.killProcessQuiet(pid);
5219            } else {
5220                try {
5221                    thread.scheduleExit();
5222                } catch (Exception e) {
5223                    // Ignore exceptions.
5224                }
5225            }
5226            return false;
5227        }
5228
5229        // If this application record is still attached to a previous
5230        // process, clean it up now.
5231        if (app.thread != null) {
5232            handleAppDiedLocked(app, true, true);
5233        }
5234
5235        // Tell the process all about itself.
5236
5237        if (localLOGV) Slog.v(
5238                TAG, "Binding process pid " + pid + " to record " + app);
5239
5240        final String processName = app.processName;
5241        try {
5242            AppDeathRecipient adr = new AppDeathRecipient(
5243                    app, pid, thread);
5244            thread.asBinder().linkToDeath(adr, 0);
5245            app.deathRecipient = adr;
5246        } catch (RemoteException e) {
5247            app.resetPackageList(mProcessStats);
5248            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5249            return false;
5250        }
5251
5252        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5253
5254        app.makeActive(thread, mProcessStats);
5255        app.curAdj = app.setAdj = -100;
5256        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5257        app.forcingToForeground = null;
5258        updateProcessForegroundLocked(app, false, false);
5259        app.hasShownUi = false;
5260        app.debugging = false;
5261        app.cached = false;
5262
5263        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5264
5265        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5266        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5267
5268        if (!normalMode) {
5269            Slog.i(TAG, "Launching preboot mode app: " + app);
5270        }
5271
5272        if (localLOGV) Slog.v(
5273            TAG, "New app record " + app
5274            + " thread=" + thread.asBinder() + " pid=" + pid);
5275        try {
5276            int testMode = IApplicationThread.DEBUG_OFF;
5277            if (mDebugApp != null && mDebugApp.equals(processName)) {
5278                testMode = mWaitForDebugger
5279                    ? IApplicationThread.DEBUG_WAIT
5280                    : IApplicationThread.DEBUG_ON;
5281                app.debugging = true;
5282                if (mDebugTransient) {
5283                    mDebugApp = mOrigDebugApp;
5284                    mWaitForDebugger = mOrigWaitForDebugger;
5285                }
5286            }
5287            String profileFile = app.instrumentationProfileFile;
5288            ParcelFileDescriptor profileFd = null;
5289            boolean profileAutoStop = false;
5290            if (mProfileApp != null && mProfileApp.equals(processName)) {
5291                mProfileProc = app;
5292                profileFile = mProfileFile;
5293                profileFd = mProfileFd;
5294                profileAutoStop = mAutoStopProfiler;
5295            }
5296            boolean enableOpenGlTrace = false;
5297            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5298                enableOpenGlTrace = true;
5299                mOpenGlTraceApp = null;
5300            }
5301
5302            // If the app is being launched for restore or full backup, set it up specially
5303            boolean isRestrictedBackupMode = false;
5304            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5305                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5306                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5307                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5308            }
5309
5310            ensurePackageDexOpt(app.instrumentationInfo != null
5311                    ? app.instrumentationInfo.packageName
5312                    : app.info.packageName);
5313            if (app.instrumentationClass != null) {
5314                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5315            }
5316            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5317                    + processName + " with config " + mConfiguration);
5318            ApplicationInfo appInfo = app.instrumentationInfo != null
5319                    ? app.instrumentationInfo : app.info;
5320            app.compat = compatibilityInfoForPackageLocked(appInfo);
5321            if (profileFd != null) {
5322                profileFd = profileFd.dup();
5323            }
5324            thread.bindApplication(processName, appInfo, providers,
5325                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5326                    app.instrumentationArguments, app.instrumentationWatcher,
5327                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5328                    isRestrictedBackupMode || !normalMode, app.persistent,
5329                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5330                    mCoreSettingsObserver.getCoreSettingsLocked());
5331            updateLruProcessLocked(app, false, null);
5332            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5333        } catch (Exception e) {
5334            // todo: Yikes!  What should we do?  For now we will try to
5335            // start another process, but that could easily get us in
5336            // an infinite loop of restarting processes...
5337            Slog.w(TAG, "Exception thrown during bind!", e);
5338
5339            app.resetPackageList(mProcessStats);
5340            app.unlinkDeathRecipient();
5341            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5342            return false;
5343        }
5344
5345        // Remove this record from the list of starting applications.
5346        mPersistentStartingProcesses.remove(app);
5347        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5348                "Attach application locked removing on hold: " + app);
5349        mProcessesOnHold.remove(app);
5350
5351        boolean badApp = false;
5352        boolean didSomething = false;
5353
5354        // See if the top visible activity is waiting to run in this process...
5355        if (normalMode) {
5356            try {
5357                if (mStackSupervisor.attachApplicationLocked(app)) {
5358                    didSomething = true;
5359                }
5360            } catch (Exception e) {
5361                badApp = true;
5362            }
5363        }
5364
5365        // Find any services that should be running in this process...
5366        if (!badApp) {
5367            try {
5368                didSomething |= mServices.attachApplicationLocked(app, processName);
5369            } catch (Exception e) {
5370                badApp = true;
5371            }
5372        }
5373
5374        // Check if a next-broadcast receiver is in this process...
5375        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5376            try {
5377                didSomething |= sendPendingBroadcastsLocked(app);
5378            } catch (Exception e) {
5379                // If the app died trying to launch the receiver we declare it 'bad'
5380                badApp = true;
5381            }
5382        }
5383
5384        // Check whether the next backup agent is in this process...
5385        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5386            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5387            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5388            try {
5389                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5390                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5391                        mBackupTarget.backupMode);
5392            } catch (Exception e) {
5393                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5394                e.printStackTrace();
5395            }
5396        }
5397
5398        if (badApp) {
5399            // todo: Also need to kill application to deal with all
5400            // kinds of exceptions.
5401            handleAppDiedLocked(app, false, true);
5402            return false;
5403        }
5404
5405        if (!didSomething) {
5406            updateOomAdjLocked();
5407        }
5408
5409        return true;
5410    }
5411
5412    @Override
5413    public final void attachApplication(IApplicationThread thread) {
5414        synchronized (this) {
5415            int callingPid = Binder.getCallingPid();
5416            final long origId = Binder.clearCallingIdentity();
5417            attachApplicationLocked(thread, callingPid);
5418            Binder.restoreCallingIdentity(origId);
5419        }
5420    }
5421
5422    @Override
5423    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5424        final long origId = Binder.clearCallingIdentity();
5425        synchronized (this) {
5426            ActivityStack stack = ActivityRecord.getStackLocked(token);
5427            if (stack != null) {
5428                ActivityRecord r =
5429                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5430                if (stopProfiling) {
5431                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5432                        try {
5433                            mProfileFd.close();
5434                        } catch (IOException e) {
5435                        }
5436                        clearProfilerLocked();
5437                    }
5438                }
5439            }
5440        }
5441        Binder.restoreCallingIdentity(origId);
5442    }
5443
5444    void enableScreenAfterBoot() {
5445        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5446                SystemClock.uptimeMillis());
5447        mWindowManager.enableScreenAfterBoot();
5448
5449        synchronized (this) {
5450            updateEventDispatchingLocked();
5451        }
5452    }
5453
5454    @Override
5455    public void showBootMessage(final CharSequence msg, final boolean always) {
5456        enforceNotIsolatedCaller("showBootMessage");
5457        mWindowManager.showBootMessage(msg, always);
5458    }
5459
5460    @Override
5461    public void dismissKeyguardOnNextActivity() {
5462        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5463        final long token = Binder.clearCallingIdentity();
5464        try {
5465            synchronized (this) {
5466                if (DEBUG_LOCKSCREEN) logLockScreen("");
5467                if (mLockScreenShown) {
5468                    mLockScreenShown = false;
5469                    comeOutOfSleepIfNeededLocked();
5470                }
5471                mStackSupervisor.setDismissKeyguard(true);
5472            }
5473        } finally {
5474            Binder.restoreCallingIdentity(token);
5475        }
5476    }
5477
5478    final void finishBooting() {
5479        // Register receivers to handle package update events
5480        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5481
5482        synchronized (this) {
5483            // Ensure that any processes we had put on hold are now started
5484            // up.
5485            final int NP = mProcessesOnHold.size();
5486            if (NP > 0) {
5487                ArrayList<ProcessRecord> procs =
5488                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5489                for (int ip=0; ip<NP; ip++) {
5490                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5491                            + procs.get(ip));
5492                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5493                }
5494            }
5495
5496            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5497                // Start looking for apps that are abusing wake locks.
5498                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5499                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5500                // Tell anyone interested that we are done booting!
5501                SystemProperties.set("sys.boot_completed", "1");
5502                SystemProperties.set("dev.bootcomplete", "1");
5503                for (int i=0; i<mStartedUsers.size(); i++) {
5504                    UserStartedState uss = mStartedUsers.valueAt(i);
5505                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5506                        uss.mState = UserStartedState.STATE_RUNNING;
5507                        final int userId = mStartedUsers.keyAt(i);
5508                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5509                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5510                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5511                        broadcastIntentLocked(null, null, intent, null,
5512                                new IIntentReceiver.Stub() {
5513                                    @Override
5514                                    public void performReceive(Intent intent, int resultCode,
5515                                            String data, Bundle extras, boolean ordered,
5516                                            boolean sticky, int sendingUser) {
5517                                        synchronized (ActivityManagerService.this) {
5518                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5519                                                    true, false);
5520                                        }
5521                                    }
5522                                },
5523                                0, null, null,
5524                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5525                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5526                                userId);
5527                    }
5528                }
5529                scheduleStartProfilesLocked();
5530            }
5531        }
5532    }
5533
5534    final void ensureBootCompleted() {
5535        boolean booting;
5536        boolean enableScreen;
5537        synchronized (this) {
5538            booting = mBooting;
5539            mBooting = false;
5540            enableScreen = !mBooted;
5541            mBooted = true;
5542        }
5543
5544        if (booting) {
5545            finishBooting();
5546        }
5547
5548        if (enableScreen) {
5549            enableScreenAfterBoot();
5550        }
5551    }
5552
5553    @Override
5554    public final void activityResumed(IBinder token) {
5555        final long origId = Binder.clearCallingIdentity();
5556        synchronized(this) {
5557            ActivityStack stack = ActivityRecord.getStackLocked(token);
5558            if (stack != null) {
5559                ActivityRecord.activityResumedLocked(token);
5560            }
5561        }
5562        Binder.restoreCallingIdentity(origId);
5563    }
5564
5565    @Override
5566    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5567        final long origId = Binder.clearCallingIdentity();
5568        synchronized(this) {
5569            ActivityStack stack = ActivityRecord.getStackLocked(token);
5570            if (stack != null) {
5571                stack.activityPausedLocked(token, false, persistentState);
5572            }
5573        }
5574        Binder.restoreCallingIdentity(origId);
5575    }
5576
5577    @Override
5578    public final void activityStopped(IBinder token, Bundle icicle,
5579            PersistableBundle persistentState, CharSequence description) {
5580        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5581
5582        // Refuse possible leaked file descriptors
5583        if (icicle != null && icicle.hasFileDescriptors()) {
5584            throw new IllegalArgumentException("File descriptors passed in Bundle");
5585        }
5586
5587        final long origId = Binder.clearCallingIdentity();
5588
5589        synchronized (this) {
5590            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5591            if (r != null) {
5592                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5593            }
5594        }
5595
5596        trimApplications();
5597
5598        Binder.restoreCallingIdentity(origId);
5599    }
5600
5601    @Override
5602    public final void activityDestroyed(IBinder token) {
5603        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5604        synchronized (this) {
5605            ActivityStack stack = ActivityRecord.getStackLocked(token);
5606            if (stack != null) {
5607                stack.activityDestroyedLocked(token);
5608            }
5609        }
5610    }
5611
5612    @Override
5613    public String getCallingPackage(IBinder token) {
5614        synchronized (this) {
5615            ActivityRecord r = getCallingRecordLocked(token);
5616            return r != null ? r.info.packageName : null;
5617        }
5618    }
5619
5620    @Override
5621    public ComponentName getCallingActivity(IBinder token) {
5622        synchronized (this) {
5623            ActivityRecord r = getCallingRecordLocked(token);
5624            return r != null ? r.intent.getComponent() : null;
5625        }
5626    }
5627
5628    private ActivityRecord getCallingRecordLocked(IBinder token) {
5629        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5630        if (r == null) {
5631            return null;
5632        }
5633        return r.resultTo;
5634    }
5635
5636    @Override
5637    public ComponentName getActivityClassForToken(IBinder token) {
5638        synchronized(this) {
5639            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5640            if (r == null) {
5641                return null;
5642            }
5643            return r.intent.getComponent();
5644        }
5645    }
5646
5647    @Override
5648    public String getPackageForToken(IBinder token) {
5649        synchronized(this) {
5650            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5651            if (r == null) {
5652                return null;
5653            }
5654            return r.packageName;
5655        }
5656    }
5657
5658    @Override
5659    public IIntentSender getIntentSender(int type,
5660            String packageName, IBinder token, String resultWho,
5661            int requestCode, Intent[] intents, String[] resolvedTypes,
5662            int flags, Bundle options, int userId) {
5663        enforceNotIsolatedCaller("getIntentSender");
5664        // Refuse possible leaked file descriptors
5665        if (intents != null) {
5666            if (intents.length < 1) {
5667                throw new IllegalArgumentException("Intents array length must be >= 1");
5668            }
5669            for (int i=0; i<intents.length; i++) {
5670                Intent intent = intents[i];
5671                if (intent != null) {
5672                    if (intent.hasFileDescriptors()) {
5673                        throw new IllegalArgumentException("File descriptors passed in Intent");
5674                    }
5675                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5676                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5677                        throw new IllegalArgumentException(
5678                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5679                    }
5680                    intents[i] = new Intent(intent);
5681                }
5682            }
5683            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5684                throw new IllegalArgumentException(
5685                        "Intent array length does not match resolvedTypes length");
5686            }
5687        }
5688        if (options != null) {
5689            if (options.hasFileDescriptors()) {
5690                throw new IllegalArgumentException("File descriptors passed in options");
5691            }
5692        }
5693
5694        synchronized(this) {
5695            int callingUid = Binder.getCallingUid();
5696            int origUserId = userId;
5697            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5698                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5699                    "getIntentSender", null);
5700            if (origUserId == UserHandle.USER_CURRENT) {
5701                // We don't want to evaluate this until the pending intent is
5702                // actually executed.  However, we do want to always do the
5703                // security checking for it above.
5704                userId = UserHandle.USER_CURRENT;
5705            }
5706            try {
5707                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5708                    int uid = AppGlobals.getPackageManager()
5709                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5710                    if (!UserHandle.isSameApp(callingUid, uid)) {
5711                        String msg = "Permission Denial: getIntentSender() from pid="
5712                            + Binder.getCallingPid()
5713                            + ", uid=" + Binder.getCallingUid()
5714                            + ", (need uid=" + uid + ")"
5715                            + " is not allowed to send as package " + packageName;
5716                        Slog.w(TAG, msg);
5717                        throw new SecurityException(msg);
5718                    }
5719                }
5720
5721                return getIntentSenderLocked(type, packageName, callingUid, userId,
5722                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5723
5724            } catch (RemoteException e) {
5725                throw new SecurityException(e);
5726            }
5727        }
5728    }
5729
5730    IIntentSender getIntentSenderLocked(int type, String packageName,
5731            int callingUid, int userId, IBinder token, String resultWho,
5732            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5733            Bundle options) {
5734        if (DEBUG_MU)
5735            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5736        ActivityRecord activity = null;
5737        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5738            activity = ActivityRecord.isInStackLocked(token);
5739            if (activity == null) {
5740                return null;
5741            }
5742            if (activity.finishing) {
5743                return null;
5744            }
5745        }
5746
5747        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5748        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5749        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5750        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5751                |PendingIntent.FLAG_UPDATE_CURRENT);
5752
5753        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5754                type, packageName, activity, resultWho,
5755                requestCode, intents, resolvedTypes, flags, options, userId);
5756        WeakReference<PendingIntentRecord> ref;
5757        ref = mIntentSenderRecords.get(key);
5758        PendingIntentRecord rec = ref != null ? ref.get() : null;
5759        if (rec != null) {
5760            if (!cancelCurrent) {
5761                if (updateCurrent) {
5762                    if (rec.key.requestIntent != null) {
5763                        rec.key.requestIntent.replaceExtras(intents != null ?
5764                                intents[intents.length - 1] : null);
5765                    }
5766                    if (intents != null) {
5767                        intents[intents.length-1] = rec.key.requestIntent;
5768                        rec.key.allIntents = intents;
5769                        rec.key.allResolvedTypes = resolvedTypes;
5770                    } else {
5771                        rec.key.allIntents = null;
5772                        rec.key.allResolvedTypes = null;
5773                    }
5774                }
5775                return rec;
5776            }
5777            rec.canceled = true;
5778            mIntentSenderRecords.remove(key);
5779        }
5780        if (noCreate) {
5781            return rec;
5782        }
5783        rec = new PendingIntentRecord(this, key, callingUid);
5784        mIntentSenderRecords.put(key, rec.ref);
5785        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5786            if (activity.pendingResults == null) {
5787                activity.pendingResults
5788                        = new HashSet<WeakReference<PendingIntentRecord>>();
5789            }
5790            activity.pendingResults.add(rec.ref);
5791        }
5792        return rec;
5793    }
5794
5795    @Override
5796    public void cancelIntentSender(IIntentSender sender) {
5797        if (!(sender instanceof PendingIntentRecord)) {
5798            return;
5799        }
5800        synchronized(this) {
5801            PendingIntentRecord rec = (PendingIntentRecord)sender;
5802            try {
5803                int uid = AppGlobals.getPackageManager()
5804                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5805                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5806                    String msg = "Permission Denial: cancelIntentSender() from pid="
5807                        + Binder.getCallingPid()
5808                        + ", uid=" + Binder.getCallingUid()
5809                        + " is not allowed to cancel packges "
5810                        + rec.key.packageName;
5811                    Slog.w(TAG, msg);
5812                    throw new SecurityException(msg);
5813                }
5814            } catch (RemoteException e) {
5815                throw new SecurityException(e);
5816            }
5817            cancelIntentSenderLocked(rec, true);
5818        }
5819    }
5820
5821    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5822        rec.canceled = true;
5823        mIntentSenderRecords.remove(rec.key);
5824        if (cleanActivity && rec.key.activity != null) {
5825            rec.key.activity.pendingResults.remove(rec.ref);
5826        }
5827    }
5828
5829    @Override
5830    public String getPackageForIntentSender(IIntentSender pendingResult) {
5831        if (!(pendingResult instanceof PendingIntentRecord)) {
5832            return null;
5833        }
5834        try {
5835            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5836            return res.key.packageName;
5837        } catch (ClassCastException e) {
5838        }
5839        return null;
5840    }
5841
5842    @Override
5843    public int getUidForIntentSender(IIntentSender sender) {
5844        if (sender instanceof PendingIntentRecord) {
5845            try {
5846                PendingIntentRecord res = (PendingIntentRecord)sender;
5847                return res.uid;
5848            } catch (ClassCastException e) {
5849            }
5850        }
5851        return -1;
5852    }
5853
5854    @Override
5855    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5856        if (!(pendingResult instanceof PendingIntentRecord)) {
5857            return false;
5858        }
5859        try {
5860            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5861            if (res.key.allIntents == null) {
5862                return false;
5863            }
5864            for (int i=0; i<res.key.allIntents.length; i++) {
5865                Intent intent = res.key.allIntents[i];
5866                if (intent.getPackage() != null && intent.getComponent() != null) {
5867                    return false;
5868                }
5869            }
5870            return true;
5871        } catch (ClassCastException e) {
5872        }
5873        return false;
5874    }
5875
5876    @Override
5877    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5878        if (!(pendingResult instanceof PendingIntentRecord)) {
5879            return false;
5880        }
5881        try {
5882            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5883            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5884                return true;
5885            }
5886            return false;
5887        } catch (ClassCastException e) {
5888        }
5889        return false;
5890    }
5891
5892    @Override
5893    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5894        if (!(pendingResult instanceof PendingIntentRecord)) {
5895            return null;
5896        }
5897        try {
5898            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5899            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5900        } catch (ClassCastException e) {
5901        }
5902        return null;
5903    }
5904
5905    @Override
5906    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5907        if (!(pendingResult instanceof PendingIntentRecord)) {
5908            return null;
5909        }
5910        try {
5911            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5912            Intent intent = res.key.requestIntent;
5913            if (intent != null) {
5914                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5915                        || res.lastTagPrefix.equals(prefix))) {
5916                    return res.lastTag;
5917                }
5918                res.lastTagPrefix = prefix;
5919                StringBuilder sb = new StringBuilder(128);
5920                if (prefix != null) {
5921                    sb.append(prefix);
5922                }
5923                if (intent.getAction() != null) {
5924                    sb.append(intent.getAction());
5925                } else if (intent.getComponent() != null) {
5926                    intent.getComponent().appendShortString(sb);
5927                } else {
5928                    sb.append("?");
5929                }
5930                return res.lastTag = sb.toString();
5931            }
5932        } catch (ClassCastException e) {
5933        }
5934        return null;
5935    }
5936
5937    @Override
5938    public void setProcessLimit(int max) {
5939        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5940                "setProcessLimit()");
5941        synchronized (this) {
5942            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5943            mProcessLimitOverride = max;
5944        }
5945        trimApplications();
5946    }
5947
5948    @Override
5949    public int getProcessLimit() {
5950        synchronized (this) {
5951            return mProcessLimitOverride;
5952        }
5953    }
5954
5955    void foregroundTokenDied(ForegroundToken token) {
5956        synchronized (ActivityManagerService.this) {
5957            synchronized (mPidsSelfLocked) {
5958                ForegroundToken cur
5959                    = mForegroundProcesses.get(token.pid);
5960                if (cur != token) {
5961                    return;
5962                }
5963                mForegroundProcesses.remove(token.pid);
5964                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5965                if (pr == null) {
5966                    return;
5967                }
5968                pr.forcingToForeground = null;
5969                updateProcessForegroundLocked(pr, false, false);
5970            }
5971            updateOomAdjLocked();
5972        }
5973    }
5974
5975    @Override
5976    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5977        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5978                "setProcessForeground()");
5979        synchronized(this) {
5980            boolean changed = false;
5981
5982            synchronized (mPidsSelfLocked) {
5983                ProcessRecord pr = mPidsSelfLocked.get(pid);
5984                if (pr == null && isForeground) {
5985                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5986                    return;
5987                }
5988                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5989                if (oldToken != null) {
5990                    oldToken.token.unlinkToDeath(oldToken, 0);
5991                    mForegroundProcesses.remove(pid);
5992                    if (pr != null) {
5993                        pr.forcingToForeground = null;
5994                    }
5995                    changed = true;
5996                }
5997                if (isForeground && token != null) {
5998                    ForegroundToken newToken = new ForegroundToken() {
5999                        @Override
6000                        public void binderDied() {
6001                            foregroundTokenDied(this);
6002                        }
6003                    };
6004                    newToken.pid = pid;
6005                    newToken.token = token;
6006                    try {
6007                        token.linkToDeath(newToken, 0);
6008                        mForegroundProcesses.put(pid, newToken);
6009                        pr.forcingToForeground = token;
6010                        changed = true;
6011                    } catch (RemoteException e) {
6012                        // If the process died while doing this, we will later
6013                        // do the cleanup with the process death link.
6014                    }
6015                }
6016            }
6017
6018            if (changed) {
6019                updateOomAdjLocked();
6020            }
6021        }
6022    }
6023
6024    // =========================================================
6025    // PERMISSIONS
6026    // =========================================================
6027
6028    static class PermissionController extends IPermissionController.Stub {
6029        ActivityManagerService mActivityManagerService;
6030        PermissionController(ActivityManagerService activityManagerService) {
6031            mActivityManagerService = activityManagerService;
6032        }
6033
6034        @Override
6035        public boolean checkPermission(String permission, int pid, int uid) {
6036            return mActivityManagerService.checkPermission(permission, pid,
6037                    uid) == PackageManager.PERMISSION_GRANTED;
6038        }
6039    }
6040
6041    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6042        @Override
6043        public int checkComponentPermission(String permission, int pid, int uid,
6044                int owningUid, boolean exported) {
6045            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6046                    owningUid, exported);
6047        }
6048
6049        @Override
6050        public Object getAMSLock() {
6051            return ActivityManagerService.this;
6052        }
6053    }
6054
6055    /**
6056     * This can be called with or without the global lock held.
6057     */
6058    int checkComponentPermission(String permission, int pid, int uid,
6059            int owningUid, boolean exported) {
6060        // We might be performing an operation on behalf of an indirect binder
6061        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6062        // client identity accordingly before proceeding.
6063        Identity tlsIdentity = sCallerIdentity.get();
6064        if (tlsIdentity != null) {
6065            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6066                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6067            uid = tlsIdentity.uid;
6068            pid = tlsIdentity.pid;
6069        }
6070
6071        if (pid == MY_PID) {
6072            return PackageManager.PERMISSION_GRANTED;
6073        }
6074
6075        return ActivityManager.checkComponentPermission(permission, uid,
6076                owningUid, exported);
6077    }
6078
6079    /**
6080     * As the only public entry point for permissions checking, this method
6081     * can enforce the semantic that requesting a check on a null global
6082     * permission is automatically denied.  (Internally a null permission
6083     * string is used when calling {@link #checkComponentPermission} in cases
6084     * when only uid-based security is needed.)
6085     *
6086     * This can be called with or without the global lock held.
6087     */
6088    @Override
6089    public int checkPermission(String permission, int pid, int uid) {
6090        if (permission == null) {
6091            return PackageManager.PERMISSION_DENIED;
6092        }
6093        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6094    }
6095
6096    /**
6097     * Binder IPC calls go through the public entry point.
6098     * This can be called with or without the global lock held.
6099     */
6100    int checkCallingPermission(String permission) {
6101        return checkPermission(permission,
6102                Binder.getCallingPid(),
6103                UserHandle.getAppId(Binder.getCallingUid()));
6104    }
6105
6106    /**
6107     * This can be called with or without the global lock held.
6108     */
6109    void enforceCallingPermission(String permission, String func) {
6110        if (checkCallingPermission(permission)
6111                == PackageManager.PERMISSION_GRANTED) {
6112            return;
6113        }
6114
6115        String msg = "Permission Denial: " + func + " from pid="
6116                + Binder.getCallingPid()
6117                + ", uid=" + Binder.getCallingUid()
6118                + " requires " + permission;
6119        Slog.w(TAG, msg);
6120        throw new SecurityException(msg);
6121    }
6122
6123    /**
6124     * Determine if UID is holding permissions required to access {@link Uri} in
6125     * the given {@link ProviderInfo}. Final permission checking is always done
6126     * in {@link ContentProvider}.
6127     */
6128    private final boolean checkHoldingPermissionsLocked(
6129            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6130        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6131                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6132        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6133            return false;
6134        }
6135        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6136    }
6137
6138    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6139            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6140        if (pi.applicationInfo.uid == uid) {
6141            return true;
6142        } else if (!pi.exported) {
6143            return false;
6144        }
6145
6146        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6147        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6148        try {
6149            // check if target holds top-level <provider> permissions
6150            if (!readMet && pi.readPermission != null && considerUidPermissions
6151                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6152                readMet = true;
6153            }
6154            if (!writeMet && pi.writePermission != null && considerUidPermissions
6155                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6156                writeMet = true;
6157            }
6158
6159            // track if unprotected read/write is allowed; any denied
6160            // <path-permission> below removes this ability
6161            boolean allowDefaultRead = pi.readPermission == null;
6162            boolean allowDefaultWrite = pi.writePermission == null;
6163
6164            // check if target holds any <path-permission> that match uri
6165            final PathPermission[] pps = pi.pathPermissions;
6166            if (pps != null) {
6167                final String path = grantUri.uri.getPath();
6168                int i = pps.length;
6169                while (i > 0 && (!readMet || !writeMet)) {
6170                    i--;
6171                    PathPermission pp = pps[i];
6172                    if (pp.match(path)) {
6173                        if (!readMet) {
6174                            final String pprperm = pp.getReadPermission();
6175                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6176                                    + pprperm + " for " + pp.getPath()
6177                                    + ": match=" + pp.match(path)
6178                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6179                            if (pprperm != null) {
6180                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6181                                        == PERMISSION_GRANTED) {
6182                                    readMet = true;
6183                                } else {
6184                                    allowDefaultRead = false;
6185                                }
6186                            }
6187                        }
6188                        if (!writeMet) {
6189                            final String ppwperm = pp.getWritePermission();
6190                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6191                                    + ppwperm + " for " + pp.getPath()
6192                                    + ": match=" + pp.match(path)
6193                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6194                            if (ppwperm != null) {
6195                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6196                                        == PERMISSION_GRANTED) {
6197                                    writeMet = true;
6198                                } else {
6199                                    allowDefaultWrite = false;
6200                                }
6201                            }
6202                        }
6203                    }
6204                }
6205            }
6206
6207            // grant unprotected <provider> read/write, if not blocked by
6208            // <path-permission> above
6209            if (allowDefaultRead) readMet = true;
6210            if (allowDefaultWrite) writeMet = true;
6211
6212        } catch (RemoteException e) {
6213            return false;
6214        }
6215
6216        return readMet && writeMet;
6217    }
6218
6219    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6220        ProviderInfo pi = null;
6221        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6222        if (cpr != null) {
6223            pi = cpr.info;
6224        } else {
6225            try {
6226                pi = AppGlobals.getPackageManager().resolveContentProvider(
6227                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6228            } catch (RemoteException ex) {
6229            }
6230        }
6231        return pi;
6232    }
6233
6234    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6235        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6236        if (targetUris != null) {
6237            return targetUris.get(grantUri);
6238        }
6239        return null;
6240    }
6241
6242    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6243            String targetPkg, int targetUid, GrantUri grantUri) {
6244        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6245        if (targetUris == null) {
6246            targetUris = Maps.newArrayMap();
6247            mGrantedUriPermissions.put(targetUid, targetUris);
6248        }
6249
6250        UriPermission perm = targetUris.get(grantUri);
6251        if (perm == null) {
6252            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6253            targetUris.put(grantUri, perm);
6254        }
6255
6256        return perm;
6257    }
6258
6259    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6260            final int modeFlags) {
6261        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6262        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6263                : UriPermission.STRENGTH_OWNED;
6264
6265        // Root gets to do everything.
6266        if (uid == 0) {
6267            return true;
6268        }
6269
6270        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6271        if (perms == null) return false;
6272
6273        // First look for exact match
6274        final UriPermission exactPerm = perms.get(grantUri);
6275        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6276            return true;
6277        }
6278
6279        // No exact match, look for prefixes
6280        final int N = perms.size();
6281        for (int i = 0; i < N; i++) {
6282            final UriPermission perm = perms.valueAt(i);
6283            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6284                    && perm.getStrength(modeFlags) >= minStrength) {
6285                return true;
6286            }
6287        }
6288
6289        return false;
6290    }
6291
6292    @Override
6293    public int checkUriPermission(Uri uri, int pid, int uid,
6294            final int modeFlags, int userId) {
6295        enforceNotIsolatedCaller("checkUriPermission");
6296
6297        // Another redirected-binder-call permissions check as in
6298        // {@link checkComponentPermission}.
6299        Identity tlsIdentity = sCallerIdentity.get();
6300        if (tlsIdentity != null) {
6301            uid = tlsIdentity.uid;
6302            pid = tlsIdentity.pid;
6303        }
6304
6305        // Our own process gets to do everything.
6306        if (pid == MY_PID) {
6307            return PackageManager.PERMISSION_GRANTED;
6308        }
6309        synchronized (this) {
6310            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6311                    ? PackageManager.PERMISSION_GRANTED
6312                    : PackageManager.PERMISSION_DENIED;
6313        }
6314    }
6315
6316    /**
6317     * Check if the targetPkg can be granted permission to access uri by
6318     * the callingUid using the given modeFlags.  Throws a security exception
6319     * if callingUid is not allowed to do this.  Returns the uid of the target
6320     * if the URI permission grant should be performed; returns -1 if it is not
6321     * needed (for example targetPkg already has permission to access the URI).
6322     * If you already know the uid of the target, you can supply it in
6323     * lastTargetUid else set that to -1.
6324     */
6325    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6326            final int modeFlags, int lastTargetUid) {
6327        if (!Intent.isAccessUriMode(modeFlags)) {
6328            return -1;
6329        }
6330
6331        if (targetPkg != null) {
6332            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6333                    "Checking grant " + targetPkg + " permission to " + grantUri);
6334        }
6335
6336        final IPackageManager pm = AppGlobals.getPackageManager();
6337
6338        // If this is not a content: uri, we can't do anything with it.
6339        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6340            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6341                    "Can't grant URI permission for non-content URI: " + grantUri);
6342            return -1;
6343        }
6344
6345        final String authority = grantUri.uri.getAuthority();
6346        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6347        if (pi == null) {
6348            Slog.w(TAG, "No content provider found for permission check: " +
6349                    grantUri.uri.toSafeString());
6350            return -1;
6351        }
6352
6353        int targetUid = lastTargetUid;
6354        if (targetUid < 0 && targetPkg != null) {
6355            try {
6356                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6357                if (targetUid < 0) {
6358                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6359                            "Can't grant URI permission no uid for: " + targetPkg);
6360                    return -1;
6361                }
6362            } catch (RemoteException ex) {
6363                return -1;
6364            }
6365        }
6366
6367        if (targetUid >= 0) {
6368            // First...  does the target actually need this permission?
6369            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6370                // No need to grant the target this permission.
6371                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6372                        "Target " + targetPkg + " already has full permission to " + grantUri);
6373                return -1;
6374            }
6375        } else {
6376            // First...  there is no target package, so can anyone access it?
6377            boolean allowed = pi.exported;
6378            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6379                if (pi.readPermission != null) {
6380                    allowed = false;
6381                }
6382            }
6383            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6384                if (pi.writePermission != null) {
6385                    allowed = false;
6386                }
6387            }
6388            if (allowed) {
6389                return -1;
6390            }
6391        }
6392
6393        /* There is a special cross user grant if:
6394         * - The target is on another user.
6395         * - Apps on the current user can access the uri without any uid permissions.
6396         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6397         * grant uri permissions.
6398         */
6399        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6400                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6401                modeFlags, false /*without considering the uid permissions*/);
6402
6403        // Second...  is the provider allowing granting of URI permissions?
6404        if (!specialCrossUserGrant) {
6405            if (!pi.grantUriPermissions) {
6406                throw new SecurityException("Provider " + pi.packageName
6407                        + "/" + pi.name
6408                        + " does not allow granting of Uri permissions (uri "
6409                        + grantUri + ")");
6410            }
6411            if (pi.uriPermissionPatterns != null) {
6412                final int N = pi.uriPermissionPatterns.length;
6413                boolean allowed = false;
6414                for (int i=0; i<N; i++) {
6415                    if (pi.uriPermissionPatterns[i] != null
6416                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6417                        allowed = true;
6418                        break;
6419                    }
6420                }
6421                if (!allowed) {
6422                    throw new SecurityException("Provider " + pi.packageName
6423                            + "/" + pi.name
6424                            + " does not allow granting of permission to path of Uri "
6425                            + grantUri);
6426                }
6427            }
6428        }
6429
6430        // Third...  does the caller itself have permission to access
6431        // this uri?
6432        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6433            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6434                // Require they hold a strong enough Uri permission
6435                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6436                    throw new SecurityException("Uid " + callingUid
6437                            + " does not have permission to uri " + grantUri);
6438                }
6439            }
6440        }
6441        return targetUid;
6442    }
6443
6444    @Override
6445    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6446            final int modeFlags, int userId) {
6447        enforceNotIsolatedCaller("checkGrantUriPermission");
6448        synchronized(this) {
6449            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6450                    new GrantUri(userId, uri, false), modeFlags, -1);
6451        }
6452    }
6453
6454    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6455            final int modeFlags, UriPermissionOwner owner) {
6456        if (!Intent.isAccessUriMode(modeFlags)) {
6457            return;
6458        }
6459
6460        // So here we are: the caller has the assumed permission
6461        // to the uri, and the target doesn't.  Let's now give this to
6462        // the target.
6463
6464        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6465                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6466
6467        final String authority = grantUri.uri.getAuthority();
6468        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6469        if (pi == null) {
6470            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6471            return;
6472        }
6473
6474        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6475            grantUri.prefix = true;
6476        }
6477        final UriPermission perm = findOrCreateUriPermissionLocked(
6478                pi.packageName, targetPkg, targetUid, grantUri);
6479        perm.grantModes(modeFlags, owner);
6480    }
6481
6482    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6483            final int modeFlags, UriPermissionOwner owner) {
6484        if (targetPkg == null) {
6485            throw new NullPointerException("targetPkg");
6486        }
6487
6488        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6489                -1);
6490        if (targetUid < 0) {
6491            return;
6492        }
6493
6494        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6495                owner);
6496    }
6497
6498    static class NeededUriGrants extends ArrayList<GrantUri> {
6499        final String targetPkg;
6500        final int targetUid;
6501        final int flags;
6502
6503        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6504            this.targetPkg = targetPkg;
6505            this.targetUid = targetUid;
6506            this.flags = flags;
6507        }
6508    }
6509
6510    /**
6511     * Like checkGrantUriPermissionLocked, but takes an Intent.
6512     */
6513    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6514            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6515        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6516                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6517                + " clip=" + (intent != null ? intent.getClipData() : null)
6518                + " from " + intent + "; flags=0x"
6519                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6520
6521        if (targetPkg == null) {
6522            throw new NullPointerException("targetPkg");
6523        }
6524
6525        if (intent == null) {
6526            return null;
6527        }
6528        Uri data = intent.getData();
6529        ClipData clip = intent.getClipData();
6530        if (data == null && clip == null) {
6531            return null;
6532        }
6533        final IPackageManager pm = AppGlobals.getPackageManager();
6534        int targetUid;
6535        if (needed != null) {
6536            targetUid = needed.targetUid;
6537        } else {
6538            try {
6539                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6540            } catch (RemoteException ex) {
6541                return null;
6542            }
6543            if (targetUid < 0) {
6544                if (DEBUG_URI_PERMISSION) {
6545                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6546                            + " on user " + targetUserId);
6547                }
6548                return null;
6549            }
6550        }
6551        if (data != null) {
6552            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6553            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6554                    targetUid);
6555            if (targetUid > 0) {
6556                if (needed == null) {
6557                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6558                }
6559                needed.add(grantUri);
6560            }
6561        }
6562        if (clip != null) {
6563            for (int i=0; i<clip.getItemCount(); i++) {
6564                Uri uri = clip.getItemAt(i).getUri();
6565                if (uri != null) {
6566                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6567                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6568                            targetUid);
6569                    if (targetUid > 0) {
6570                        if (needed == null) {
6571                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6572                        }
6573                        needed.add(grantUri);
6574                    }
6575                } else {
6576                    Intent clipIntent = clip.getItemAt(i).getIntent();
6577                    if (clipIntent != null) {
6578                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6579                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6580                        if (newNeeded != null) {
6581                            needed = newNeeded;
6582                        }
6583                    }
6584                }
6585            }
6586        }
6587
6588        return needed;
6589    }
6590
6591    /**
6592     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6593     */
6594    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6595            UriPermissionOwner owner) {
6596        if (needed != null) {
6597            for (int i=0; i<needed.size(); i++) {
6598                GrantUri grantUri = needed.get(i);
6599                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6600                        grantUri, needed.flags, owner);
6601            }
6602        }
6603    }
6604
6605    void grantUriPermissionFromIntentLocked(int callingUid,
6606            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6607        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6608                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6609        if (needed == null) {
6610            return;
6611        }
6612
6613        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6614    }
6615
6616    @Override
6617    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6618            final int modeFlags, int userId) {
6619        enforceNotIsolatedCaller("grantUriPermission");
6620        GrantUri grantUri = new GrantUri(userId, uri, false);
6621        synchronized(this) {
6622            final ProcessRecord r = getRecordForAppLocked(caller);
6623            if (r == null) {
6624                throw new SecurityException("Unable to find app for caller "
6625                        + caller
6626                        + " when granting permission to uri " + grantUri);
6627            }
6628            if (targetPkg == null) {
6629                throw new IllegalArgumentException("null target");
6630            }
6631            if (grantUri == null) {
6632                throw new IllegalArgumentException("null uri");
6633            }
6634
6635            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6636                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6637                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6638                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6639
6640            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6641        }
6642    }
6643
6644    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6645        if (perm.modeFlags == 0) {
6646            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6647                    perm.targetUid);
6648            if (perms != null) {
6649                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6650                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6651
6652                perms.remove(perm.uri);
6653                if (perms.isEmpty()) {
6654                    mGrantedUriPermissions.remove(perm.targetUid);
6655                }
6656            }
6657        }
6658    }
6659
6660    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6661        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6662
6663        final IPackageManager pm = AppGlobals.getPackageManager();
6664        final String authority = grantUri.uri.getAuthority();
6665        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6666        if (pi == null) {
6667            Slog.w(TAG, "No content provider found for permission revoke: "
6668                    + grantUri.toSafeString());
6669            return;
6670        }
6671
6672        // Does the caller have this permission on the URI?
6673        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6674            // Right now, if you are not the original owner of the permission,
6675            // you are not allowed to revoke it.
6676            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6677                throw new SecurityException("Uid " + callingUid
6678                        + " does not have permission to uri " + grantUri);
6679            //}
6680        }
6681
6682        boolean persistChanged = false;
6683
6684        // Go through all of the permissions and remove any that match.
6685        int N = mGrantedUriPermissions.size();
6686        for (int i = 0; i < N; i++) {
6687            final int targetUid = mGrantedUriPermissions.keyAt(i);
6688            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6689
6690            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6691                final UriPermission perm = it.next();
6692                if (perm.uri.sourceUserId == grantUri.sourceUserId
6693                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6694                    if (DEBUG_URI_PERMISSION)
6695                        Slog.v(TAG,
6696                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6697                    persistChanged |= perm.revokeModes(
6698                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6699                    if (perm.modeFlags == 0) {
6700                        it.remove();
6701                    }
6702                }
6703            }
6704
6705            if (perms.isEmpty()) {
6706                mGrantedUriPermissions.remove(targetUid);
6707                N--;
6708                i--;
6709            }
6710        }
6711
6712        if (persistChanged) {
6713            schedulePersistUriGrants();
6714        }
6715    }
6716
6717    @Override
6718    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6719            int userId) {
6720        enforceNotIsolatedCaller("revokeUriPermission");
6721        synchronized(this) {
6722            final ProcessRecord r = getRecordForAppLocked(caller);
6723            if (r == null) {
6724                throw new SecurityException("Unable to find app for caller "
6725                        + caller
6726                        + " when revoking permission to uri " + uri);
6727            }
6728            if (uri == null) {
6729                Slog.w(TAG, "revokeUriPermission: null uri");
6730                return;
6731            }
6732
6733            if (!Intent.isAccessUriMode(modeFlags)) {
6734                return;
6735            }
6736
6737            final IPackageManager pm = AppGlobals.getPackageManager();
6738            final String authority = uri.getAuthority();
6739            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6740            if (pi == null) {
6741                Slog.w(TAG, "No content provider found for permission revoke: "
6742                        + uri.toSafeString());
6743                return;
6744            }
6745
6746            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6747        }
6748    }
6749
6750    /**
6751     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6752     * given package.
6753     *
6754     * @param packageName Package name to match, or {@code null} to apply to all
6755     *            packages.
6756     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6757     *            to all users.
6758     * @param persistable If persistable grants should be removed.
6759     */
6760    private void removeUriPermissionsForPackageLocked(
6761            String packageName, int userHandle, boolean persistable) {
6762        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6763            throw new IllegalArgumentException("Must narrow by either package or user");
6764        }
6765
6766        boolean persistChanged = false;
6767
6768        int N = mGrantedUriPermissions.size();
6769        for (int i = 0; i < N; i++) {
6770            final int targetUid = mGrantedUriPermissions.keyAt(i);
6771            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6772
6773            // Only inspect grants matching user
6774            if (userHandle == UserHandle.USER_ALL
6775                    || userHandle == UserHandle.getUserId(targetUid)) {
6776                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6777                    final UriPermission perm = it.next();
6778
6779                    // Only inspect grants matching package
6780                    if (packageName == null || perm.sourcePkg.equals(packageName)
6781                            || perm.targetPkg.equals(packageName)) {
6782                        persistChanged |= perm.revokeModes(
6783                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6784
6785                        // Only remove when no modes remain; any persisted grants
6786                        // will keep this alive.
6787                        if (perm.modeFlags == 0) {
6788                            it.remove();
6789                        }
6790                    }
6791                }
6792
6793                if (perms.isEmpty()) {
6794                    mGrantedUriPermissions.remove(targetUid);
6795                    N--;
6796                    i--;
6797                }
6798            }
6799        }
6800
6801        if (persistChanged) {
6802            schedulePersistUriGrants();
6803        }
6804    }
6805
6806    @Override
6807    public IBinder newUriPermissionOwner(String name) {
6808        enforceNotIsolatedCaller("newUriPermissionOwner");
6809        synchronized(this) {
6810            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6811            return owner.getExternalTokenLocked();
6812        }
6813    }
6814
6815    @Override
6816    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6817            final int modeFlags, int userId) {
6818        synchronized(this) {
6819            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6820            if (owner == null) {
6821                throw new IllegalArgumentException("Unknown owner: " + token);
6822            }
6823            if (fromUid != Binder.getCallingUid()) {
6824                if (Binder.getCallingUid() != Process.myUid()) {
6825                    // Only system code can grant URI permissions on behalf
6826                    // of other users.
6827                    throw new SecurityException("nice try");
6828                }
6829            }
6830            if (targetPkg == null) {
6831                throw new IllegalArgumentException("null target");
6832            }
6833            if (uri == null) {
6834                throw new IllegalArgumentException("null uri");
6835            }
6836
6837            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6838                    modeFlags, owner);
6839        }
6840    }
6841
6842    @Override
6843    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6844        synchronized(this) {
6845            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6846            if (owner == null) {
6847                throw new IllegalArgumentException("Unknown owner: " + token);
6848            }
6849
6850            if (uri == null) {
6851                owner.removeUriPermissionsLocked(mode);
6852            } else {
6853                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6854            }
6855        }
6856    }
6857
6858    private void schedulePersistUriGrants() {
6859        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6860            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6861                    10 * DateUtils.SECOND_IN_MILLIS);
6862        }
6863    }
6864
6865    private void writeGrantedUriPermissions() {
6866        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6867
6868        // Snapshot permissions so we can persist without lock
6869        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6870        synchronized (this) {
6871            final int size = mGrantedUriPermissions.size();
6872            for (int i = 0; i < size; i++) {
6873                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6874                for (UriPermission perm : perms.values()) {
6875                    if (perm.persistedModeFlags != 0) {
6876                        persist.add(perm.snapshot());
6877                    }
6878                }
6879            }
6880        }
6881
6882        FileOutputStream fos = null;
6883        try {
6884            fos = mGrantFile.startWrite();
6885
6886            XmlSerializer out = new FastXmlSerializer();
6887            out.setOutput(fos, "utf-8");
6888            out.startDocument(null, true);
6889            out.startTag(null, TAG_URI_GRANTS);
6890            for (UriPermission.Snapshot perm : persist) {
6891                out.startTag(null, TAG_URI_GRANT);
6892                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6893                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6894                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6895                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6896                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6897                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6898                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6899                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6900                out.endTag(null, TAG_URI_GRANT);
6901            }
6902            out.endTag(null, TAG_URI_GRANTS);
6903            out.endDocument();
6904
6905            mGrantFile.finishWrite(fos);
6906        } catch (IOException e) {
6907            if (fos != null) {
6908                mGrantFile.failWrite(fos);
6909            }
6910        }
6911    }
6912
6913    private void readGrantedUriPermissionsLocked() {
6914        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6915
6916        final long now = System.currentTimeMillis();
6917
6918        FileInputStream fis = null;
6919        try {
6920            fis = mGrantFile.openRead();
6921            final XmlPullParser in = Xml.newPullParser();
6922            in.setInput(fis, null);
6923
6924            int type;
6925            while ((type = in.next()) != END_DOCUMENT) {
6926                final String tag = in.getName();
6927                if (type == START_TAG) {
6928                    if (TAG_URI_GRANT.equals(tag)) {
6929                        final int sourceUserId;
6930                        final int targetUserId;
6931                        final int userHandle = readIntAttribute(in,
6932                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6933                        if (userHandle != UserHandle.USER_NULL) {
6934                            // For backwards compatibility.
6935                            sourceUserId = userHandle;
6936                            targetUserId = userHandle;
6937                        } else {
6938                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6939                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6940                        }
6941                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6942                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6943                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6944                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6945                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6946                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6947
6948                        // Sanity check that provider still belongs to source package
6949                        final ProviderInfo pi = getProviderInfoLocked(
6950                                uri.getAuthority(), sourceUserId);
6951                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6952                            int targetUid = -1;
6953                            try {
6954                                targetUid = AppGlobals.getPackageManager()
6955                                        .getPackageUid(targetPkg, targetUserId);
6956                            } catch (RemoteException e) {
6957                            }
6958                            if (targetUid != -1) {
6959                                final UriPermission perm = findOrCreateUriPermissionLocked(
6960                                        sourcePkg, targetPkg, targetUid,
6961                                        new GrantUri(sourceUserId, uri, prefix));
6962                                perm.initPersistedModes(modeFlags, createdTime);
6963                            }
6964                        } else {
6965                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6966                                    + " but instead found " + pi);
6967                        }
6968                    }
6969                }
6970            }
6971        } catch (FileNotFoundException e) {
6972            // Missing grants is okay
6973        } catch (IOException e) {
6974            Log.wtf(TAG, "Failed reading Uri grants", e);
6975        } catch (XmlPullParserException e) {
6976            Log.wtf(TAG, "Failed reading Uri grants", e);
6977        } finally {
6978            IoUtils.closeQuietly(fis);
6979        }
6980    }
6981
6982    @Override
6983    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6984        enforceNotIsolatedCaller("takePersistableUriPermission");
6985
6986        Preconditions.checkFlagsArgument(modeFlags,
6987                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6988
6989        synchronized (this) {
6990            final int callingUid = Binder.getCallingUid();
6991            boolean persistChanged = false;
6992            GrantUri grantUri = new GrantUri(userId, uri, false);
6993
6994            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6995                    new GrantUri(userId, uri, false));
6996            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6997                    new GrantUri(userId, uri, true));
6998
6999            final boolean exactValid = (exactPerm != null)
7000                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7001            final boolean prefixValid = (prefixPerm != null)
7002                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7003
7004            if (!(exactValid || prefixValid)) {
7005                throw new SecurityException("No persistable permission grants found for UID "
7006                        + callingUid + " and Uri " + grantUri.toSafeString());
7007            }
7008
7009            if (exactValid) {
7010                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7011            }
7012            if (prefixValid) {
7013                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7014            }
7015
7016            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7017
7018            if (persistChanged) {
7019                schedulePersistUriGrants();
7020            }
7021        }
7022    }
7023
7024    @Override
7025    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7026        enforceNotIsolatedCaller("releasePersistableUriPermission");
7027
7028        Preconditions.checkFlagsArgument(modeFlags,
7029                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7030
7031        synchronized (this) {
7032            final int callingUid = Binder.getCallingUid();
7033            boolean persistChanged = false;
7034
7035            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7036                    new GrantUri(userId, uri, false));
7037            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7038                    new GrantUri(userId, uri, true));
7039            if (exactPerm == null && prefixPerm == null) {
7040                throw new SecurityException("No permission grants found for UID " + callingUid
7041                        + " and Uri " + uri.toSafeString());
7042            }
7043
7044            if (exactPerm != null) {
7045                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7046                removeUriPermissionIfNeededLocked(exactPerm);
7047            }
7048            if (prefixPerm != null) {
7049                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7050                removeUriPermissionIfNeededLocked(prefixPerm);
7051            }
7052
7053            if (persistChanged) {
7054                schedulePersistUriGrants();
7055            }
7056        }
7057    }
7058
7059    /**
7060     * Prune any older {@link UriPermission} for the given UID until outstanding
7061     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7062     *
7063     * @return if any mutations occured that require persisting.
7064     */
7065    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7066        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7067        if (perms == null) return false;
7068        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7069
7070        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7071        for (UriPermission perm : perms.values()) {
7072            if (perm.persistedModeFlags != 0) {
7073                persisted.add(perm);
7074            }
7075        }
7076
7077        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7078        if (trimCount <= 0) return false;
7079
7080        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7081        for (int i = 0; i < trimCount; i++) {
7082            final UriPermission perm = persisted.get(i);
7083
7084            if (DEBUG_URI_PERMISSION) {
7085                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7086            }
7087
7088            perm.releasePersistableModes(~0);
7089            removeUriPermissionIfNeededLocked(perm);
7090        }
7091
7092        return true;
7093    }
7094
7095    @Override
7096    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7097            String packageName, boolean incoming) {
7098        enforceNotIsolatedCaller("getPersistedUriPermissions");
7099        Preconditions.checkNotNull(packageName, "packageName");
7100
7101        final int callingUid = Binder.getCallingUid();
7102        final IPackageManager pm = AppGlobals.getPackageManager();
7103        try {
7104            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7105            if (packageUid != callingUid) {
7106                throw new SecurityException(
7107                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7108            }
7109        } catch (RemoteException e) {
7110            throw new SecurityException("Failed to verify package name ownership");
7111        }
7112
7113        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7114        synchronized (this) {
7115            if (incoming) {
7116                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7117                        callingUid);
7118                if (perms == null) {
7119                    Slog.w(TAG, "No permission grants found for " + packageName);
7120                } else {
7121                    for (UriPermission perm : perms.values()) {
7122                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7123                            result.add(perm.buildPersistedPublicApiObject());
7124                        }
7125                    }
7126                }
7127            } else {
7128                final int size = mGrantedUriPermissions.size();
7129                for (int i = 0; i < size; i++) {
7130                    final ArrayMap<GrantUri, UriPermission> perms =
7131                            mGrantedUriPermissions.valueAt(i);
7132                    for (UriPermission perm : perms.values()) {
7133                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7134                            result.add(perm.buildPersistedPublicApiObject());
7135                        }
7136                    }
7137                }
7138            }
7139        }
7140        return new ParceledListSlice<android.content.UriPermission>(result);
7141    }
7142
7143    @Override
7144    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7145        synchronized (this) {
7146            ProcessRecord app =
7147                who != null ? getRecordForAppLocked(who) : null;
7148            if (app == null) return;
7149
7150            Message msg = Message.obtain();
7151            msg.what = WAIT_FOR_DEBUGGER_MSG;
7152            msg.obj = app;
7153            msg.arg1 = waiting ? 1 : 0;
7154            mHandler.sendMessage(msg);
7155        }
7156    }
7157
7158    @Override
7159    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7160        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7161        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7162        outInfo.availMem = Process.getFreeMemory();
7163        outInfo.totalMem = Process.getTotalMemory();
7164        outInfo.threshold = homeAppMem;
7165        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7166        outInfo.hiddenAppThreshold = cachedAppMem;
7167        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7168                ProcessList.SERVICE_ADJ);
7169        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7170                ProcessList.VISIBLE_APP_ADJ);
7171        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7172                ProcessList.FOREGROUND_APP_ADJ);
7173    }
7174
7175    // =========================================================
7176    // TASK MANAGEMENT
7177    // =========================================================
7178
7179    @Override
7180    public List<IAppTask> getAppTasks() {
7181        final PackageManager pm = mContext.getPackageManager();
7182        int callingUid = Binder.getCallingUid();
7183        long ident = Binder.clearCallingIdentity();
7184
7185        // Compose the list of packages for this id to test against
7186        HashSet<String> packages = new HashSet<String>();
7187        String[] uidPackages = pm.getPackagesForUid(callingUid);
7188        for (int i = 0; i < uidPackages.length; i++) {
7189            packages.add(uidPackages[i]);
7190        }
7191
7192        synchronized(this) {
7193            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7194            try {
7195                if (localLOGV) Slog.v(TAG, "getAppTasks");
7196
7197                final int N = mRecentTasks.size();
7198                for (int i = 0; i < N; i++) {
7199                    TaskRecord tr = mRecentTasks.get(i);
7200                    // Skip tasks that are not created by the caller
7201                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7202                        ActivityManager.RecentTaskInfo taskInfo =
7203                                createRecentTaskInfoFromTaskRecord(tr);
7204                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7205                        list.add(taskImpl);
7206                    }
7207                }
7208            } finally {
7209                Binder.restoreCallingIdentity(ident);
7210            }
7211            return list;
7212        }
7213    }
7214
7215    @Override
7216    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7217        final int callingUid = Binder.getCallingUid();
7218        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7219
7220        synchronized(this) {
7221            if (localLOGV) Slog.v(
7222                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7223
7224            final boolean allowed = checkCallingPermission(
7225                    android.Manifest.permission.GET_TASKS)
7226                    == PackageManager.PERMISSION_GRANTED;
7227            if (!allowed) {
7228                Slog.w(TAG, "getTasks: caller " + callingUid
7229                        + " does not hold GET_TASKS; limiting output");
7230            }
7231
7232            // TODO: Improve with MRU list from all ActivityStacks.
7233            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7234        }
7235
7236        return list;
7237    }
7238
7239    TaskRecord getMostRecentTask() {
7240        return mRecentTasks.get(0);
7241    }
7242
7243    /**
7244     * Creates a new RecentTaskInfo from a TaskRecord.
7245     */
7246    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7247        // Update the task description to reflect any changes in the task stack
7248        tr.updateTaskDescription();
7249
7250        // Compose the recent task info
7251        ActivityManager.RecentTaskInfo rti
7252                = new ActivityManager.RecentTaskInfo();
7253        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7254        rti.persistentId = tr.taskId;
7255        rti.baseIntent = new Intent(tr.getBaseIntent());
7256        rti.origActivity = tr.origActivity;
7257        rti.description = tr.lastDescription;
7258        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7259        rti.userId = tr.userId;
7260        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7261        rti.lastActiveTime = tr.lastActiveTime;
7262        return rti;
7263    }
7264
7265    @Override
7266    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7267            int flags, int userId) {
7268        final int callingUid = Binder.getCallingUid();
7269        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7270                false, true, "getRecentTasks", null);
7271
7272        synchronized (this) {
7273            final boolean allowed = checkCallingPermission(
7274                    android.Manifest.permission.GET_TASKS)
7275                    == PackageManager.PERMISSION_GRANTED;
7276            if (!allowed) {
7277                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7278                        + " does not hold GET_TASKS; limiting output");
7279            }
7280            final boolean detailed = checkCallingPermission(
7281                    android.Manifest.permission.GET_DETAILED_TASKS)
7282                    == PackageManager.PERMISSION_GRANTED;
7283
7284            IPackageManager pm = AppGlobals.getPackageManager();
7285
7286            final int N = mRecentTasks.size();
7287            ArrayList<ActivityManager.RecentTaskInfo> res
7288                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7289                            maxNum < N ? maxNum : N);
7290
7291            final Set<Integer> includedUsers;
7292            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7293                includedUsers = getProfileIdsLocked(userId);
7294            } else {
7295                includedUsers = new HashSet<Integer>();
7296            }
7297            includedUsers.add(Integer.valueOf(userId));
7298            for (int i=0; i<N && maxNum > 0; i++) {
7299                TaskRecord tr = mRecentTasks.get(i);
7300                // Only add calling user or related users recent tasks
7301                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7302
7303                // Return the entry if desired by the caller.  We always return
7304                // the first entry, because callers always expect this to be the
7305                // foreground app.  We may filter others if the caller has
7306                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7307                // we should exclude the entry.
7308
7309                if (i == 0
7310                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7311                        || (tr.intent == null)
7312                        || ((tr.intent.getFlags()
7313                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7314                    if (!allowed) {
7315                        // If the caller doesn't have the GET_TASKS permission, then only
7316                        // allow them to see a small subset of tasks -- their own and home.
7317                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7318                            continue;
7319                        }
7320                    }
7321                    if (tr.intent != null &&
7322                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7323                            != 0 && tr.getTopActivity() == null) {
7324                        // Don't include auto remove tasks that are finished or finishing.
7325                        continue;
7326                    }
7327
7328                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7329                    if (!detailed) {
7330                        rti.baseIntent.replaceExtras((Bundle)null);
7331                    }
7332
7333                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7334                        // Check whether this activity is currently available.
7335                        try {
7336                            if (rti.origActivity != null) {
7337                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7338                                        == null) {
7339                                    continue;
7340                                }
7341                            } else if (rti.baseIntent != null) {
7342                                if (pm.queryIntentActivities(rti.baseIntent,
7343                                        null, 0, userId) == null) {
7344                                    continue;
7345                                }
7346                            }
7347                        } catch (RemoteException e) {
7348                            // Will never happen.
7349                        }
7350                    }
7351
7352                    res.add(rti);
7353                    maxNum--;
7354                }
7355            }
7356            return res;
7357        }
7358    }
7359
7360    private TaskRecord recentTaskForIdLocked(int id) {
7361        final int N = mRecentTasks.size();
7362            for (int i=0; i<N; i++) {
7363                TaskRecord tr = mRecentTasks.get(i);
7364                if (tr.taskId == id) {
7365                    return tr;
7366                }
7367            }
7368            return null;
7369    }
7370
7371    @Override
7372    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7373        synchronized (this) {
7374            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7375                    "getTaskThumbnail()");
7376            TaskRecord tr = recentTaskForIdLocked(id);
7377            if (tr != null) {
7378                return tr.getTaskThumbnailLocked();
7379            }
7380        }
7381        return null;
7382    }
7383
7384    @Override
7385    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7386        synchronized (this) {
7387            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7388            if (r != null) {
7389                r.taskDescription = td;
7390                r.task.updateTaskDescription();
7391            }
7392        }
7393    }
7394
7395    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7396        if (!pr.killedByAm) {
7397            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7398            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7399                    pr.processName, pr.setAdj, reason);
7400            pr.killedByAm = true;
7401            Process.killProcessQuiet(pr.pid);
7402        }
7403    }
7404
7405    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7406        tr.disposeThumbnail();
7407        mRecentTasks.remove(tr);
7408        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7409        Intent baseIntent = new Intent(
7410                tr.intent != null ? tr.intent : tr.affinityIntent);
7411        ComponentName component = baseIntent.getComponent();
7412        if (component == null) {
7413            Slog.w(TAG, "Now component for base intent of task: " + tr);
7414            return;
7415        }
7416
7417        // Find any running services associated with this app.
7418        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7419
7420        if (killProcesses) {
7421            // Find any running processes associated with this app.
7422            final String pkg = component.getPackageName();
7423            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7424            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7425            for (int i=0; i<pmap.size(); i++) {
7426                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7427                for (int j=0; j<uids.size(); j++) {
7428                    ProcessRecord proc = uids.valueAt(j);
7429                    if (proc.userId != tr.userId) {
7430                        continue;
7431                    }
7432                    if (!proc.pkgList.containsKey(pkg)) {
7433                        continue;
7434                    }
7435                    procs.add(proc);
7436                }
7437            }
7438
7439            // Kill the running processes.
7440            for (int i=0; i<procs.size(); i++) {
7441                ProcessRecord pr = procs.get(i);
7442                if (pr == mHomeProcess) {
7443                    // Don't kill the home process along with tasks from the same package.
7444                    continue;
7445                }
7446                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7447                    killUnneededProcessLocked(pr, "remove task");
7448                } else {
7449                    pr.waitingToKill = "remove task";
7450                }
7451            }
7452        }
7453    }
7454
7455    /**
7456     * Removes the task with the specified task id.
7457     *
7458     * @param taskId Identifier of the task to be removed.
7459     * @param flags Additional operational flags.  May be 0 or
7460     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7461     * @return Returns true if the given task was found and removed.
7462     */
7463    private boolean removeTaskByIdLocked(int taskId, int flags) {
7464        TaskRecord tr = recentTaskForIdLocked(taskId);
7465        if (tr != null) {
7466            tr.removeTaskActivitiesLocked();
7467            cleanUpRemovedTaskLocked(tr, flags);
7468            if (tr.isPersistable) {
7469                notifyTaskPersisterLocked(tr, true);
7470            }
7471            return true;
7472        }
7473        return false;
7474    }
7475
7476    @Override
7477    public boolean removeTask(int taskId, int flags) {
7478        synchronized (this) {
7479            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7480                    "removeTask()");
7481            long ident = Binder.clearCallingIdentity();
7482            try {
7483                return removeTaskByIdLocked(taskId, flags);
7484            } finally {
7485                Binder.restoreCallingIdentity(ident);
7486            }
7487        }
7488    }
7489
7490    /**
7491     * TODO: Add mController hook
7492     */
7493    @Override
7494    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7495        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7496                "moveTaskToFront()");
7497
7498        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7499        synchronized(this) {
7500            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7501                    Binder.getCallingUid(), "Task to front")) {
7502                ActivityOptions.abort(options);
7503                return;
7504            }
7505            final long origId = Binder.clearCallingIdentity();
7506            try {
7507                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7508                if (task == null) {
7509                    return;
7510                }
7511                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7512                    mStackSupervisor.showLockTaskToast();
7513                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7514                    return;
7515                }
7516                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7517                if (prev != null && prev.isRecentsActivity()) {
7518                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7519                }
7520                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7521            } finally {
7522                Binder.restoreCallingIdentity(origId);
7523            }
7524            ActivityOptions.abort(options);
7525        }
7526    }
7527
7528    @Override
7529    public void moveTaskToBack(int taskId) {
7530        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7531                "moveTaskToBack()");
7532
7533        synchronized(this) {
7534            TaskRecord tr = recentTaskForIdLocked(taskId);
7535            if (tr != null) {
7536                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7537                ActivityStack stack = tr.stack;
7538                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7539                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7540                            Binder.getCallingUid(), "Task to back")) {
7541                        return;
7542                    }
7543                }
7544                final long origId = Binder.clearCallingIdentity();
7545                try {
7546                    stack.moveTaskToBackLocked(taskId, null);
7547                } finally {
7548                    Binder.restoreCallingIdentity(origId);
7549                }
7550            }
7551        }
7552    }
7553
7554    /**
7555     * Moves an activity, and all of the other activities within the same task, to the bottom
7556     * of the history stack.  The activity's order within the task is unchanged.
7557     *
7558     * @param token A reference to the activity we wish to move
7559     * @param nonRoot If false then this only works if the activity is the root
7560     *                of a task; if true it will work for any activity in a task.
7561     * @return Returns true if the move completed, false if not.
7562     */
7563    @Override
7564    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7565        enforceNotIsolatedCaller("moveActivityTaskToBack");
7566        synchronized(this) {
7567            final long origId = Binder.clearCallingIdentity();
7568            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7569            if (taskId >= 0) {
7570                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7571            }
7572            Binder.restoreCallingIdentity(origId);
7573        }
7574        return false;
7575    }
7576
7577    @Override
7578    public void moveTaskBackwards(int task) {
7579        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7580                "moveTaskBackwards()");
7581
7582        synchronized(this) {
7583            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7584                    Binder.getCallingUid(), "Task backwards")) {
7585                return;
7586            }
7587            final long origId = Binder.clearCallingIdentity();
7588            moveTaskBackwardsLocked(task);
7589            Binder.restoreCallingIdentity(origId);
7590        }
7591    }
7592
7593    private final void moveTaskBackwardsLocked(int task) {
7594        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7595    }
7596
7597    @Override
7598    public IBinder getHomeActivityToken() throws RemoteException {
7599        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7600                "getHomeActivityToken()");
7601        synchronized (this) {
7602            return mStackSupervisor.getHomeActivityToken();
7603        }
7604    }
7605
7606    @Override
7607    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7608            IActivityContainerCallback callback) throws RemoteException {
7609        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7610                "createActivityContainer()");
7611        synchronized (this) {
7612            if (parentActivityToken == null) {
7613                throw new IllegalArgumentException("parent token must not be null");
7614            }
7615            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7616            if (r == null) {
7617                return null;
7618            }
7619            if (callback == null) {
7620                throw new IllegalArgumentException("callback must not be null");
7621            }
7622            return mStackSupervisor.createActivityContainer(r, callback);
7623        }
7624    }
7625
7626    @Override
7627    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7628        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7629                "deleteActivityContainer()");
7630        synchronized (this) {
7631            mStackSupervisor.deleteActivityContainer(container);
7632        }
7633    }
7634
7635    @Override
7636    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7637            throws RemoteException {
7638        synchronized (this) {
7639            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7640            if (stack != null) {
7641                return stack.mActivityContainer;
7642            }
7643            return null;
7644        }
7645    }
7646
7647    @Override
7648    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7649        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7650                "moveTaskToStack()");
7651        if (stackId == HOME_STACK_ID) {
7652            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7653                    new RuntimeException("here").fillInStackTrace());
7654        }
7655        synchronized (this) {
7656            long ident = Binder.clearCallingIdentity();
7657            try {
7658                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7659                        + stackId + " toTop=" + toTop);
7660                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7661            } finally {
7662                Binder.restoreCallingIdentity(ident);
7663            }
7664        }
7665    }
7666
7667    @Override
7668    public void resizeStack(int stackBoxId, Rect bounds) {
7669        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7670                "resizeStackBox()");
7671        long ident = Binder.clearCallingIdentity();
7672        try {
7673            mWindowManager.resizeStack(stackBoxId, bounds);
7674        } finally {
7675            Binder.restoreCallingIdentity(ident);
7676        }
7677    }
7678
7679    @Override
7680    public List<StackInfo> getAllStackInfos() {
7681        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7682                "getAllStackInfos()");
7683        long ident = Binder.clearCallingIdentity();
7684        try {
7685            synchronized (this) {
7686                return mStackSupervisor.getAllStackInfosLocked();
7687            }
7688        } finally {
7689            Binder.restoreCallingIdentity(ident);
7690        }
7691    }
7692
7693    @Override
7694    public StackInfo getStackInfo(int stackId) {
7695        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7696                "getStackInfo()");
7697        long ident = Binder.clearCallingIdentity();
7698        try {
7699            synchronized (this) {
7700                return mStackSupervisor.getStackInfoLocked(stackId);
7701            }
7702        } finally {
7703            Binder.restoreCallingIdentity(ident);
7704        }
7705    }
7706
7707    @Override
7708    public boolean isInHomeStack(int taskId) {
7709        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7710                "getStackInfo()");
7711        long ident = Binder.clearCallingIdentity();
7712        try {
7713            synchronized (this) {
7714                TaskRecord tr = recentTaskForIdLocked(taskId);
7715                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7716            }
7717        } finally {
7718            Binder.restoreCallingIdentity(ident);
7719        }
7720    }
7721
7722    @Override
7723    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7724        synchronized(this) {
7725            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7726        }
7727    }
7728
7729    private boolean isLockTaskAuthorized(String pkg) {
7730        final DevicePolicyManager dpm = (DevicePolicyManager)
7731                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7732        try {
7733            int uid = mContext.getPackageManager().getPackageUid(pkg,
7734                    Binder.getCallingUserHandle().getIdentifier());
7735            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7736        } catch (NameNotFoundException e) {
7737            return false;
7738        }
7739    }
7740
7741    void startLockTaskMode(TaskRecord task) {
7742        final String pkg;
7743        synchronized (this) {
7744            pkg = task.intent.getComponent().getPackageName();
7745        }
7746        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7747        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7748            final TaskRecord taskRecord = task;
7749            mHandler.post(new Runnable() {
7750                @Override
7751                public void run() {
7752                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7753                }
7754            });
7755            return;
7756        }
7757        long ident = Binder.clearCallingIdentity();
7758        try {
7759            synchronized (this) {
7760                // Since we lost lock on task, make sure it is still there.
7761                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7762                if (task != null) {
7763                    if (!isSystemInitiated
7764                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7765                        throw new IllegalArgumentException("Invalid task, not in foreground");
7766                    }
7767                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7768                }
7769            }
7770        } finally {
7771            Binder.restoreCallingIdentity(ident);
7772        }
7773    }
7774
7775    @Override
7776    public void startLockTaskMode(int taskId) {
7777        final TaskRecord task;
7778        long ident = Binder.clearCallingIdentity();
7779        try {
7780            synchronized (this) {
7781                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7782            }
7783        } finally {
7784            Binder.restoreCallingIdentity(ident);
7785        }
7786        if (task != null) {
7787            startLockTaskMode(task);
7788        }
7789    }
7790
7791    @Override
7792    public void startLockTaskMode(IBinder token) {
7793        final TaskRecord task;
7794        long ident = Binder.clearCallingIdentity();
7795        try {
7796            synchronized (this) {
7797                final ActivityRecord r = ActivityRecord.forToken(token);
7798                if (r == null) {
7799                    return;
7800                }
7801                task = r.task;
7802            }
7803        } finally {
7804            Binder.restoreCallingIdentity(ident);
7805        }
7806        if (task != null) {
7807            startLockTaskMode(task);
7808        }
7809    }
7810
7811    @Override
7812    public void startLockTaskModeOnCurrent() throws RemoteException {
7813        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7814        ActivityRecord r = null;
7815        synchronized (this) {
7816            r = mStackSupervisor.topRunningActivityLocked();
7817        }
7818        startLockTaskMode(r.task);
7819    }
7820
7821    @Override
7822    public void stopLockTaskMode() {
7823        // Verify that the user matches the package of the intent for the TaskRecord
7824        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7825        // and stopLockTaskMode.
7826        final int callingUid = Binder.getCallingUid();
7827        if (callingUid != Process.SYSTEM_UID) {
7828            try {
7829                String pkg =
7830                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7831                int uid = mContext.getPackageManager().getPackageUid(pkg,
7832                        Binder.getCallingUserHandle().getIdentifier());
7833                if (uid != callingUid) {
7834                    throw new SecurityException("Invalid uid, expected " + uid);
7835                }
7836            } catch (NameNotFoundException e) {
7837                Log.d(TAG, "stopLockTaskMode " + e);
7838                return;
7839            }
7840        }
7841        long ident = Binder.clearCallingIdentity();
7842        try {
7843            Log.d(TAG, "stopLockTaskMode");
7844            // Stop lock task
7845            synchronized (this) {
7846                mStackSupervisor.setLockTaskModeLocked(null, false);
7847            }
7848        } finally {
7849            Binder.restoreCallingIdentity(ident);
7850        }
7851    }
7852
7853    @Override
7854    public void stopLockTaskModeOnCurrent() throws RemoteException {
7855        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7856        long ident = Binder.clearCallingIdentity();
7857        try {
7858            stopLockTaskMode();
7859        } finally {
7860            Binder.restoreCallingIdentity(ident);
7861        }
7862    }
7863
7864    @Override
7865    public boolean isInLockTaskMode() {
7866        synchronized (this) {
7867            return mStackSupervisor.isInLockTaskMode();
7868        }
7869    }
7870
7871    // =========================================================
7872    // CONTENT PROVIDERS
7873    // =========================================================
7874
7875    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7876        List<ProviderInfo> providers = null;
7877        try {
7878            providers = AppGlobals.getPackageManager().
7879                queryContentProviders(app.processName, app.uid,
7880                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7881        } catch (RemoteException ex) {
7882        }
7883        if (DEBUG_MU)
7884            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7885        int userId = app.userId;
7886        if (providers != null) {
7887            int N = providers.size();
7888            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7889            for (int i=0; i<N; i++) {
7890                ProviderInfo cpi =
7891                    (ProviderInfo)providers.get(i);
7892                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7893                        cpi.name, cpi.flags);
7894                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7895                    // This is a singleton provider, but a user besides the
7896                    // default user is asking to initialize a process it runs
7897                    // in...  well, no, it doesn't actually run in this process,
7898                    // it runs in the process of the default user.  Get rid of it.
7899                    providers.remove(i);
7900                    N--;
7901                    i--;
7902                    continue;
7903                }
7904
7905                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7906                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7907                if (cpr == null) {
7908                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7909                    mProviderMap.putProviderByClass(comp, cpr);
7910                }
7911                if (DEBUG_MU)
7912                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7913                app.pubProviders.put(cpi.name, cpr);
7914                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7915                    // Don't add this if it is a platform component that is marked
7916                    // to run in multiple processes, because this is actually
7917                    // part of the framework so doesn't make sense to track as a
7918                    // separate apk in the process.
7919                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
7920                            mProcessStats);
7921                }
7922                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7923            }
7924        }
7925        return providers;
7926    }
7927
7928    /**
7929     * Check if {@link ProcessRecord} has a possible chance at accessing the
7930     * given {@link ProviderInfo}. Final permission checking is always done
7931     * in {@link ContentProvider}.
7932     */
7933    private final String checkContentProviderPermissionLocked(
7934            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7935        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7936        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7937        boolean checkedGrants = false;
7938        if (checkUser) {
7939            // Looking for cross-user grants before enforcing the typical cross-users permissions
7940            if (UserHandle.getUserId(callingUid) != userId) {
7941                if (checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
7942                    return null;
7943                }
7944                checkedGrants = true;
7945            }
7946            userId = handleIncomingUser(callingPid, callingUid, userId,
7947                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7948        }
7949        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7950                cpi.applicationInfo.uid, cpi.exported)
7951                == PackageManager.PERMISSION_GRANTED) {
7952            return null;
7953        }
7954        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7955                cpi.applicationInfo.uid, cpi.exported)
7956                == PackageManager.PERMISSION_GRANTED) {
7957            return null;
7958        }
7959
7960        PathPermission[] pps = cpi.pathPermissions;
7961        if (pps != null) {
7962            int i = pps.length;
7963            while (i > 0) {
7964                i--;
7965                PathPermission pp = pps[i];
7966                String pprperm = pp.getReadPermission();
7967                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
7968                        cpi.applicationInfo.uid, cpi.exported)
7969                        == PackageManager.PERMISSION_GRANTED) {
7970                    return null;
7971                }
7972                String ppwperm = pp.getWritePermission();
7973                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
7974                        cpi.applicationInfo.uid, cpi.exported)
7975                        == PackageManager.PERMISSION_GRANTED) {
7976                    return null;
7977                }
7978            }
7979        }
7980        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
7981            return null;
7982        }
7983
7984        String msg;
7985        if (!cpi.exported) {
7986            msg = "Permission Denial: opening provider " + cpi.name
7987                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7988                    + ", uid=" + callingUid + ") that is not exported from uid "
7989                    + cpi.applicationInfo.uid;
7990        } else {
7991            msg = "Permission Denial: opening provider " + cpi.name
7992                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7993                    + ", uid=" + callingUid + ") requires "
7994                    + cpi.readPermission + " or " + cpi.writePermission;
7995        }
7996        Slog.w(TAG, msg);
7997        return msg;
7998    }
7999
8000    /**
8001     * Returns if the ContentProvider has granted a uri to callingUid
8002     */
8003    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8004        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8005        if (perms != null) {
8006            for (GrantUri grantUri : perms.keySet()) {
8007                if (grantUri.sourceUserId == userId || !checkUser) {
8008                    if (matchesProvider(grantUri.uri, cpi)) {
8009                        return true;
8010                    }
8011                }
8012            }
8013        }
8014        return false;
8015    }
8016
8017    /**
8018     * Returns true if the uri authority is one of the authorities specified in the provider.
8019     */
8020    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8021        String uriAuth = uri.getAuthority();
8022        String cpiAuth = cpi.authority;
8023        if (cpiAuth.indexOf(';') == -1) {
8024            return cpiAuth.equals(uriAuth);
8025        }
8026        String[] cpiAuths = cpiAuth.split(";");
8027        int length = cpiAuths.length;
8028        for (int i = 0; i < length; i++) {
8029            if (cpiAuths[i].equals(uriAuth)) return true;
8030        }
8031        return false;
8032    }
8033
8034    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8035            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8036        if (r != null) {
8037            for (int i=0; i<r.conProviders.size(); i++) {
8038                ContentProviderConnection conn = r.conProviders.get(i);
8039                if (conn.provider == cpr) {
8040                    if (DEBUG_PROVIDER) Slog.v(TAG,
8041                            "Adding provider requested by "
8042                            + r.processName + " from process "
8043                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8044                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8045                    if (stable) {
8046                        conn.stableCount++;
8047                        conn.numStableIncs++;
8048                    } else {
8049                        conn.unstableCount++;
8050                        conn.numUnstableIncs++;
8051                    }
8052                    return conn;
8053                }
8054            }
8055            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8056            if (stable) {
8057                conn.stableCount = 1;
8058                conn.numStableIncs = 1;
8059            } else {
8060                conn.unstableCount = 1;
8061                conn.numUnstableIncs = 1;
8062            }
8063            cpr.connections.add(conn);
8064            r.conProviders.add(conn);
8065            return conn;
8066        }
8067        cpr.addExternalProcessHandleLocked(externalProcessToken);
8068        return null;
8069    }
8070
8071    boolean decProviderCountLocked(ContentProviderConnection conn,
8072            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8073        if (conn != null) {
8074            cpr = conn.provider;
8075            if (DEBUG_PROVIDER) Slog.v(TAG,
8076                    "Removing provider requested by "
8077                    + conn.client.processName + " from process "
8078                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8079                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8080            if (stable) {
8081                conn.stableCount--;
8082            } else {
8083                conn.unstableCount--;
8084            }
8085            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8086                cpr.connections.remove(conn);
8087                conn.client.conProviders.remove(conn);
8088                return true;
8089            }
8090            return false;
8091        }
8092        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8093        return false;
8094    }
8095
8096    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8097            String name, IBinder token, boolean stable, int userId) {
8098        ContentProviderRecord cpr;
8099        ContentProviderConnection conn = null;
8100        ProviderInfo cpi = null;
8101
8102        synchronized(this) {
8103            ProcessRecord r = null;
8104            if (caller != null) {
8105                r = getRecordForAppLocked(caller);
8106                if (r == null) {
8107                    throw new SecurityException(
8108                            "Unable to find app for caller " + caller
8109                          + " (pid=" + Binder.getCallingPid()
8110                          + ") when getting content provider " + name);
8111                }
8112            }
8113
8114            boolean checkCrossUser = true;
8115
8116            // First check if this content provider has been published...
8117            cpr = mProviderMap.getProviderByName(name, userId);
8118            // If that didn't work, check if it exists for user 0 and then
8119            // verify that it's a singleton provider before using it.
8120            if (cpr == null && userId != UserHandle.USER_OWNER) {
8121                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8122                if (cpr != null) {
8123                    cpi = cpr.info;
8124                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8125                            cpi.name, cpi.flags)
8126                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8127                        userId = UserHandle.USER_OWNER;
8128                        checkCrossUser = false;
8129                    } else {
8130                        cpr = null;
8131                        cpi = null;
8132                    }
8133                }
8134            }
8135
8136            boolean providerRunning = cpr != null;
8137            if (providerRunning) {
8138                cpi = cpr.info;
8139                String msg;
8140                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8141                        != null) {
8142                    throw new SecurityException(msg);
8143                }
8144
8145                if (r != null && cpr.canRunHere(r)) {
8146                    // This provider has been published or is in the process
8147                    // of being published...  but it is also allowed to run
8148                    // in the caller's process, so don't make a connection
8149                    // and just let the caller instantiate its own instance.
8150                    ContentProviderHolder holder = cpr.newHolder(null);
8151                    // don't give caller the provider object, it needs
8152                    // to make its own.
8153                    holder.provider = null;
8154                    return holder;
8155                }
8156
8157                final long origId = Binder.clearCallingIdentity();
8158
8159                // In this case the provider instance already exists, so we can
8160                // return it right away.
8161                conn = incProviderCountLocked(r, cpr, token, stable);
8162                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8163                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8164                        // If this is a perceptible app accessing the provider,
8165                        // make sure to count it as being accessed and thus
8166                        // back up on the LRU list.  This is good because
8167                        // content providers are often expensive to start.
8168                        updateLruProcessLocked(cpr.proc, false, null);
8169                    }
8170                }
8171
8172                if (cpr.proc != null) {
8173                    if (false) {
8174                        if (cpr.name.flattenToShortString().equals(
8175                                "com.android.providers.calendar/.CalendarProvider2")) {
8176                            Slog.v(TAG, "****************** KILLING "
8177                                + cpr.name.flattenToShortString());
8178                            Process.killProcess(cpr.proc.pid);
8179                        }
8180                    }
8181                    boolean success = updateOomAdjLocked(cpr.proc);
8182                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8183                    // NOTE: there is still a race here where a signal could be
8184                    // pending on the process even though we managed to update its
8185                    // adj level.  Not sure what to do about this, but at least
8186                    // the race is now smaller.
8187                    if (!success) {
8188                        // Uh oh...  it looks like the provider's process
8189                        // has been killed on us.  We need to wait for a new
8190                        // process to be started, and make sure its death
8191                        // doesn't kill our process.
8192                        Slog.i(TAG,
8193                                "Existing provider " + cpr.name.flattenToShortString()
8194                                + " is crashing; detaching " + r);
8195                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8196                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8197                        if (!lastRef) {
8198                            // This wasn't the last ref our process had on
8199                            // the provider...  we have now been killed, bail.
8200                            return null;
8201                        }
8202                        providerRunning = false;
8203                        conn = null;
8204                    }
8205                }
8206
8207                Binder.restoreCallingIdentity(origId);
8208            }
8209
8210            boolean singleton;
8211            if (!providerRunning) {
8212                try {
8213                    cpi = AppGlobals.getPackageManager().
8214                        resolveContentProvider(name,
8215                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8216                } catch (RemoteException ex) {
8217                }
8218                if (cpi == null) {
8219                    return null;
8220                }
8221                // If the provider is a singleton AND
8222                // (it's a call within the same user || the provider is a
8223                // privileged app)
8224                // Then allow connecting to the singleton provider
8225                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8226                        cpi.name, cpi.flags)
8227                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8228                if (singleton) {
8229                    userId = UserHandle.USER_OWNER;
8230                }
8231                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8232
8233                String msg;
8234                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8235                        != null) {
8236                    throw new SecurityException(msg);
8237                }
8238
8239                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8240                        && !cpi.processName.equals("system")) {
8241                    // If this content provider does not run in the system
8242                    // process, and the system is not yet ready to run other
8243                    // processes, then fail fast instead of hanging.
8244                    throw new IllegalArgumentException(
8245                            "Attempt to launch content provider before system ready");
8246                }
8247
8248                // Make sure that the user who owns this provider is started.  If not,
8249                // we don't want to allow it to run.
8250                if (mStartedUsers.get(userId) == null) {
8251                    Slog.w(TAG, "Unable to launch app "
8252                            + cpi.applicationInfo.packageName + "/"
8253                            + cpi.applicationInfo.uid + " for provider "
8254                            + name + ": user " + userId + " is stopped");
8255                    return null;
8256                }
8257
8258                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8259                cpr = mProviderMap.getProviderByClass(comp, userId);
8260                final boolean firstClass = cpr == null;
8261                if (firstClass) {
8262                    try {
8263                        ApplicationInfo ai =
8264                            AppGlobals.getPackageManager().
8265                                getApplicationInfo(
8266                                        cpi.applicationInfo.packageName,
8267                                        STOCK_PM_FLAGS, userId);
8268                        if (ai == null) {
8269                            Slog.w(TAG, "No package info for content provider "
8270                                    + cpi.name);
8271                            return null;
8272                        }
8273                        ai = getAppInfoForUser(ai, userId);
8274                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8275                    } catch (RemoteException ex) {
8276                        // pm is in same process, this will never happen.
8277                    }
8278                }
8279
8280                if (r != null && cpr.canRunHere(r)) {
8281                    // If this is a multiprocess provider, then just return its
8282                    // info and allow the caller to instantiate it.  Only do
8283                    // this if the provider is the same user as the caller's
8284                    // process, or can run as root (so can be in any process).
8285                    return cpr.newHolder(null);
8286                }
8287
8288                if (DEBUG_PROVIDER) {
8289                    RuntimeException e = new RuntimeException("here");
8290                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8291                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8292                }
8293
8294                // This is single process, and our app is now connecting to it.
8295                // See if we are already in the process of launching this
8296                // provider.
8297                final int N = mLaunchingProviders.size();
8298                int i;
8299                for (i=0; i<N; i++) {
8300                    if (mLaunchingProviders.get(i) == cpr) {
8301                        break;
8302                    }
8303                }
8304
8305                // If the provider is not already being launched, then get it
8306                // started.
8307                if (i >= N) {
8308                    final long origId = Binder.clearCallingIdentity();
8309
8310                    try {
8311                        // Content provider is now in use, its package can't be stopped.
8312                        try {
8313                            AppGlobals.getPackageManager().setPackageStoppedState(
8314                                    cpr.appInfo.packageName, false, userId);
8315                        } catch (RemoteException e) {
8316                        } catch (IllegalArgumentException e) {
8317                            Slog.w(TAG, "Failed trying to unstop package "
8318                                    + cpr.appInfo.packageName + ": " + e);
8319                        }
8320
8321                        // Use existing process if already started
8322                        ProcessRecord proc = getProcessRecordLocked(
8323                                cpi.processName, cpr.appInfo.uid, false);
8324                        if (proc != null && proc.thread != null) {
8325                            if (DEBUG_PROVIDER) {
8326                                Slog.d(TAG, "Installing in existing process " + proc);
8327                            }
8328                            proc.pubProviders.put(cpi.name, cpr);
8329                            try {
8330                                proc.thread.scheduleInstallProvider(cpi);
8331                            } catch (RemoteException e) {
8332                            }
8333                        } else {
8334                            proc = startProcessLocked(cpi.processName,
8335                                    cpr.appInfo, false, 0, "content provider",
8336                                    new ComponentName(cpi.applicationInfo.packageName,
8337                                            cpi.name), false, false, false);
8338                            if (proc == null) {
8339                                Slog.w(TAG, "Unable to launch app "
8340                                        + cpi.applicationInfo.packageName + "/"
8341                                        + cpi.applicationInfo.uid + " for provider "
8342                                        + name + ": process is bad");
8343                                return null;
8344                            }
8345                        }
8346                        cpr.launchingApp = proc;
8347                        mLaunchingProviders.add(cpr);
8348                    } finally {
8349                        Binder.restoreCallingIdentity(origId);
8350                    }
8351                }
8352
8353                // Make sure the provider is published (the same provider class
8354                // may be published under multiple names).
8355                if (firstClass) {
8356                    mProviderMap.putProviderByClass(comp, cpr);
8357                }
8358
8359                mProviderMap.putProviderByName(name, cpr);
8360                conn = incProviderCountLocked(r, cpr, token, stable);
8361                if (conn != null) {
8362                    conn.waiting = true;
8363                }
8364            }
8365        }
8366
8367        // Wait for the provider to be published...
8368        synchronized (cpr) {
8369            while (cpr.provider == null) {
8370                if (cpr.launchingApp == null) {
8371                    Slog.w(TAG, "Unable to launch app "
8372                            + cpi.applicationInfo.packageName + "/"
8373                            + cpi.applicationInfo.uid + " for provider "
8374                            + name + ": launching app became null");
8375                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8376                            UserHandle.getUserId(cpi.applicationInfo.uid),
8377                            cpi.applicationInfo.packageName,
8378                            cpi.applicationInfo.uid, name);
8379                    return null;
8380                }
8381                try {
8382                    if (DEBUG_MU) {
8383                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8384                                + cpr.launchingApp);
8385                    }
8386                    if (conn != null) {
8387                        conn.waiting = true;
8388                    }
8389                    cpr.wait();
8390                } catch (InterruptedException ex) {
8391                } finally {
8392                    if (conn != null) {
8393                        conn.waiting = false;
8394                    }
8395                }
8396            }
8397        }
8398        return cpr != null ? cpr.newHolder(conn) : null;
8399    }
8400
8401    @Override
8402    public final ContentProviderHolder getContentProvider(
8403            IApplicationThread caller, String name, int userId, boolean stable) {
8404        enforceNotIsolatedCaller("getContentProvider");
8405        if (caller == null) {
8406            String msg = "null IApplicationThread when getting content provider "
8407                    + name;
8408            Slog.w(TAG, msg);
8409            throw new SecurityException(msg);
8410        }
8411        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8412        // with cross-user grant.
8413        return getContentProviderImpl(caller, name, null, stable, userId);
8414    }
8415
8416    public ContentProviderHolder getContentProviderExternal(
8417            String name, int userId, IBinder token) {
8418        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8419            "Do not have permission in call getContentProviderExternal()");
8420        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8421                false, true, "getContentProvider", null);
8422        return getContentProviderExternalUnchecked(name, token, userId);
8423    }
8424
8425    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8426            IBinder token, int userId) {
8427        return getContentProviderImpl(null, name, token, true, userId);
8428    }
8429
8430    /**
8431     * Drop a content provider from a ProcessRecord's bookkeeping
8432     */
8433    public void removeContentProvider(IBinder connection, boolean stable) {
8434        enforceNotIsolatedCaller("removeContentProvider");
8435        long ident = Binder.clearCallingIdentity();
8436        try {
8437            synchronized (this) {
8438                ContentProviderConnection conn;
8439                try {
8440                    conn = (ContentProviderConnection)connection;
8441                } catch (ClassCastException e) {
8442                    String msg ="removeContentProvider: " + connection
8443                            + " not a ContentProviderConnection";
8444                    Slog.w(TAG, msg);
8445                    throw new IllegalArgumentException(msg);
8446                }
8447                if (conn == null) {
8448                    throw new NullPointerException("connection is null");
8449                }
8450                if (decProviderCountLocked(conn, null, null, stable)) {
8451                    updateOomAdjLocked();
8452                }
8453            }
8454        } finally {
8455            Binder.restoreCallingIdentity(ident);
8456        }
8457    }
8458
8459    public void removeContentProviderExternal(String name, IBinder token) {
8460        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8461            "Do not have permission in call removeContentProviderExternal()");
8462        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8463    }
8464
8465    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8466        synchronized (this) {
8467            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8468            if(cpr == null) {
8469                //remove from mProvidersByClass
8470                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8471                return;
8472            }
8473
8474            //update content provider record entry info
8475            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8476            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8477            if (localCpr.hasExternalProcessHandles()) {
8478                if (localCpr.removeExternalProcessHandleLocked(token)) {
8479                    updateOomAdjLocked();
8480                } else {
8481                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8482                            + " with no external reference for token: "
8483                            + token + ".");
8484                }
8485            } else {
8486                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8487                        + " with no external references.");
8488            }
8489        }
8490    }
8491
8492    public final void publishContentProviders(IApplicationThread caller,
8493            List<ContentProviderHolder> providers) {
8494        if (providers == null) {
8495            return;
8496        }
8497
8498        enforceNotIsolatedCaller("publishContentProviders");
8499        synchronized (this) {
8500            final ProcessRecord r = getRecordForAppLocked(caller);
8501            if (DEBUG_MU)
8502                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8503            if (r == null) {
8504                throw new SecurityException(
8505                        "Unable to find app for caller " + caller
8506                      + " (pid=" + Binder.getCallingPid()
8507                      + ") when publishing content providers");
8508            }
8509
8510            final long origId = Binder.clearCallingIdentity();
8511
8512            final int N = providers.size();
8513            for (int i=0; i<N; i++) {
8514                ContentProviderHolder src = providers.get(i);
8515                if (src == null || src.info == null || src.provider == null) {
8516                    continue;
8517                }
8518                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8519                if (DEBUG_MU)
8520                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8521                if (dst != null) {
8522                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8523                    mProviderMap.putProviderByClass(comp, dst);
8524                    String names[] = dst.info.authority.split(";");
8525                    for (int j = 0; j < names.length; j++) {
8526                        mProviderMap.putProviderByName(names[j], dst);
8527                    }
8528
8529                    int NL = mLaunchingProviders.size();
8530                    int j;
8531                    for (j=0; j<NL; j++) {
8532                        if (mLaunchingProviders.get(j) == dst) {
8533                            mLaunchingProviders.remove(j);
8534                            j--;
8535                            NL--;
8536                        }
8537                    }
8538                    synchronized (dst) {
8539                        dst.provider = src.provider;
8540                        dst.proc = r;
8541                        dst.notifyAll();
8542                    }
8543                    updateOomAdjLocked(r);
8544                }
8545            }
8546
8547            Binder.restoreCallingIdentity(origId);
8548        }
8549    }
8550
8551    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8552        ContentProviderConnection conn;
8553        try {
8554            conn = (ContentProviderConnection)connection;
8555        } catch (ClassCastException e) {
8556            String msg ="refContentProvider: " + connection
8557                    + " not a ContentProviderConnection";
8558            Slog.w(TAG, msg);
8559            throw new IllegalArgumentException(msg);
8560        }
8561        if (conn == null) {
8562            throw new NullPointerException("connection is null");
8563        }
8564
8565        synchronized (this) {
8566            if (stable > 0) {
8567                conn.numStableIncs += stable;
8568            }
8569            stable = conn.stableCount + stable;
8570            if (stable < 0) {
8571                throw new IllegalStateException("stableCount < 0: " + stable);
8572            }
8573
8574            if (unstable > 0) {
8575                conn.numUnstableIncs += unstable;
8576            }
8577            unstable = conn.unstableCount + unstable;
8578            if (unstable < 0) {
8579                throw new IllegalStateException("unstableCount < 0: " + unstable);
8580            }
8581
8582            if ((stable+unstable) <= 0) {
8583                throw new IllegalStateException("ref counts can't go to zero here: stable="
8584                        + stable + " unstable=" + unstable);
8585            }
8586            conn.stableCount = stable;
8587            conn.unstableCount = unstable;
8588            return !conn.dead;
8589        }
8590    }
8591
8592    public void unstableProviderDied(IBinder connection) {
8593        ContentProviderConnection conn;
8594        try {
8595            conn = (ContentProviderConnection)connection;
8596        } catch (ClassCastException e) {
8597            String msg ="refContentProvider: " + connection
8598                    + " not a ContentProviderConnection";
8599            Slog.w(TAG, msg);
8600            throw new IllegalArgumentException(msg);
8601        }
8602        if (conn == null) {
8603            throw new NullPointerException("connection is null");
8604        }
8605
8606        // Safely retrieve the content provider associated with the connection.
8607        IContentProvider provider;
8608        synchronized (this) {
8609            provider = conn.provider.provider;
8610        }
8611
8612        if (provider == null) {
8613            // Um, yeah, we're way ahead of you.
8614            return;
8615        }
8616
8617        // Make sure the caller is being honest with us.
8618        if (provider.asBinder().pingBinder()) {
8619            // Er, no, still looks good to us.
8620            synchronized (this) {
8621                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8622                        + " says " + conn + " died, but we don't agree");
8623                return;
8624            }
8625        }
8626
8627        // Well look at that!  It's dead!
8628        synchronized (this) {
8629            if (conn.provider.provider != provider) {
8630                // But something changed...  good enough.
8631                return;
8632            }
8633
8634            ProcessRecord proc = conn.provider.proc;
8635            if (proc == null || proc.thread == null) {
8636                // Seems like the process is already cleaned up.
8637                return;
8638            }
8639
8640            // As far as we're concerned, this is just like receiving a
8641            // death notification...  just a bit prematurely.
8642            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8643                    + ") early provider death");
8644            final long ident = Binder.clearCallingIdentity();
8645            try {
8646                appDiedLocked(proc, proc.pid, proc.thread);
8647            } finally {
8648                Binder.restoreCallingIdentity(ident);
8649            }
8650        }
8651    }
8652
8653    @Override
8654    public void appNotRespondingViaProvider(IBinder connection) {
8655        enforceCallingPermission(
8656                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8657
8658        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8659        if (conn == null) {
8660            Slog.w(TAG, "ContentProviderConnection is null");
8661            return;
8662        }
8663
8664        final ProcessRecord host = conn.provider.proc;
8665        if (host == null) {
8666            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8667            return;
8668        }
8669
8670        final long token = Binder.clearCallingIdentity();
8671        try {
8672            appNotResponding(host, null, null, false, "ContentProvider not responding");
8673        } finally {
8674            Binder.restoreCallingIdentity(token);
8675        }
8676    }
8677
8678    public final void installSystemProviders() {
8679        List<ProviderInfo> providers;
8680        synchronized (this) {
8681            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8682            providers = generateApplicationProvidersLocked(app);
8683            if (providers != null) {
8684                for (int i=providers.size()-1; i>=0; i--) {
8685                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8686                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8687                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8688                                + ": not system .apk");
8689                        providers.remove(i);
8690                    }
8691                }
8692            }
8693        }
8694        if (providers != null) {
8695            mSystemThread.installSystemProviders(providers);
8696        }
8697
8698        mCoreSettingsObserver = new CoreSettingsObserver(this);
8699
8700        mUsageStatsService.monitorPackages();
8701    }
8702
8703    /**
8704     * Allows app to retrieve the MIME type of a URI without having permission
8705     * to access its content provider.
8706     *
8707     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8708     *
8709     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8710     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8711     */
8712    public String getProviderMimeType(Uri uri, int userId) {
8713        enforceNotIsolatedCaller("getProviderMimeType");
8714        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8715                userId, false, true, "getProviderMimeType", null);
8716        final String name = uri.getAuthority();
8717        final long ident = Binder.clearCallingIdentity();
8718        ContentProviderHolder holder = null;
8719
8720        try {
8721            holder = getContentProviderExternalUnchecked(name, null, userId);
8722            if (holder != null) {
8723                return holder.provider.getType(uri);
8724            }
8725        } catch (RemoteException e) {
8726            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8727            return null;
8728        } finally {
8729            if (holder != null) {
8730                removeContentProviderExternalUnchecked(name, null, userId);
8731            }
8732            Binder.restoreCallingIdentity(ident);
8733        }
8734
8735        return null;
8736    }
8737
8738    // =========================================================
8739    // GLOBAL MANAGEMENT
8740    // =========================================================
8741
8742    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8743            boolean isolated) {
8744        String proc = customProcess != null ? customProcess : info.processName;
8745        BatteryStatsImpl.Uid.Proc ps = null;
8746        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8747        int uid = info.uid;
8748        if (isolated) {
8749            int userId = UserHandle.getUserId(uid);
8750            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8751            while (true) {
8752                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8753                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8754                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8755                }
8756                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8757                mNextIsolatedProcessUid++;
8758                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8759                    // No process for this uid, use it.
8760                    break;
8761                }
8762                stepsLeft--;
8763                if (stepsLeft <= 0) {
8764                    return null;
8765                }
8766            }
8767        }
8768        return new ProcessRecord(stats, info, proc, uid);
8769    }
8770
8771    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8772            String abiOverride) {
8773        ProcessRecord app;
8774        if (!isolated) {
8775            app = getProcessRecordLocked(info.processName, info.uid, true);
8776        } else {
8777            app = null;
8778        }
8779
8780        if (app == null) {
8781            app = newProcessRecordLocked(info, null, isolated);
8782            mProcessNames.put(info.processName, app.uid, app);
8783            if (isolated) {
8784                mIsolatedProcesses.put(app.uid, app);
8785            }
8786            updateLruProcessLocked(app, false, null);
8787            updateOomAdjLocked();
8788        }
8789
8790        // This package really, really can not be stopped.
8791        try {
8792            AppGlobals.getPackageManager().setPackageStoppedState(
8793                    info.packageName, false, UserHandle.getUserId(app.uid));
8794        } catch (RemoteException e) {
8795        } catch (IllegalArgumentException e) {
8796            Slog.w(TAG, "Failed trying to unstop package "
8797                    + info.packageName + ": " + e);
8798        }
8799
8800        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8801                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8802            app.persistent = true;
8803            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8804        }
8805        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8806            mPersistentStartingProcesses.add(app);
8807            startProcessLocked(app, "added application", app.processName,
8808                    abiOverride);
8809        }
8810
8811        return app;
8812    }
8813
8814    public void unhandledBack() {
8815        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8816                "unhandledBack()");
8817
8818        synchronized(this) {
8819            final long origId = Binder.clearCallingIdentity();
8820            try {
8821                getFocusedStack().unhandledBackLocked();
8822            } finally {
8823                Binder.restoreCallingIdentity(origId);
8824            }
8825        }
8826    }
8827
8828    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8829        enforceNotIsolatedCaller("openContentUri");
8830        final int userId = UserHandle.getCallingUserId();
8831        String name = uri.getAuthority();
8832        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8833        ParcelFileDescriptor pfd = null;
8834        if (cph != null) {
8835            // We record the binder invoker's uid in thread-local storage before
8836            // going to the content provider to open the file.  Later, in the code
8837            // that handles all permissions checks, we look for this uid and use
8838            // that rather than the Activity Manager's own uid.  The effect is that
8839            // we do the check against the caller's permissions even though it looks
8840            // to the content provider like the Activity Manager itself is making
8841            // the request.
8842            sCallerIdentity.set(new Identity(
8843                    Binder.getCallingPid(), Binder.getCallingUid()));
8844            try {
8845                pfd = cph.provider.openFile(null, uri, "r", null);
8846            } catch (FileNotFoundException e) {
8847                // do nothing; pfd will be returned null
8848            } finally {
8849                // Ensure that whatever happens, we clean up the identity state
8850                sCallerIdentity.remove();
8851            }
8852
8853            // We've got the fd now, so we're done with the provider.
8854            removeContentProviderExternalUnchecked(name, null, userId);
8855        } else {
8856            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8857        }
8858        return pfd;
8859    }
8860
8861    // Actually is sleeping or shutting down or whatever else in the future
8862    // is an inactive state.
8863    public boolean isSleepingOrShuttingDown() {
8864        return mSleeping || mShuttingDown;
8865    }
8866
8867    public boolean isSleeping() {
8868        return mSleeping;
8869    }
8870
8871    void goingToSleep() {
8872        synchronized(this) {
8873            mWentToSleep = true;
8874            updateEventDispatchingLocked();
8875            goToSleepIfNeededLocked();
8876        }
8877    }
8878
8879    void finishRunningVoiceLocked() {
8880        if (mRunningVoice) {
8881            mRunningVoice = false;
8882            goToSleepIfNeededLocked();
8883        }
8884    }
8885
8886    void goToSleepIfNeededLocked() {
8887        if (mWentToSleep && !mRunningVoice) {
8888            if (!mSleeping) {
8889                mSleeping = true;
8890                mStackSupervisor.goingToSleepLocked();
8891
8892                // Initialize the wake times of all processes.
8893                checkExcessivePowerUsageLocked(false);
8894                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8895                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8896                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8897            }
8898        }
8899    }
8900
8901    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8902        mTaskPersister.notify(task, flush);
8903    }
8904
8905    @Override
8906    public boolean shutdown(int timeout) {
8907        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8908                != PackageManager.PERMISSION_GRANTED) {
8909            throw new SecurityException("Requires permission "
8910                    + android.Manifest.permission.SHUTDOWN);
8911        }
8912
8913        boolean timedout = false;
8914
8915        synchronized(this) {
8916            mShuttingDown = true;
8917            updateEventDispatchingLocked();
8918            timedout = mStackSupervisor.shutdownLocked(timeout);
8919        }
8920
8921        mAppOpsService.shutdown();
8922        mUsageStatsService.shutdown();
8923        mBatteryStatsService.shutdown();
8924        synchronized (this) {
8925            mProcessStats.shutdownLocked();
8926        }
8927        notifyTaskPersisterLocked(null, true);
8928
8929        return timedout;
8930    }
8931
8932    public final void activitySlept(IBinder token) {
8933        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8934
8935        final long origId = Binder.clearCallingIdentity();
8936
8937        synchronized (this) {
8938            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8939            if (r != null) {
8940                mStackSupervisor.activitySleptLocked(r);
8941            }
8942        }
8943
8944        Binder.restoreCallingIdentity(origId);
8945    }
8946
8947    void logLockScreen(String msg) {
8948        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8949                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8950                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8951                mStackSupervisor.mDismissKeyguardOnNextActivity);
8952    }
8953
8954    private void comeOutOfSleepIfNeededLocked() {
8955        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8956            if (mSleeping) {
8957                mSleeping = false;
8958                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8959            }
8960        }
8961    }
8962
8963    void wakingUp() {
8964        synchronized(this) {
8965            mWentToSleep = false;
8966            updateEventDispatchingLocked();
8967            comeOutOfSleepIfNeededLocked();
8968        }
8969    }
8970
8971    void startRunningVoiceLocked() {
8972        if (!mRunningVoice) {
8973            mRunningVoice = true;
8974            comeOutOfSleepIfNeededLocked();
8975        }
8976    }
8977
8978    private void updateEventDispatchingLocked() {
8979        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8980    }
8981
8982    public void setLockScreenShown(boolean shown) {
8983        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8984                != PackageManager.PERMISSION_GRANTED) {
8985            throw new SecurityException("Requires permission "
8986                    + android.Manifest.permission.DEVICE_POWER);
8987        }
8988
8989        synchronized(this) {
8990            long ident = Binder.clearCallingIdentity();
8991            try {
8992                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8993                mLockScreenShown = shown;
8994                comeOutOfSleepIfNeededLocked();
8995            } finally {
8996                Binder.restoreCallingIdentity(ident);
8997            }
8998        }
8999    }
9000
9001    public void stopAppSwitches() {
9002        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9003                != PackageManager.PERMISSION_GRANTED) {
9004            throw new SecurityException("Requires permission "
9005                    + android.Manifest.permission.STOP_APP_SWITCHES);
9006        }
9007
9008        synchronized(this) {
9009            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9010                    + APP_SWITCH_DELAY_TIME;
9011            mDidAppSwitch = false;
9012            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9013            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9014            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9015        }
9016    }
9017
9018    public void resumeAppSwitches() {
9019        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9020                != PackageManager.PERMISSION_GRANTED) {
9021            throw new SecurityException("Requires permission "
9022                    + android.Manifest.permission.STOP_APP_SWITCHES);
9023        }
9024
9025        synchronized(this) {
9026            // Note that we don't execute any pending app switches... we will
9027            // let those wait until either the timeout, or the next start
9028            // activity request.
9029            mAppSwitchesAllowedTime = 0;
9030        }
9031    }
9032
9033    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9034            String name) {
9035        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9036            return true;
9037        }
9038
9039        final int perm = checkComponentPermission(
9040                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9041                callingUid, -1, true);
9042        if (perm == PackageManager.PERMISSION_GRANTED) {
9043            return true;
9044        }
9045
9046        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9047        return false;
9048    }
9049
9050    public void setDebugApp(String packageName, boolean waitForDebugger,
9051            boolean persistent) {
9052        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9053                "setDebugApp()");
9054
9055        long ident = Binder.clearCallingIdentity();
9056        try {
9057            // Note that this is not really thread safe if there are multiple
9058            // callers into it at the same time, but that's not a situation we
9059            // care about.
9060            if (persistent) {
9061                final ContentResolver resolver = mContext.getContentResolver();
9062                Settings.Global.putString(
9063                    resolver, Settings.Global.DEBUG_APP,
9064                    packageName);
9065                Settings.Global.putInt(
9066                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9067                    waitForDebugger ? 1 : 0);
9068            }
9069
9070            synchronized (this) {
9071                if (!persistent) {
9072                    mOrigDebugApp = mDebugApp;
9073                    mOrigWaitForDebugger = mWaitForDebugger;
9074                }
9075                mDebugApp = packageName;
9076                mWaitForDebugger = waitForDebugger;
9077                mDebugTransient = !persistent;
9078                if (packageName != null) {
9079                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9080                            false, UserHandle.USER_ALL, "set debug app");
9081                }
9082            }
9083        } finally {
9084            Binder.restoreCallingIdentity(ident);
9085        }
9086    }
9087
9088    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9089        synchronized (this) {
9090            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9091            if (!isDebuggable) {
9092                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9093                    throw new SecurityException("Process not debuggable: " + app.packageName);
9094                }
9095            }
9096
9097            mOpenGlTraceApp = processName;
9098        }
9099    }
9100
9101    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9102            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9103        synchronized (this) {
9104            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9105            if (!isDebuggable) {
9106                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9107                    throw new SecurityException("Process not debuggable: " + app.packageName);
9108                }
9109            }
9110            mProfileApp = processName;
9111            mProfileFile = profileFile;
9112            if (mProfileFd != null) {
9113                try {
9114                    mProfileFd.close();
9115                } catch (IOException e) {
9116                }
9117                mProfileFd = null;
9118            }
9119            mProfileFd = profileFd;
9120            mProfileType = 0;
9121            mAutoStopProfiler = autoStopProfiler;
9122        }
9123    }
9124
9125    @Override
9126    public void setAlwaysFinish(boolean enabled) {
9127        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9128                "setAlwaysFinish()");
9129
9130        Settings.Global.putInt(
9131                mContext.getContentResolver(),
9132                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9133
9134        synchronized (this) {
9135            mAlwaysFinishActivities = enabled;
9136        }
9137    }
9138
9139    @Override
9140    public void setActivityController(IActivityController controller) {
9141        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9142                "setActivityController()");
9143        synchronized (this) {
9144            mController = controller;
9145            Watchdog.getInstance().setActivityController(controller);
9146        }
9147    }
9148
9149    @Override
9150    public void setUserIsMonkey(boolean userIsMonkey) {
9151        synchronized (this) {
9152            synchronized (mPidsSelfLocked) {
9153                final int callingPid = Binder.getCallingPid();
9154                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9155                if (precessRecord == null) {
9156                    throw new SecurityException("Unknown process: " + callingPid);
9157                }
9158                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9159                    throw new SecurityException("Only an instrumentation process "
9160                            + "with a UiAutomation can call setUserIsMonkey");
9161                }
9162            }
9163            mUserIsMonkey = userIsMonkey;
9164        }
9165    }
9166
9167    @Override
9168    public boolean isUserAMonkey() {
9169        synchronized (this) {
9170            // If there is a controller also implies the user is a monkey.
9171            return (mUserIsMonkey || mController != null);
9172        }
9173    }
9174
9175    public void requestBugReport() {
9176        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9177        SystemProperties.set("ctl.start", "bugreport");
9178    }
9179
9180    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9181        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9182    }
9183
9184    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9185        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9186            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9187        }
9188        return KEY_DISPATCHING_TIMEOUT;
9189    }
9190
9191    @Override
9192    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9193        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9194                != PackageManager.PERMISSION_GRANTED) {
9195            throw new SecurityException("Requires permission "
9196                    + android.Manifest.permission.FILTER_EVENTS);
9197        }
9198        ProcessRecord proc;
9199        long timeout;
9200        synchronized (this) {
9201            synchronized (mPidsSelfLocked) {
9202                proc = mPidsSelfLocked.get(pid);
9203            }
9204            timeout = getInputDispatchingTimeoutLocked(proc);
9205        }
9206
9207        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9208            return -1;
9209        }
9210
9211        return timeout;
9212    }
9213
9214    /**
9215     * Handle input dispatching timeouts.
9216     * Returns whether input dispatching should be aborted or not.
9217     */
9218    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9219            final ActivityRecord activity, final ActivityRecord parent,
9220            final boolean aboveSystem, String reason) {
9221        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9222                != PackageManager.PERMISSION_GRANTED) {
9223            throw new SecurityException("Requires permission "
9224                    + android.Manifest.permission.FILTER_EVENTS);
9225        }
9226
9227        final String annotation;
9228        if (reason == null) {
9229            annotation = "Input dispatching timed out";
9230        } else {
9231            annotation = "Input dispatching timed out (" + reason + ")";
9232        }
9233
9234        if (proc != null) {
9235            synchronized (this) {
9236                if (proc.debugging) {
9237                    return false;
9238                }
9239
9240                if (mDidDexOpt) {
9241                    // Give more time since we were dexopting.
9242                    mDidDexOpt = false;
9243                    return false;
9244                }
9245
9246                if (proc.instrumentationClass != null) {
9247                    Bundle info = new Bundle();
9248                    info.putString("shortMsg", "keyDispatchingTimedOut");
9249                    info.putString("longMsg", annotation);
9250                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9251                    return true;
9252                }
9253            }
9254            mHandler.post(new Runnable() {
9255                @Override
9256                public void run() {
9257                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9258                }
9259            });
9260        }
9261
9262        return true;
9263    }
9264
9265    public Bundle getAssistContextExtras(int requestType) {
9266        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9267                "getAssistContextExtras()");
9268        PendingAssistExtras pae;
9269        Bundle extras = new Bundle();
9270        synchronized (this) {
9271            ActivityRecord activity = getFocusedStack().mResumedActivity;
9272            if (activity == null) {
9273                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9274                return null;
9275            }
9276            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9277            if (activity.app == null || activity.app.thread == null) {
9278                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9279                return extras;
9280            }
9281            if (activity.app.pid == Binder.getCallingPid()) {
9282                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9283                return extras;
9284            }
9285            pae = new PendingAssistExtras(activity);
9286            try {
9287                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9288                        requestType);
9289                mPendingAssistExtras.add(pae);
9290                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9291            } catch (RemoteException e) {
9292                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9293                return extras;
9294            }
9295        }
9296        synchronized (pae) {
9297            while (!pae.haveResult) {
9298                try {
9299                    pae.wait();
9300                } catch (InterruptedException e) {
9301                }
9302            }
9303            if (pae.result != null) {
9304                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9305            }
9306        }
9307        synchronized (this) {
9308            mPendingAssistExtras.remove(pae);
9309            mHandler.removeCallbacks(pae);
9310        }
9311        return extras;
9312    }
9313
9314    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9315        PendingAssistExtras pae = (PendingAssistExtras)token;
9316        synchronized (pae) {
9317            pae.result = extras;
9318            pae.haveResult = true;
9319            pae.notifyAll();
9320        }
9321    }
9322
9323    public void registerProcessObserver(IProcessObserver observer) {
9324        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9325                "registerProcessObserver()");
9326        synchronized (this) {
9327            mProcessObservers.register(observer);
9328        }
9329    }
9330
9331    @Override
9332    public void unregisterProcessObserver(IProcessObserver observer) {
9333        synchronized (this) {
9334            mProcessObservers.unregister(observer);
9335        }
9336    }
9337
9338    @Override
9339    public boolean convertFromTranslucent(IBinder token) {
9340        final long origId = Binder.clearCallingIdentity();
9341        try {
9342            synchronized (this) {
9343                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9344                if (r == null) {
9345                    return false;
9346                }
9347                if (r.changeWindowTranslucency(true)) {
9348                    mWindowManager.setAppFullscreen(token, true);
9349                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9350                    return true;
9351                }
9352                return false;
9353            }
9354        } finally {
9355            Binder.restoreCallingIdentity(origId);
9356        }
9357    }
9358
9359    @Override
9360    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9361        final long origId = Binder.clearCallingIdentity();
9362        try {
9363            synchronized (this) {
9364                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9365                if (r == null) {
9366                    return false;
9367                }
9368                if (r.changeWindowTranslucency(false)) {
9369                    r.task.stack.convertToTranslucent(r, options);
9370                    mWindowManager.setAppFullscreen(token, false);
9371                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9372                    return true;
9373                }
9374                return false;
9375            }
9376        } finally {
9377            Binder.restoreCallingIdentity(origId);
9378        }
9379    }
9380
9381    @Override
9382    public ActivityOptions getActivityOptions(IBinder token) {
9383        final long origId = Binder.clearCallingIdentity();
9384        try {
9385            synchronized (this) {
9386                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9387                if (r != null) {
9388                    final ActivityOptions activityOptions = r.pendingOptions;
9389                    r.pendingOptions = null;
9390                    return activityOptions;
9391                }
9392                return null;
9393            }
9394        } finally {
9395            Binder.restoreCallingIdentity(origId);
9396        }
9397    }
9398
9399    @Override
9400    public void setImmersive(IBinder token, boolean immersive) {
9401        synchronized(this) {
9402            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9403            if (r == null) {
9404                throw new IllegalArgumentException();
9405            }
9406            r.immersive = immersive;
9407
9408            // update associated state if we're frontmost
9409            if (r == mFocusedActivity) {
9410                if (DEBUG_IMMERSIVE) {
9411                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9412                }
9413                applyUpdateLockStateLocked(r);
9414            }
9415        }
9416    }
9417
9418    @Override
9419    public boolean isImmersive(IBinder token) {
9420        synchronized (this) {
9421            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9422            if (r == null) {
9423                throw new IllegalArgumentException();
9424            }
9425            return r.immersive;
9426        }
9427    }
9428
9429    public boolean isTopActivityImmersive() {
9430        enforceNotIsolatedCaller("startActivity");
9431        synchronized (this) {
9432            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9433            return (r != null) ? r.immersive : false;
9434        }
9435    }
9436
9437    public final void enterSafeMode() {
9438        synchronized(this) {
9439            // It only makes sense to do this before the system is ready
9440            // and started launching other packages.
9441            if (!mSystemReady) {
9442                try {
9443                    AppGlobals.getPackageManager().enterSafeMode();
9444                } catch (RemoteException e) {
9445                }
9446            }
9447
9448            mSafeMode = true;
9449        }
9450    }
9451
9452    public final void showSafeModeOverlay() {
9453        View v = LayoutInflater.from(mContext).inflate(
9454                com.android.internal.R.layout.safe_mode, null);
9455        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9456        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9457        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9458        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9459        lp.gravity = Gravity.BOTTOM | Gravity.START;
9460        lp.format = v.getBackground().getOpacity();
9461        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9462                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9463        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9464        ((WindowManager)mContext.getSystemService(
9465                Context.WINDOW_SERVICE)).addView(v, lp);
9466    }
9467
9468    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9469        if (!(sender instanceof PendingIntentRecord)) {
9470            return;
9471        }
9472        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9473        synchronized (stats) {
9474            if (mBatteryStatsService.isOnBattery()) {
9475                mBatteryStatsService.enforceCallingPermission();
9476                PendingIntentRecord rec = (PendingIntentRecord)sender;
9477                int MY_UID = Binder.getCallingUid();
9478                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9479                BatteryStatsImpl.Uid.Pkg pkg =
9480                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9481                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9482                pkg.incWakeupsLocked();
9483            }
9484        }
9485    }
9486
9487    public boolean killPids(int[] pids, String pReason, boolean secure) {
9488        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9489            throw new SecurityException("killPids only available to the system");
9490        }
9491        String reason = (pReason == null) ? "Unknown" : pReason;
9492        // XXX Note: don't acquire main activity lock here, because the window
9493        // manager calls in with its locks held.
9494
9495        boolean killed = false;
9496        synchronized (mPidsSelfLocked) {
9497            int[] types = new int[pids.length];
9498            int worstType = 0;
9499            for (int i=0; i<pids.length; i++) {
9500                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9501                if (proc != null) {
9502                    int type = proc.setAdj;
9503                    types[i] = type;
9504                    if (type > worstType) {
9505                        worstType = type;
9506                    }
9507                }
9508            }
9509
9510            // If the worst oom_adj is somewhere in the cached proc LRU range,
9511            // then constrain it so we will kill all cached procs.
9512            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9513                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9514                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9515            }
9516
9517            // If this is not a secure call, don't let it kill processes that
9518            // are important.
9519            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9520                worstType = ProcessList.SERVICE_ADJ;
9521            }
9522
9523            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9524            for (int i=0; i<pids.length; i++) {
9525                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9526                if (proc == null) {
9527                    continue;
9528                }
9529                int adj = proc.setAdj;
9530                if (adj >= worstType && !proc.killedByAm) {
9531                    killUnneededProcessLocked(proc, reason);
9532                    killed = true;
9533                }
9534            }
9535        }
9536        return killed;
9537    }
9538
9539    @Override
9540    public void killUid(int uid, String reason) {
9541        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9542            throw new SecurityException("killUid only available to the system");
9543        }
9544        synchronized (this) {
9545            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9546                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9547                    reason != null ? reason : "kill uid");
9548        }
9549    }
9550
9551    @Override
9552    public boolean killProcessesBelowForeground(String reason) {
9553        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9554            throw new SecurityException("killProcessesBelowForeground() only available to system");
9555        }
9556
9557        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9558    }
9559
9560    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9561        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9562            throw new SecurityException("killProcessesBelowAdj() only available to system");
9563        }
9564
9565        boolean killed = false;
9566        synchronized (mPidsSelfLocked) {
9567            final int size = mPidsSelfLocked.size();
9568            for (int i = 0; i < size; i++) {
9569                final int pid = mPidsSelfLocked.keyAt(i);
9570                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9571                if (proc == null) continue;
9572
9573                final int adj = proc.setAdj;
9574                if (adj > belowAdj && !proc.killedByAm) {
9575                    killUnneededProcessLocked(proc, reason);
9576                    killed = true;
9577                }
9578            }
9579        }
9580        return killed;
9581    }
9582
9583    @Override
9584    public void hang(final IBinder who, boolean allowRestart) {
9585        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9586                != PackageManager.PERMISSION_GRANTED) {
9587            throw new SecurityException("Requires permission "
9588                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9589        }
9590
9591        final IBinder.DeathRecipient death = new DeathRecipient() {
9592            @Override
9593            public void binderDied() {
9594                synchronized (this) {
9595                    notifyAll();
9596                }
9597            }
9598        };
9599
9600        try {
9601            who.linkToDeath(death, 0);
9602        } catch (RemoteException e) {
9603            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9604            return;
9605        }
9606
9607        synchronized (this) {
9608            Watchdog.getInstance().setAllowRestart(allowRestart);
9609            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9610            synchronized (death) {
9611                while (who.isBinderAlive()) {
9612                    try {
9613                        death.wait();
9614                    } catch (InterruptedException e) {
9615                    }
9616                }
9617            }
9618            Watchdog.getInstance().setAllowRestart(true);
9619        }
9620    }
9621
9622    @Override
9623    public void restart() {
9624        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9625                != PackageManager.PERMISSION_GRANTED) {
9626            throw new SecurityException("Requires permission "
9627                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9628        }
9629
9630        Log.i(TAG, "Sending shutdown broadcast...");
9631
9632        BroadcastReceiver br = new BroadcastReceiver() {
9633            @Override public void onReceive(Context context, Intent intent) {
9634                // Now the broadcast is done, finish up the low-level shutdown.
9635                Log.i(TAG, "Shutting down activity manager...");
9636                shutdown(10000);
9637                Log.i(TAG, "Shutdown complete, restarting!");
9638                Process.killProcess(Process.myPid());
9639                System.exit(10);
9640            }
9641        };
9642
9643        // First send the high-level shut down broadcast.
9644        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9645        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9646        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9647        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9648        mContext.sendOrderedBroadcastAsUser(intent,
9649                UserHandle.ALL, null, br, mHandler, 0, null, null);
9650        */
9651        br.onReceive(mContext, intent);
9652    }
9653
9654    private long getLowRamTimeSinceIdle(long now) {
9655        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9656    }
9657
9658    @Override
9659    public void performIdleMaintenance() {
9660        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9661                != PackageManager.PERMISSION_GRANTED) {
9662            throw new SecurityException("Requires permission "
9663                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9664        }
9665
9666        synchronized (this) {
9667            final long now = SystemClock.uptimeMillis();
9668            final long timeSinceLastIdle = now - mLastIdleTime;
9669            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9670            mLastIdleTime = now;
9671            mLowRamTimeSinceLastIdle = 0;
9672            if (mLowRamStartTime != 0) {
9673                mLowRamStartTime = now;
9674            }
9675
9676            StringBuilder sb = new StringBuilder(128);
9677            sb.append("Idle maintenance over ");
9678            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9679            sb.append(" low RAM for ");
9680            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9681            Slog.i(TAG, sb.toString());
9682
9683            // If at least 1/3 of our time since the last idle period has been spent
9684            // with RAM low, then we want to kill processes.
9685            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9686
9687            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9688                ProcessRecord proc = mLruProcesses.get(i);
9689                if (proc.notCachedSinceIdle) {
9690                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9691                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9692                        if (doKilling && proc.initialIdlePss != 0
9693                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9694                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9695                                    + " from " + proc.initialIdlePss + ")");
9696                        }
9697                    }
9698                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9699                    proc.notCachedSinceIdle = true;
9700                    proc.initialIdlePss = 0;
9701                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9702                            isSleeping(), now);
9703                }
9704            }
9705
9706            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9707            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9708        }
9709    }
9710
9711    private void retrieveSettings() {
9712        final ContentResolver resolver = mContext.getContentResolver();
9713        String debugApp = Settings.Global.getString(
9714            resolver, Settings.Global.DEBUG_APP);
9715        boolean waitForDebugger = Settings.Global.getInt(
9716            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9717        boolean alwaysFinishActivities = Settings.Global.getInt(
9718            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9719        boolean forceRtl = Settings.Global.getInt(
9720                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9721        // Transfer any global setting for forcing RTL layout, into a System Property
9722        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9723
9724        Configuration configuration = new Configuration();
9725        Settings.System.getConfiguration(resolver, configuration);
9726        if (forceRtl) {
9727            // This will take care of setting the correct layout direction flags
9728            configuration.setLayoutDirection(configuration.locale);
9729        }
9730
9731        synchronized (this) {
9732            mDebugApp = mOrigDebugApp = debugApp;
9733            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9734            mAlwaysFinishActivities = alwaysFinishActivities;
9735            // This happens before any activities are started, so we can
9736            // change mConfiguration in-place.
9737            updateConfigurationLocked(configuration, null, false, true);
9738            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9739        }
9740    }
9741
9742    public boolean testIsSystemReady() {
9743        // no need to synchronize(this) just to read & return the value
9744        return mSystemReady;
9745    }
9746
9747    private static File getCalledPreBootReceiversFile() {
9748        File dataDir = Environment.getDataDirectory();
9749        File systemDir = new File(dataDir, "system");
9750        File fname = new File(systemDir, "called_pre_boots.dat");
9751        return fname;
9752    }
9753
9754    static final int LAST_DONE_VERSION = 10000;
9755
9756    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9757        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9758        File file = getCalledPreBootReceiversFile();
9759        FileInputStream fis = null;
9760        try {
9761            fis = new FileInputStream(file);
9762            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9763            int fvers = dis.readInt();
9764            if (fvers == LAST_DONE_VERSION) {
9765                String vers = dis.readUTF();
9766                String codename = dis.readUTF();
9767                String build = dis.readUTF();
9768                if (android.os.Build.VERSION.RELEASE.equals(vers)
9769                        && android.os.Build.VERSION.CODENAME.equals(codename)
9770                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9771                    int num = dis.readInt();
9772                    while (num > 0) {
9773                        num--;
9774                        String pkg = dis.readUTF();
9775                        String cls = dis.readUTF();
9776                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9777                    }
9778                }
9779            }
9780        } catch (FileNotFoundException e) {
9781        } catch (IOException e) {
9782            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9783        } finally {
9784            if (fis != null) {
9785                try {
9786                    fis.close();
9787                } catch (IOException e) {
9788                }
9789            }
9790        }
9791        return lastDoneReceivers;
9792    }
9793
9794    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9795        File file = getCalledPreBootReceiversFile();
9796        FileOutputStream fos = null;
9797        DataOutputStream dos = null;
9798        try {
9799            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9800            fos = new FileOutputStream(file);
9801            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9802            dos.writeInt(LAST_DONE_VERSION);
9803            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9804            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9805            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9806            dos.writeInt(list.size());
9807            for (int i=0; i<list.size(); i++) {
9808                dos.writeUTF(list.get(i).getPackageName());
9809                dos.writeUTF(list.get(i).getClassName());
9810            }
9811        } catch (IOException e) {
9812            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9813            file.delete();
9814        } finally {
9815            FileUtils.sync(fos);
9816            if (dos != null) {
9817                try {
9818                    dos.close();
9819                } catch (IOException e) {
9820                    // TODO Auto-generated catch block
9821                    e.printStackTrace();
9822                }
9823            }
9824        }
9825    }
9826
9827    public void systemReady(final Runnable goingCallback) {
9828        synchronized(this) {
9829            if (mSystemReady) {
9830                if (goingCallback != null) goingCallback.run();
9831                return;
9832            }
9833
9834            if (mRecentTasks == null) {
9835                mRecentTasks = mTaskPersister.restoreTasksLocked();
9836                if (!mRecentTasks.isEmpty()) {
9837                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9838                }
9839                mTaskPersister.startPersisting();
9840            }
9841
9842            // Check to see if there are any update receivers to run.
9843            if (!mDidUpdate) {
9844                if (mWaitingUpdate) {
9845                    return;
9846                }
9847                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9848                List<ResolveInfo> ris = null;
9849                try {
9850                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9851                            intent, null, 0, 0);
9852                } catch (RemoteException e) {
9853                }
9854                if (ris != null) {
9855                    for (int i=ris.size()-1; i>=0; i--) {
9856                        if ((ris.get(i).activityInfo.applicationInfo.flags
9857                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9858                            ris.remove(i);
9859                        }
9860                    }
9861                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9862
9863                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9864
9865                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9866                    for (int i=0; i<ris.size(); i++) {
9867                        ActivityInfo ai = ris.get(i).activityInfo;
9868                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9869                        if (lastDoneReceivers.contains(comp)) {
9870                            // We already did the pre boot receiver for this app with the current
9871                            // platform version, so don't do it again...
9872                            ris.remove(i);
9873                            i--;
9874                            // ...however, do keep it as one that has been done, so we don't
9875                            // forget about it when rewriting the file of last done receivers.
9876                            doneReceivers.add(comp);
9877                        }
9878                    }
9879
9880                    final int[] users = getUsersLocked();
9881                    for (int i=0; i<ris.size(); i++) {
9882                        ActivityInfo ai = ris.get(i).activityInfo;
9883                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9884                        doneReceivers.add(comp);
9885                        intent.setComponent(comp);
9886                        for (int j=0; j<users.length; j++) {
9887                            IIntentReceiver finisher = null;
9888                            if (i == ris.size()-1 && j == users.length-1) {
9889                                finisher = new IIntentReceiver.Stub() {
9890                                    public void performReceive(Intent intent, int resultCode,
9891                                            String data, Bundle extras, boolean ordered,
9892                                            boolean sticky, int sendingUser) {
9893                                        // The raw IIntentReceiver interface is called
9894                                        // with the AM lock held, so redispatch to
9895                                        // execute our code without the lock.
9896                                        mHandler.post(new Runnable() {
9897                                            public void run() {
9898                                                synchronized (ActivityManagerService.this) {
9899                                                    mDidUpdate = true;
9900                                                }
9901                                                writeLastDonePreBootReceivers(doneReceivers);
9902                                                showBootMessage(mContext.getText(
9903                                                        R.string.android_upgrading_complete),
9904                                                        false);
9905                                                systemReady(goingCallback);
9906                                            }
9907                                        });
9908                                    }
9909                                };
9910                            }
9911                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9912                                    + " for user " + users[j]);
9913                            broadcastIntentLocked(null, null, intent, null, finisher,
9914                                    0, null, null, null, AppOpsManager.OP_NONE,
9915                                    true, false, MY_PID, Process.SYSTEM_UID,
9916                                    users[j]);
9917                            if (finisher != null) {
9918                                mWaitingUpdate = true;
9919                            }
9920                        }
9921                    }
9922                }
9923                if (mWaitingUpdate) {
9924                    return;
9925                }
9926                mDidUpdate = true;
9927            }
9928
9929            mAppOpsService.systemReady();
9930            mUsageStatsService.systemReady();
9931            mSystemReady = true;
9932        }
9933
9934        ArrayList<ProcessRecord> procsToKill = null;
9935        synchronized(mPidsSelfLocked) {
9936            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9937                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9938                if (!isAllowedWhileBooting(proc.info)){
9939                    if (procsToKill == null) {
9940                        procsToKill = new ArrayList<ProcessRecord>();
9941                    }
9942                    procsToKill.add(proc);
9943                }
9944            }
9945        }
9946
9947        synchronized(this) {
9948            if (procsToKill != null) {
9949                for (int i=procsToKill.size()-1; i>=0; i--) {
9950                    ProcessRecord proc = procsToKill.get(i);
9951                    Slog.i(TAG, "Removing system update proc: " + proc);
9952                    removeProcessLocked(proc, true, false, "system update done");
9953                }
9954            }
9955
9956            // Now that we have cleaned up any update processes, we
9957            // are ready to start launching real processes and know that
9958            // we won't trample on them any more.
9959            mProcessesReady = true;
9960        }
9961
9962        Slog.i(TAG, "System now ready");
9963        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9964            SystemClock.uptimeMillis());
9965
9966        synchronized(this) {
9967            // Make sure we have no pre-ready processes sitting around.
9968
9969            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9970                ResolveInfo ri = mContext.getPackageManager()
9971                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9972                                STOCK_PM_FLAGS);
9973                CharSequence errorMsg = null;
9974                if (ri != null) {
9975                    ActivityInfo ai = ri.activityInfo;
9976                    ApplicationInfo app = ai.applicationInfo;
9977                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9978                        mTopAction = Intent.ACTION_FACTORY_TEST;
9979                        mTopData = null;
9980                        mTopComponent = new ComponentName(app.packageName,
9981                                ai.name);
9982                    } else {
9983                        errorMsg = mContext.getResources().getText(
9984                                com.android.internal.R.string.factorytest_not_system);
9985                    }
9986                } else {
9987                    errorMsg = mContext.getResources().getText(
9988                            com.android.internal.R.string.factorytest_no_action);
9989                }
9990                if (errorMsg != null) {
9991                    mTopAction = null;
9992                    mTopData = null;
9993                    mTopComponent = null;
9994                    Message msg = Message.obtain();
9995                    msg.what = SHOW_FACTORY_ERROR_MSG;
9996                    msg.getData().putCharSequence("msg", errorMsg);
9997                    mHandler.sendMessage(msg);
9998                }
9999            }
10000        }
10001
10002        retrieveSettings();
10003
10004        synchronized (this) {
10005            readGrantedUriPermissionsLocked();
10006        }
10007
10008        if (goingCallback != null) goingCallback.run();
10009
10010        mSystemServiceManager.startUser(mCurrentUserId);
10011
10012        synchronized (this) {
10013            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10014                try {
10015                    List apps = AppGlobals.getPackageManager().
10016                        getPersistentApplications(STOCK_PM_FLAGS);
10017                    if (apps != null) {
10018                        int N = apps.size();
10019                        int i;
10020                        for (i=0; i<N; i++) {
10021                            ApplicationInfo info
10022                                = (ApplicationInfo)apps.get(i);
10023                            if (info != null &&
10024                                    !info.packageName.equals("android")) {
10025                                addAppLocked(info, false, null /* ABI override */);
10026                            }
10027                        }
10028                    }
10029                } catch (RemoteException ex) {
10030                    // pm is in same process, this will never happen.
10031                }
10032            }
10033
10034            // Start up initial activity.
10035            mBooting = true;
10036
10037            try {
10038                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10039                    Message msg = Message.obtain();
10040                    msg.what = SHOW_UID_ERROR_MSG;
10041                    mHandler.sendMessage(msg);
10042                }
10043            } catch (RemoteException e) {
10044            }
10045
10046            long ident = Binder.clearCallingIdentity();
10047            try {
10048                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10049                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10050                        | Intent.FLAG_RECEIVER_FOREGROUND);
10051                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10052                broadcastIntentLocked(null, null, intent,
10053                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10054                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10055                intent = new Intent(Intent.ACTION_USER_STARTING);
10056                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10057                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10058                broadcastIntentLocked(null, null, intent,
10059                        null, new IIntentReceiver.Stub() {
10060                            @Override
10061                            public void performReceive(Intent intent, int resultCode, String data,
10062                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10063                                    throws RemoteException {
10064                            }
10065                        }, 0, null, null,
10066                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10067                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10068            } catch (Throwable t) {
10069                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10070            } finally {
10071                Binder.restoreCallingIdentity(ident);
10072            }
10073            mStackSupervisor.resumeTopActivitiesLocked();
10074            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10075        }
10076    }
10077
10078    private boolean makeAppCrashingLocked(ProcessRecord app,
10079            String shortMsg, String longMsg, String stackTrace) {
10080        app.crashing = true;
10081        app.crashingReport = generateProcessError(app,
10082                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10083        startAppProblemLocked(app);
10084        app.stopFreezingAllLocked();
10085        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10086    }
10087
10088    private void makeAppNotRespondingLocked(ProcessRecord app,
10089            String activity, String shortMsg, String longMsg) {
10090        app.notResponding = true;
10091        app.notRespondingReport = generateProcessError(app,
10092                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10093                activity, shortMsg, longMsg, null);
10094        startAppProblemLocked(app);
10095        app.stopFreezingAllLocked();
10096    }
10097
10098    /**
10099     * Generate a process error record, suitable for attachment to a ProcessRecord.
10100     *
10101     * @param app The ProcessRecord in which the error occurred.
10102     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10103     *                      ActivityManager.AppErrorStateInfo
10104     * @param activity The activity associated with the crash, if known.
10105     * @param shortMsg Short message describing the crash.
10106     * @param longMsg Long message describing the crash.
10107     * @param stackTrace Full crash stack trace, may be null.
10108     *
10109     * @return Returns a fully-formed AppErrorStateInfo record.
10110     */
10111    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10112            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10113        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10114
10115        report.condition = condition;
10116        report.processName = app.processName;
10117        report.pid = app.pid;
10118        report.uid = app.info.uid;
10119        report.tag = activity;
10120        report.shortMsg = shortMsg;
10121        report.longMsg = longMsg;
10122        report.stackTrace = stackTrace;
10123
10124        return report;
10125    }
10126
10127    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10128        synchronized (this) {
10129            app.crashing = false;
10130            app.crashingReport = null;
10131            app.notResponding = false;
10132            app.notRespondingReport = null;
10133            if (app.anrDialog == fromDialog) {
10134                app.anrDialog = null;
10135            }
10136            if (app.waitDialog == fromDialog) {
10137                app.waitDialog = null;
10138            }
10139            if (app.pid > 0 && app.pid != MY_PID) {
10140                handleAppCrashLocked(app, null, null, null);
10141                killUnneededProcessLocked(app, "user request after error");
10142            }
10143        }
10144    }
10145
10146    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10147            String stackTrace) {
10148        long now = SystemClock.uptimeMillis();
10149
10150        Long crashTime;
10151        if (!app.isolated) {
10152            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10153        } else {
10154            crashTime = null;
10155        }
10156        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10157            // This process loses!
10158            Slog.w(TAG, "Process " + app.info.processName
10159                    + " has crashed too many times: killing!");
10160            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10161                    app.userId, app.info.processName, app.uid);
10162            mStackSupervisor.handleAppCrashLocked(app);
10163            if (!app.persistent) {
10164                // We don't want to start this process again until the user
10165                // explicitly does so...  but for persistent process, we really
10166                // need to keep it running.  If a persistent process is actually
10167                // repeatedly crashing, then badness for everyone.
10168                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10169                        app.info.processName);
10170                if (!app.isolated) {
10171                    // XXX We don't have a way to mark isolated processes
10172                    // as bad, since they don't have a peristent identity.
10173                    mBadProcesses.put(app.info.processName, app.uid,
10174                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10175                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10176                }
10177                app.bad = true;
10178                app.removed = true;
10179                // Don't let services in this process be restarted and potentially
10180                // annoy the user repeatedly.  Unless it is persistent, since those
10181                // processes run critical code.
10182                removeProcessLocked(app, false, false, "crash");
10183                mStackSupervisor.resumeTopActivitiesLocked();
10184                return false;
10185            }
10186            mStackSupervisor.resumeTopActivitiesLocked();
10187        } else {
10188            mStackSupervisor.finishTopRunningActivityLocked(app);
10189        }
10190
10191        // Bump up the crash count of any services currently running in the proc.
10192        for (int i=app.services.size()-1; i>=0; i--) {
10193            // Any services running in the application need to be placed
10194            // back in the pending list.
10195            ServiceRecord sr = app.services.valueAt(i);
10196            sr.crashCount++;
10197        }
10198
10199        // If the crashing process is what we consider to be the "home process" and it has been
10200        // replaced by a third-party app, clear the package preferred activities from packages
10201        // with a home activity running in the process to prevent a repeatedly crashing app
10202        // from blocking the user to manually clear the list.
10203        final ArrayList<ActivityRecord> activities = app.activities;
10204        if (app == mHomeProcess && activities.size() > 0
10205                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10206            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10207                final ActivityRecord r = activities.get(activityNdx);
10208                if (r.isHomeActivity()) {
10209                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10210                    try {
10211                        ActivityThread.getPackageManager()
10212                                .clearPackagePreferredActivities(r.packageName);
10213                    } catch (RemoteException c) {
10214                        // pm is in same process, this will never happen.
10215                    }
10216                }
10217            }
10218        }
10219
10220        if (!app.isolated) {
10221            // XXX Can't keep track of crash times for isolated processes,
10222            // because they don't have a perisistent identity.
10223            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10224        }
10225
10226        return true;
10227    }
10228
10229    void startAppProblemLocked(ProcessRecord app) {
10230        if (app.userId == mCurrentUserId) {
10231            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10232                    mContext, app.info.packageName, app.info.flags);
10233        } else {
10234            // If this app is not running under the current user, then we
10235            // can't give it a report button because that would require
10236            // launching the report UI under a different user.
10237            app.errorReportReceiver = null;
10238        }
10239        skipCurrentReceiverLocked(app);
10240    }
10241
10242    void skipCurrentReceiverLocked(ProcessRecord app) {
10243        for (BroadcastQueue queue : mBroadcastQueues) {
10244            queue.skipCurrentReceiverLocked(app);
10245        }
10246    }
10247
10248    /**
10249     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10250     * The application process will exit immediately after this call returns.
10251     * @param app object of the crashing app, null for the system server
10252     * @param crashInfo describing the exception
10253     */
10254    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10255        ProcessRecord r = findAppProcess(app, "Crash");
10256        final String processName = app == null ? "system_server"
10257                : (r == null ? "unknown" : r.processName);
10258
10259        handleApplicationCrashInner("crash", r, processName, crashInfo);
10260    }
10261
10262    /* Native crash reporting uses this inner version because it needs to be somewhat
10263     * decoupled from the AM-managed cleanup lifecycle
10264     */
10265    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10266            ApplicationErrorReport.CrashInfo crashInfo) {
10267        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10268                UserHandle.getUserId(Binder.getCallingUid()), processName,
10269                r == null ? -1 : r.info.flags,
10270                crashInfo.exceptionClassName,
10271                crashInfo.exceptionMessage,
10272                crashInfo.throwFileName,
10273                crashInfo.throwLineNumber);
10274
10275        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10276
10277        crashApplication(r, crashInfo);
10278    }
10279
10280    public void handleApplicationStrictModeViolation(
10281            IBinder app,
10282            int violationMask,
10283            StrictMode.ViolationInfo info) {
10284        ProcessRecord r = findAppProcess(app, "StrictMode");
10285        if (r == null) {
10286            return;
10287        }
10288
10289        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10290            Integer stackFingerprint = info.hashCode();
10291            boolean logIt = true;
10292            synchronized (mAlreadyLoggedViolatedStacks) {
10293                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10294                    logIt = false;
10295                    // TODO: sub-sample into EventLog for these, with
10296                    // the info.durationMillis?  Then we'd get
10297                    // the relative pain numbers, without logging all
10298                    // the stack traces repeatedly.  We'd want to do
10299                    // likewise in the client code, which also does
10300                    // dup suppression, before the Binder call.
10301                } else {
10302                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10303                        mAlreadyLoggedViolatedStacks.clear();
10304                    }
10305                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10306                }
10307            }
10308            if (logIt) {
10309                logStrictModeViolationToDropBox(r, info);
10310            }
10311        }
10312
10313        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10314            AppErrorResult result = new AppErrorResult();
10315            synchronized (this) {
10316                final long origId = Binder.clearCallingIdentity();
10317
10318                Message msg = Message.obtain();
10319                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10320                HashMap<String, Object> data = new HashMap<String, Object>();
10321                data.put("result", result);
10322                data.put("app", r);
10323                data.put("violationMask", violationMask);
10324                data.put("info", info);
10325                msg.obj = data;
10326                mHandler.sendMessage(msg);
10327
10328                Binder.restoreCallingIdentity(origId);
10329            }
10330            int res = result.get();
10331            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10332        }
10333    }
10334
10335    // Depending on the policy in effect, there could be a bunch of
10336    // these in quick succession so we try to batch these together to
10337    // minimize disk writes, number of dropbox entries, and maximize
10338    // compression, by having more fewer, larger records.
10339    private void logStrictModeViolationToDropBox(
10340            ProcessRecord process,
10341            StrictMode.ViolationInfo info) {
10342        if (info == null) {
10343            return;
10344        }
10345        final boolean isSystemApp = process == null ||
10346                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10347                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10348        final String processName = process == null ? "unknown" : process.processName;
10349        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10350        final DropBoxManager dbox = (DropBoxManager)
10351                mContext.getSystemService(Context.DROPBOX_SERVICE);
10352
10353        // Exit early if the dropbox isn't configured to accept this report type.
10354        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10355
10356        boolean bufferWasEmpty;
10357        boolean needsFlush;
10358        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10359        synchronized (sb) {
10360            bufferWasEmpty = sb.length() == 0;
10361            appendDropBoxProcessHeaders(process, processName, sb);
10362            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10363            sb.append("System-App: ").append(isSystemApp).append("\n");
10364            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10365            if (info.violationNumThisLoop != 0) {
10366                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10367            }
10368            if (info.numAnimationsRunning != 0) {
10369                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10370            }
10371            if (info.broadcastIntentAction != null) {
10372                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10373            }
10374            if (info.durationMillis != -1) {
10375                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10376            }
10377            if (info.numInstances != -1) {
10378                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10379            }
10380            if (info.tags != null) {
10381                for (String tag : info.tags) {
10382                    sb.append("Span-Tag: ").append(tag).append("\n");
10383                }
10384            }
10385            sb.append("\n");
10386            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10387                sb.append(info.crashInfo.stackTrace);
10388            }
10389            sb.append("\n");
10390
10391            // Only buffer up to ~64k.  Various logging bits truncate
10392            // things at 128k.
10393            needsFlush = (sb.length() > 64 * 1024);
10394        }
10395
10396        // Flush immediately if the buffer's grown too large, or this
10397        // is a non-system app.  Non-system apps are isolated with a
10398        // different tag & policy and not batched.
10399        //
10400        // Batching is useful during internal testing with
10401        // StrictMode settings turned up high.  Without batching,
10402        // thousands of separate files could be created on boot.
10403        if (!isSystemApp || needsFlush) {
10404            new Thread("Error dump: " + dropboxTag) {
10405                @Override
10406                public void run() {
10407                    String report;
10408                    synchronized (sb) {
10409                        report = sb.toString();
10410                        sb.delete(0, sb.length());
10411                        sb.trimToSize();
10412                    }
10413                    if (report.length() != 0) {
10414                        dbox.addText(dropboxTag, report);
10415                    }
10416                }
10417            }.start();
10418            return;
10419        }
10420
10421        // System app batching:
10422        if (!bufferWasEmpty) {
10423            // An existing dropbox-writing thread is outstanding, so
10424            // we don't need to start it up.  The existing thread will
10425            // catch the buffer appends we just did.
10426            return;
10427        }
10428
10429        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10430        // (After this point, we shouldn't access AMS internal data structures.)
10431        new Thread("Error dump: " + dropboxTag) {
10432            @Override
10433            public void run() {
10434                // 5 second sleep to let stacks arrive and be batched together
10435                try {
10436                    Thread.sleep(5000);  // 5 seconds
10437                } catch (InterruptedException e) {}
10438
10439                String errorReport;
10440                synchronized (mStrictModeBuffer) {
10441                    errorReport = mStrictModeBuffer.toString();
10442                    if (errorReport.length() == 0) {
10443                        return;
10444                    }
10445                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10446                    mStrictModeBuffer.trimToSize();
10447                }
10448                dbox.addText(dropboxTag, errorReport);
10449            }
10450        }.start();
10451    }
10452
10453    /**
10454     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10455     * @param app object of the crashing app, null for the system server
10456     * @param tag reported by the caller
10457     * @param crashInfo describing the context of the error
10458     * @return true if the process should exit immediately (WTF is fatal)
10459     */
10460    public boolean handleApplicationWtf(IBinder app, String tag,
10461            ApplicationErrorReport.CrashInfo crashInfo) {
10462        ProcessRecord r = findAppProcess(app, "WTF");
10463        final String processName = app == null ? "system_server"
10464                : (r == null ? "unknown" : r.processName);
10465
10466        EventLog.writeEvent(EventLogTags.AM_WTF,
10467                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10468                processName,
10469                r == null ? -1 : r.info.flags,
10470                tag, crashInfo.exceptionMessage);
10471
10472        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10473
10474        if (r != null && r.pid != Process.myPid() &&
10475                Settings.Global.getInt(mContext.getContentResolver(),
10476                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10477            crashApplication(r, crashInfo);
10478            return true;
10479        } else {
10480            return false;
10481        }
10482    }
10483
10484    /**
10485     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10486     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10487     */
10488    private ProcessRecord findAppProcess(IBinder app, String reason) {
10489        if (app == null) {
10490            return null;
10491        }
10492
10493        synchronized (this) {
10494            final int NP = mProcessNames.getMap().size();
10495            for (int ip=0; ip<NP; ip++) {
10496                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10497                final int NA = apps.size();
10498                for (int ia=0; ia<NA; ia++) {
10499                    ProcessRecord p = apps.valueAt(ia);
10500                    if (p.thread != null && p.thread.asBinder() == app) {
10501                        return p;
10502                    }
10503                }
10504            }
10505
10506            Slog.w(TAG, "Can't find mystery application for " + reason
10507                    + " from pid=" + Binder.getCallingPid()
10508                    + " uid=" + Binder.getCallingUid() + ": " + app);
10509            return null;
10510        }
10511    }
10512
10513    /**
10514     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10515     * to append various headers to the dropbox log text.
10516     */
10517    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10518            StringBuilder sb) {
10519        // Watchdog thread ends up invoking this function (with
10520        // a null ProcessRecord) to add the stack file to dropbox.
10521        // Do not acquire a lock on this (am) in such cases, as it
10522        // could cause a potential deadlock, if and when watchdog
10523        // is invoked due to unavailability of lock on am and it
10524        // would prevent watchdog from killing system_server.
10525        if (process == null) {
10526            sb.append("Process: ").append(processName).append("\n");
10527            return;
10528        }
10529        // Note: ProcessRecord 'process' is guarded by the service
10530        // instance.  (notably process.pkgList, which could otherwise change
10531        // concurrently during execution of this method)
10532        synchronized (this) {
10533            sb.append("Process: ").append(processName).append("\n");
10534            int flags = process.info.flags;
10535            IPackageManager pm = AppGlobals.getPackageManager();
10536            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10537            for (int ip=0; ip<process.pkgList.size(); ip++) {
10538                String pkg = process.pkgList.keyAt(ip);
10539                sb.append("Package: ").append(pkg);
10540                try {
10541                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10542                    if (pi != null) {
10543                        sb.append(" v").append(pi.versionCode);
10544                        if (pi.versionName != null) {
10545                            sb.append(" (").append(pi.versionName).append(")");
10546                        }
10547                    }
10548                } catch (RemoteException e) {
10549                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10550                }
10551                sb.append("\n");
10552            }
10553        }
10554    }
10555
10556    private static String processClass(ProcessRecord process) {
10557        if (process == null || process.pid == MY_PID) {
10558            return "system_server";
10559        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10560            return "system_app";
10561        } else {
10562            return "data_app";
10563        }
10564    }
10565
10566    /**
10567     * Write a description of an error (crash, WTF, ANR) to the drop box.
10568     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10569     * @param process which caused the error, null means the system server
10570     * @param activity which triggered the error, null if unknown
10571     * @param parent activity related to the error, null if unknown
10572     * @param subject line related to the error, null if absent
10573     * @param report in long form describing the error, null if absent
10574     * @param logFile to include in the report, null if none
10575     * @param crashInfo giving an application stack trace, null if absent
10576     */
10577    public void addErrorToDropBox(String eventType,
10578            ProcessRecord process, String processName, ActivityRecord activity,
10579            ActivityRecord parent, String subject,
10580            final String report, final File logFile,
10581            final ApplicationErrorReport.CrashInfo crashInfo) {
10582        // NOTE -- this must never acquire the ActivityManagerService lock,
10583        // otherwise the watchdog may be prevented from resetting the system.
10584
10585        final String dropboxTag = processClass(process) + "_" + eventType;
10586        final DropBoxManager dbox = (DropBoxManager)
10587                mContext.getSystemService(Context.DROPBOX_SERVICE);
10588
10589        // Exit early if the dropbox isn't configured to accept this report type.
10590        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10591
10592        final StringBuilder sb = new StringBuilder(1024);
10593        appendDropBoxProcessHeaders(process, processName, sb);
10594        if (activity != null) {
10595            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10596        }
10597        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10598            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10599        }
10600        if (parent != null && parent != activity) {
10601            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10602        }
10603        if (subject != null) {
10604            sb.append("Subject: ").append(subject).append("\n");
10605        }
10606        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10607        if (Debug.isDebuggerConnected()) {
10608            sb.append("Debugger: Connected\n");
10609        }
10610        sb.append("\n");
10611
10612        // Do the rest in a worker thread to avoid blocking the caller on I/O
10613        // (After this point, we shouldn't access AMS internal data structures.)
10614        Thread worker = new Thread("Error dump: " + dropboxTag) {
10615            @Override
10616            public void run() {
10617                if (report != null) {
10618                    sb.append(report);
10619                }
10620                if (logFile != null) {
10621                    try {
10622                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10623                                    "\n\n[[TRUNCATED]]"));
10624                    } catch (IOException e) {
10625                        Slog.e(TAG, "Error reading " + logFile, e);
10626                    }
10627                }
10628                if (crashInfo != null && crashInfo.stackTrace != null) {
10629                    sb.append(crashInfo.stackTrace);
10630                }
10631
10632                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10633                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10634                if (lines > 0) {
10635                    sb.append("\n");
10636
10637                    // Merge several logcat streams, and take the last N lines
10638                    InputStreamReader input = null;
10639                    try {
10640                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10641                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10642                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10643
10644                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10645                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10646                        input = new InputStreamReader(logcat.getInputStream());
10647
10648                        int num;
10649                        char[] buf = new char[8192];
10650                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10651                    } catch (IOException e) {
10652                        Slog.e(TAG, "Error running logcat", e);
10653                    } finally {
10654                        if (input != null) try { input.close(); } catch (IOException e) {}
10655                    }
10656                }
10657
10658                dbox.addText(dropboxTag, sb.toString());
10659            }
10660        };
10661
10662        if (process == null) {
10663            // If process is null, we are being called from some internal code
10664            // and may be about to die -- run this synchronously.
10665            worker.run();
10666        } else {
10667            worker.start();
10668        }
10669    }
10670
10671    /**
10672     * Bring up the "unexpected error" dialog box for a crashing app.
10673     * Deal with edge cases (intercepts from instrumented applications,
10674     * ActivityController, error intent receivers, that sort of thing).
10675     * @param r the application crashing
10676     * @param crashInfo describing the failure
10677     */
10678    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10679        long timeMillis = System.currentTimeMillis();
10680        String shortMsg = crashInfo.exceptionClassName;
10681        String longMsg = crashInfo.exceptionMessage;
10682        String stackTrace = crashInfo.stackTrace;
10683        if (shortMsg != null && longMsg != null) {
10684            longMsg = shortMsg + ": " + longMsg;
10685        } else if (shortMsg != null) {
10686            longMsg = shortMsg;
10687        }
10688
10689        AppErrorResult result = new AppErrorResult();
10690        synchronized (this) {
10691            if (mController != null) {
10692                try {
10693                    String name = r != null ? r.processName : null;
10694                    int pid = r != null ? r.pid : Binder.getCallingPid();
10695                    if (!mController.appCrashed(name, pid,
10696                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10697                        Slog.w(TAG, "Force-killing crashed app " + name
10698                                + " at watcher's request");
10699                        Process.killProcess(pid);
10700                        return;
10701                    }
10702                } catch (RemoteException e) {
10703                    mController = null;
10704                    Watchdog.getInstance().setActivityController(null);
10705                }
10706            }
10707
10708            final long origId = Binder.clearCallingIdentity();
10709
10710            // If this process is running instrumentation, finish it.
10711            if (r != null && r.instrumentationClass != null) {
10712                Slog.w(TAG, "Error in app " + r.processName
10713                      + " running instrumentation " + r.instrumentationClass + ":");
10714                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10715                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10716                Bundle info = new Bundle();
10717                info.putString("shortMsg", shortMsg);
10718                info.putString("longMsg", longMsg);
10719                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10720                Binder.restoreCallingIdentity(origId);
10721                return;
10722            }
10723
10724            // If we can't identify the process or it's already exceeded its crash quota,
10725            // quit right away without showing a crash dialog.
10726            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10727                Binder.restoreCallingIdentity(origId);
10728                return;
10729            }
10730
10731            Message msg = Message.obtain();
10732            msg.what = SHOW_ERROR_MSG;
10733            HashMap data = new HashMap();
10734            data.put("result", result);
10735            data.put("app", r);
10736            msg.obj = data;
10737            mHandler.sendMessage(msg);
10738
10739            Binder.restoreCallingIdentity(origId);
10740        }
10741
10742        int res = result.get();
10743
10744        Intent appErrorIntent = null;
10745        synchronized (this) {
10746            if (r != null && !r.isolated) {
10747                // XXX Can't keep track of crash time for isolated processes,
10748                // since they don't have a persistent identity.
10749                mProcessCrashTimes.put(r.info.processName, r.uid,
10750                        SystemClock.uptimeMillis());
10751            }
10752            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10753                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10754            }
10755        }
10756
10757        if (appErrorIntent != null) {
10758            try {
10759                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10760            } catch (ActivityNotFoundException e) {
10761                Slog.w(TAG, "bug report receiver dissappeared", e);
10762            }
10763        }
10764    }
10765
10766    Intent createAppErrorIntentLocked(ProcessRecord r,
10767            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10768        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10769        if (report == null) {
10770            return null;
10771        }
10772        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10773        result.setComponent(r.errorReportReceiver);
10774        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10775        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10776        return result;
10777    }
10778
10779    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10780            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10781        if (r.errorReportReceiver == null) {
10782            return null;
10783        }
10784
10785        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10786            return null;
10787        }
10788
10789        ApplicationErrorReport report = new ApplicationErrorReport();
10790        report.packageName = r.info.packageName;
10791        report.installerPackageName = r.errorReportReceiver.getPackageName();
10792        report.processName = r.processName;
10793        report.time = timeMillis;
10794        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10795
10796        if (r.crashing || r.forceCrashReport) {
10797            report.type = ApplicationErrorReport.TYPE_CRASH;
10798            report.crashInfo = crashInfo;
10799        } else if (r.notResponding) {
10800            report.type = ApplicationErrorReport.TYPE_ANR;
10801            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10802
10803            report.anrInfo.activity = r.notRespondingReport.tag;
10804            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10805            report.anrInfo.info = r.notRespondingReport.longMsg;
10806        }
10807
10808        return report;
10809    }
10810
10811    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10812        enforceNotIsolatedCaller("getProcessesInErrorState");
10813        // assume our apps are happy - lazy create the list
10814        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10815
10816        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10817                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10818        int userId = UserHandle.getUserId(Binder.getCallingUid());
10819
10820        synchronized (this) {
10821
10822            // iterate across all processes
10823            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10824                ProcessRecord app = mLruProcesses.get(i);
10825                if (!allUsers && app.userId != userId) {
10826                    continue;
10827                }
10828                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10829                    // This one's in trouble, so we'll generate a report for it
10830                    // crashes are higher priority (in case there's a crash *and* an anr)
10831                    ActivityManager.ProcessErrorStateInfo report = null;
10832                    if (app.crashing) {
10833                        report = app.crashingReport;
10834                    } else if (app.notResponding) {
10835                        report = app.notRespondingReport;
10836                    }
10837
10838                    if (report != null) {
10839                        if (errList == null) {
10840                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10841                        }
10842                        errList.add(report);
10843                    } else {
10844                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10845                                " crashing = " + app.crashing +
10846                                " notResponding = " + app.notResponding);
10847                    }
10848                }
10849            }
10850        }
10851
10852        return errList;
10853    }
10854
10855    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10856        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10857            if (currApp != null) {
10858                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10859            }
10860            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10861        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10862            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10863        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10864            if (currApp != null) {
10865                currApp.lru = 0;
10866            }
10867            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10868        } else if (adj >= ProcessList.SERVICE_ADJ) {
10869            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10870        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10871            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10872        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10873            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10874        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10875            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10876        } else {
10877            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10878        }
10879    }
10880
10881    private void fillInProcMemInfo(ProcessRecord app,
10882            ActivityManager.RunningAppProcessInfo outInfo) {
10883        outInfo.pid = app.pid;
10884        outInfo.uid = app.info.uid;
10885        if (mHeavyWeightProcess == app) {
10886            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10887        }
10888        if (app.persistent) {
10889            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10890        }
10891        if (app.activities.size() > 0) {
10892            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10893        }
10894        outInfo.lastTrimLevel = app.trimMemoryLevel;
10895        int adj = app.curAdj;
10896        outInfo.importance = oomAdjToImportance(adj, outInfo);
10897        outInfo.importanceReasonCode = app.adjTypeCode;
10898        outInfo.processState = app.curProcState;
10899    }
10900
10901    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10902        enforceNotIsolatedCaller("getRunningAppProcesses");
10903        // Lazy instantiation of list
10904        List<ActivityManager.RunningAppProcessInfo> runList = null;
10905        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10906                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10907        int userId = UserHandle.getUserId(Binder.getCallingUid());
10908        synchronized (this) {
10909            // Iterate across all processes
10910            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10911                ProcessRecord app = mLruProcesses.get(i);
10912                if (!allUsers && app.userId != userId) {
10913                    continue;
10914                }
10915                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10916                    // Generate process state info for running application
10917                    ActivityManager.RunningAppProcessInfo currApp =
10918                        new ActivityManager.RunningAppProcessInfo(app.processName,
10919                                app.pid, app.getPackageList());
10920                    fillInProcMemInfo(app, currApp);
10921                    if (app.adjSource instanceof ProcessRecord) {
10922                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10923                        currApp.importanceReasonImportance = oomAdjToImportance(
10924                                app.adjSourceOom, null);
10925                    } else if (app.adjSource instanceof ActivityRecord) {
10926                        ActivityRecord r = (ActivityRecord)app.adjSource;
10927                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10928                    }
10929                    if (app.adjTarget instanceof ComponentName) {
10930                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10931                    }
10932                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10933                    //        + " lru=" + currApp.lru);
10934                    if (runList == null) {
10935                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10936                    }
10937                    runList.add(currApp);
10938                }
10939            }
10940        }
10941        return runList;
10942    }
10943
10944    public List<ApplicationInfo> getRunningExternalApplications() {
10945        enforceNotIsolatedCaller("getRunningExternalApplications");
10946        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10947        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10948        if (runningApps != null && runningApps.size() > 0) {
10949            Set<String> extList = new HashSet<String>();
10950            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10951                if (app.pkgList != null) {
10952                    for (String pkg : app.pkgList) {
10953                        extList.add(pkg);
10954                    }
10955                }
10956            }
10957            IPackageManager pm = AppGlobals.getPackageManager();
10958            for (String pkg : extList) {
10959                try {
10960                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10961                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10962                        retList.add(info);
10963                    }
10964                } catch (RemoteException e) {
10965                }
10966            }
10967        }
10968        return retList;
10969    }
10970
10971    @Override
10972    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10973        enforceNotIsolatedCaller("getMyMemoryState");
10974        synchronized (this) {
10975            ProcessRecord proc;
10976            synchronized (mPidsSelfLocked) {
10977                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10978            }
10979            fillInProcMemInfo(proc, outInfo);
10980        }
10981    }
10982
10983    @Override
10984    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10985        if (checkCallingPermission(android.Manifest.permission.DUMP)
10986                != PackageManager.PERMISSION_GRANTED) {
10987            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10988                    + Binder.getCallingPid()
10989                    + ", uid=" + Binder.getCallingUid()
10990                    + " without permission "
10991                    + android.Manifest.permission.DUMP);
10992            return;
10993        }
10994
10995        boolean dumpAll = false;
10996        boolean dumpClient = false;
10997        String dumpPackage = null;
10998
10999        int opti = 0;
11000        while (opti < args.length) {
11001            String opt = args[opti];
11002            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11003                break;
11004            }
11005            opti++;
11006            if ("-a".equals(opt)) {
11007                dumpAll = true;
11008            } else if ("-c".equals(opt)) {
11009                dumpClient = true;
11010            } else if ("-h".equals(opt)) {
11011                pw.println("Activity manager dump options:");
11012                pw.println("  [-a] [-c] [-h] [cmd] ...");
11013                pw.println("  cmd may be one of:");
11014                pw.println("    a[ctivities]: activity stack state");
11015                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11016                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11017                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11018                pw.println("    o[om]: out of memory management");
11019                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11020                pw.println("    provider [COMP_SPEC]: provider client-side state");
11021                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11022                pw.println("    service [COMP_SPEC]: service client-side state");
11023                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11024                pw.println("    all: dump all activities");
11025                pw.println("    top: dump the top activity");
11026                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11027                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11028                pw.println("    a partial substring in a component name, a");
11029                pw.println("    hex object identifier.");
11030                pw.println("  -a: include all available server state.");
11031                pw.println("  -c: include client state.");
11032                return;
11033            } else {
11034                pw.println("Unknown argument: " + opt + "; use -h for help");
11035            }
11036        }
11037
11038        long origId = Binder.clearCallingIdentity();
11039        boolean more = false;
11040        // Is the caller requesting to dump a particular piece of data?
11041        if (opti < args.length) {
11042            String cmd = args[opti];
11043            opti++;
11044            if ("activities".equals(cmd) || "a".equals(cmd)) {
11045                synchronized (this) {
11046                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11047                }
11048            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11049                String[] newArgs;
11050                String name;
11051                if (opti >= args.length) {
11052                    name = null;
11053                    newArgs = EMPTY_STRING_ARRAY;
11054                } else {
11055                    name = args[opti];
11056                    opti++;
11057                    newArgs = new String[args.length - opti];
11058                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11059                            args.length - opti);
11060                }
11061                synchronized (this) {
11062                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11063                }
11064            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11065                String[] newArgs;
11066                String name;
11067                if (opti >= args.length) {
11068                    name = null;
11069                    newArgs = EMPTY_STRING_ARRAY;
11070                } else {
11071                    name = args[opti];
11072                    opti++;
11073                    newArgs = new String[args.length - opti];
11074                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11075                            args.length - opti);
11076                }
11077                synchronized (this) {
11078                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11079                }
11080            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11081                String[] newArgs;
11082                String name;
11083                if (opti >= args.length) {
11084                    name = null;
11085                    newArgs = EMPTY_STRING_ARRAY;
11086                } else {
11087                    name = args[opti];
11088                    opti++;
11089                    newArgs = new String[args.length - opti];
11090                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11091                            args.length - opti);
11092                }
11093                synchronized (this) {
11094                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11095                }
11096            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11097                synchronized (this) {
11098                    dumpOomLocked(fd, pw, args, opti, true);
11099                }
11100            } else if ("provider".equals(cmd)) {
11101                String[] newArgs;
11102                String name;
11103                if (opti >= args.length) {
11104                    name = null;
11105                    newArgs = EMPTY_STRING_ARRAY;
11106                } else {
11107                    name = args[opti];
11108                    opti++;
11109                    newArgs = new String[args.length - opti];
11110                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11111                }
11112                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11113                    pw.println("No providers match: " + name);
11114                    pw.println("Use -h for help.");
11115                }
11116            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11117                synchronized (this) {
11118                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11119                }
11120            } else if ("service".equals(cmd)) {
11121                String[] newArgs;
11122                String name;
11123                if (opti >= args.length) {
11124                    name = null;
11125                    newArgs = EMPTY_STRING_ARRAY;
11126                } else {
11127                    name = args[opti];
11128                    opti++;
11129                    newArgs = new String[args.length - opti];
11130                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11131                            args.length - opti);
11132                }
11133                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11134                    pw.println("No services match: " + name);
11135                    pw.println("Use -h for help.");
11136                }
11137            } else if ("package".equals(cmd)) {
11138                String[] newArgs;
11139                if (opti >= args.length) {
11140                    pw.println("package: no package name specified");
11141                    pw.println("Use -h for help.");
11142                } else {
11143                    dumpPackage = args[opti];
11144                    opti++;
11145                    newArgs = new String[args.length - opti];
11146                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11147                            args.length - opti);
11148                    args = newArgs;
11149                    opti = 0;
11150                    more = true;
11151                }
11152            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11153                synchronized (this) {
11154                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11155                }
11156            } else {
11157                // Dumping a single activity?
11158                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11159                    pw.println("Bad activity command, or no activities match: " + cmd);
11160                    pw.println("Use -h for help.");
11161                }
11162            }
11163            if (!more) {
11164                Binder.restoreCallingIdentity(origId);
11165                return;
11166            }
11167        }
11168
11169        // No piece of data specified, dump everything.
11170        synchronized (this) {
11171            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11172            pw.println();
11173            if (dumpAll) {
11174                pw.println("-------------------------------------------------------------------------------");
11175            }
11176            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11177            pw.println();
11178            if (dumpAll) {
11179                pw.println("-------------------------------------------------------------------------------");
11180            }
11181            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11182            pw.println();
11183            if (dumpAll) {
11184                pw.println("-------------------------------------------------------------------------------");
11185            }
11186            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11187            pw.println();
11188            if (dumpAll) {
11189                pw.println("-------------------------------------------------------------------------------");
11190            }
11191            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11192            pw.println();
11193            if (dumpAll) {
11194                pw.println("-------------------------------------------------------------------------------");
11195            }
11196            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11197        }
11198        Binder.restoreCallingIdentity(origId);
11199    }
11200
11201    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11202            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11203        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11204
11205        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11206                dumpPackage);
11207        boolean needSep = printedAnything;
11208
11209        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11210                dumpPackage, needSep, "  mFocusedActivity: ");
11211        if (printed) {
11212            printedAnything = true;
11213            needSep = false;
11214        }
11215
11216        if (dumpPackage == null) {
11217            if (needSep) {
11218                pw.println();
11219            }
11220            needSep = true;
11221            printedAnything = true;
11222            mStackSupervisor.dump(pw, "  ");
11223        }
11224
11225        if (mRecentTasks.size() > 0) {
11226            boolean printedHeader = false;
11227
11228            final int N = mRecentTasks.size();
11229            for (int i=0; i<N; i++) {
11230                TaskRecord tr = mRecentTasks.get(i);
11231                if (dumpPackage != null) {
11232                    if (tr.realActivity == null ||
11233                            !dumpPackage.equals(tr.realActivity)) {
11234                        continue;
11235                    }
11236                }
11237                if (!printedHeader) {
11238                    if (needSep) {
11239                        pw.println();
11240                    }
11241                    pw.println("  Recent tasks:");
11242                    printedHeader = true;
11243                    printedAnything = true;
11244                }
11245                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11246                        pw.println(tr);
11247                if (dumpAll) {
11248                    mRecentTasks.get(i).dump(pw, "    ");
11249                }
11250            }
11251        }
11252
11253        if (!printedAnything) {
11254            pw.println("  (nothing)");
11255        }
11256    }
11257
11258    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11259            int opti, boolean dumpAll, String dumpPackage) {
11260        boolean needSep = false;
11261        boolean printedAnything = false;
11262        int numPers = 0;
11263
11264        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11265
11266        if (dumpAll) {
11267            final int NP = mProcessNames.getMap().size();
11268            for (int ip=0; ip<NP; ip++) {
11269                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11270                final int NA = procs.size();
11271                for (int ia=0; ia<NA; ia++) {
11272                    ProcessRecord r = procs.valueAt(ia);
11273                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11274                        continue;
11275                    }
11276                    if (!needSep) {
11277                        pw.println("  All known processes:");
11278                        needSep = true;
11279                        printedAnything = true;
11280                    }
11281                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11282                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11283                        pw.print(" "); pw.println(r);
11284                    r.dump(pw, "    ");
11285                    if (r.persistent) {
11286                        numPers++;
11287                    }
11288                }
11289            }
11290        }
11291
11292        if (mIsolatedProcesses.size() > 0) {
11293            boolean printed = false;
11294            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11295                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11296                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11297                    continue;
11298                }
11299                if (!printed) {
11300                    if (needSep) {
11301                        pw.println();
11302                    }
11303                    pw.println("  Isolated process list (sorted by uid):");
11304                    printedAnything = true;
11305                    printed = true;
11306                    needSep = true;
11307                }
11308                pw.println(String.format("%sIsolated #%2d: %s",
11309                        "    ", i, r.toString()));
11310            }
11311        }
11312
11313        if (mLruProcesses.size() > 0) {
11314            if (needSep) {
11315                pw.println();
11316            }
11317            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11318                    pw.print(" total, non-act at ");
11319                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11320                    pw.print(", non-svc at ");
11321                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11322                    pw.println("):");
11323            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11324            needSep = true;
11325            printedAnything = true;
11326        }
11327
11328        if (dumpAll || dumpPackage != null) {
11329            synchronized (mPidsSelfLocked) {
11330                boolean printed = false;
11331                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11332                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11333                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11334                        continue;
11335                    }
11336                    if (!printed) {
11337                        if (needSep) pw.println();
11338                        needSep = true;
11339                        pw.println("  PID mappings:");
11340                        printed = true;
11341                        printedAnything = true;
11342                    }
11343                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11344                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11345                }
11346            }
11347        }
11348
11349        if (mForegroundProcesses.size() > 0) {
11350            synchronized (mPidsSelfLocked) {
11351                boolean printed = false;
11352                for (int i=0; i<mForegroundProcesses.size(); i++) {
11353                    ProcessRecord r = mPidsSelfLocked.get(
11354                            mForegroundProcesses.valueAt(i).pid);
11355                    if (dumpPackage != null && (r == null
11356                            || !r.pkgList.containsKey(dumpPackage))) {
11357                        continue;
11358                    }
11359                    if (!printed) {
11360                        if (needSep) pw.println();
11361                        needSep = true;
11362                        pw.println("  Foreground Processes:");
11363                        printed = true;
11364                        printedAnything = true;
11365                    }
11366                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11367                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11368                }
11369            }
11370        }
11371
11372        if (mPersistentStartingProcesses.size() > 0) {
11373            if (needSep) pw.println();
11374            needSep = true;
11375            printedAnything = true;
11376            pw.println("  Persisent processes that are starting:");
11377            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11378                    "Starting Norm", "Restarting PERS", dumpPackage);
11379        }
11380
11381        if (mRemovedProcesses.size() > 0) {
11382            if (needSep) pw.println();
11383            needSep = true;
11384            printedAnything = true;
11385            pw.println("  Processes that are being removed:");
11386            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11387                    "Removed Norm", "Removed PERS", dumpPackage);
11388        }
11389
11390        if (mProcessesOnHold.size() > 0) {
11391            if (needSep) pw.println();
11392            needSep = true;
11393            printedAnything = true;
11394            pw.println("  Processes that are on old until the system is ready:");
11395            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11396                    "OnHold Norm", "OnHold PERS", dumpPackage);
11397        }
11398
11399        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11400
11401        if (mProcessCrashTimes.getMap().size() > 0) {
11402            boolean printed = false;
11403            long now = SystemClock.uptimeMillis();
11404            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11405            final int NP = pmap.size();
11406            for (int ip=0; ip<NP; ip++) {
11407                String pname = pmap.keyAt(ip);
11408                SparseArray<Long> uids = pmap.valueAt(ip);
11409                final int N = uids.size();
11410                for (int i=0; i<N; i++) {
11411                    int puid = uids.keyAt(i);
11412                    ProcessRecord r = mProcessNames.get(pname, puid);
11413                    if (dumpPackage != null && (r == null
11414                            || !r.pkgList.containsKey(dumpPackage))) {
11415                        continue;
11416                    }
11417                    if (!printed) {
11418                        if (needSep) pw.println();
11419                        needSep = true;
11420                        pw.println("  Time since processes crashed:");
11421                        printed = true;
11422                        printedAnything = true;
11423                    }
11424                    pw.print("    Process "); pw.print(pname);
11425                            pw.print(" uid "); pw.print(puid);
11426                            pw.print(": last crashed ");
11427                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11428                            pw.println(" ago");
11429                }
11430            }
11431        }
11432
11433        if (mBadProcesses.getMap().size() > 0) {
11434            boolean printed = false;
11435            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11436            final int NP = pmap.size();
11437            for (int ip=0; ip<NP; ip++) {
11438                String pname = pmap.keyAt(ip);
11439                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11440                final int N = uids.size();
11441                for (int i=0; i<N; i++) {
11442                    int puid = uids.keyAt(i);
11443                    ProcessRecord r = mProcessNames.get(pname, puid);
11444                    if (dumpPackage != null && (r == null
11445                            || !r.pkgList.containsKey(dumpPackage))) {
11446                        continue;
11447                    }
11448                    if (!printed) {
11449                        if (needSep) pw.println();
11450                        needSep = true;
11451                        pw.println("  Bad processes:");
11452                        printedAnything = true;
11453                    }
11454                    BadProcessInfo info = uids.valueAt(i);
11455                    pw.print("    Bad process "); pw.print(pname);
11456                            pw.print(" uid "); pw.print(puid);
11457                            pw.print(": crashed at time "); pw.println(info.time);
11458                    if (info.shortMsg != null) {
11459                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11460                    }
11461                    if (info.longMsg != null) {
11462                        pw.print("      Long msg: "); pw.println(info.longMsg);
11463                    }
11464                    if (info.stack != null) {
11465                        pw.println("      Stack:");
11466                        int lastPos = 0;
11467                        for (int pos=0; pos<info.stack.length(); pos++) {
11468                            if (info.stack.charAt(pos) == '\n') {
11469                                pw.print("        ");
11470                                pw.write(info.stack, lastPos, pos-lastPos);
11471                                pw.println();
11472                                lastPos = pos+1;
11473                            }
11474                        }
11475                        if (lastPos < info.stack.length()) {
11476                            pw.print("        ");
11477                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11478                            pw.println();
11479                        }
11480                    }
11481                }
11482            }
11483        }
11484
11485        if (dumpPackage == null) {
11486            pw.println();
11487            needSep = false;
11488            pw.println("  mStartedUsers:");
11489            for (int i=0; i<mStartedUsers.size(); i++) {
11490                UserStartedState uss = mStartedUsers.valueAt(i);
11491                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11492                        pw.print(": "); uss.dump("", pw);
11493            }
11494            pw.print("  mStartedUserArray: [");
11495            for (int i=0; i<mStartedUserArray.length; i++) {
11496                if (i > 0) pw.print(", ");
11497                pw.print(mStartedUserArray[i]);
11498            }
11499            pw.println("]");
11500            pw.print("  mUserLru: [");
11501            for (int i=0; i<mUserLru.size(); i++) {
11502                if (i > 0) pw.print(", ");
11503                pw.print(mUserLru.get(i));
11504            }
11505            pw.println("]");
11506            if (dumpAll) {
11507                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11508            }
11509        }
11510        if (mHomeProcess != null && (dumpPackage == null
11511                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11512            if (needSep) {
11513                pw.println();
11514                needSep = false;
11515            }
11516            pw.println("  mHomeProcess: " + mHomeProcess);
11517        }
11518        if (mPreviousProcess != null && (dumpPackage == null
11519                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11520            if (needSep) {
11521                pw.println();
11522                needSep = false;
11523            }
11524            pw.println("  mPreviousProcess: " + mPreviousProcess);
11525        }
11526        if (dumpAll) {
11527            StringBuilder sb = new StringBuilder(128);
11528            sb.append("  mPreviousProcessVisibleTime: ");
11529            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11530            pw.println(sb);
11531        }
11532        if (mHeavyWeightProcess != null && (dumpPackage == null
11533                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11534            if (needSep) {
11535                pw.println();
11536                needSep = false;
11537            }
11538            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11539        }
11540        if (dumpPackage == null) {
11541            pw.println("  mConfiguration: " + mConfiguration);
11542        }
11543        if (dumpAll) {
11544            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11545            if (mCompatModePackages.getPackages().size() > 0) {
11546                boolean printed = false;
11547                for (Map.Entry<String, Integer> entry
11548                        : mCompatModePackages.getPackages().entrySet()) {
11549                    String pkg = entry.getKey();
11550                    int mode = entry.getValue();
11551                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11552                        continue;
11553                    }
11554                    if (!printed) {
11555                        pw.println("  mScreenCompatPackages:");
11556                        printed = true;
11557                    }
11558                    pw.print("    "); pw.print(pkg); pw.print(": ");
11559                            pw.print(mode); pw.println();
11560                }
11561            }
11562        }
11563        if (dumpPackage == null) {
11564            if (mSleeping || mWentToSleep || mLockScreenShown) {
11565                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11566                        + " mLockScreenShown " + mLockScreenShown);
11567            }
11568            if (mShuttingDown || mRunningVoice) {
11569                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11570            }
11571        }
11572        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11573                || mOrigWaitForDebugger) {
11574            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11575                    || dumpPackage.equals(mOrigDebugApp)) {
11576                if (needSep) {
11577                    pw.println();
11578                    needSep = false;
11579                }
11580                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11581                        + " mDebugTransient=" + mDebugTransient
11582                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11583            }
11584        }
11585        if (mOpenGlTraceApp != null) {
11586            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11587                if (needSep) {
11588                    pw.println();
11589                    needSep = false;
11590                }
11591                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11592            }
11593        }
11594        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11595                || mProfileFd != null) {
11596            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11597                if (needSep) {
11598                    pw.println();
11599                    needSep = false;
11600                }
11601                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11602                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11603                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11604                        + mAutoStopProfiler);
11605            }
11606        }
11607        if (dumpPackage == null) {
11608            if (mAlwaysFinishActivities || mController != null) {
11609                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11610                        + " mController=" + mController);
11611            }
11612            if (dumpAll) {
11613                pw.println("  Total persistent processes: " + numPers);
11614                pw.println("  mProcessesReady=" + mProcessesReady
11615                        + " mSystemReady=" + mSystemReady);
11616                pw.println("  mBooting=" + mBooting
11617                        + " mBooted=" + mBooted
11618                        + " mFactoryTest=" + mFactoryTest);
11619                pw.print("  mLastPowerCheckRealtime=");
11620                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11621                        pw.println("");
11622                pw.print("  mLastPowerCheckUptime=");
11623                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11624                        pw.println("");
11625                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11626                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11627                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11628                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11629                        + " (" + mLruProcesses.size() + " total)"
11630                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11631                        + " mNumServiceProcs=" + mNumServiceProcs
11632                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11633                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11634                        + " mLastMemoryLevel" + mLastMemoryLevel
11635                        + " mLastNumProcesses" + mLastNumProcesses);
11636                long now = SystemClock.uptimeMillis();
11637                pw.print("  mLastIdleTime=");
11638                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11639                        pw.print(" mLowRamSinceLastIdle=");
11640                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11641                        pw.println();
11642            }
11643        }
11644
11645        if (!printedAnything) {
11646            pw.println("  (nothing)");
11647        }
11648    }
11649
11650    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11651            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11652        if (mProcessesToGc.size() > 0) {
11653            boolean printed = false;
11654            long now = SystemClock.uptimeMillis();
11655            for (int i=0; i<mProcessesToGc.size(); i++) {
11656                ProcessRecord proc = mProcessesToGc.get(i);
11657                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11658                    continue;
11659                }
11660                if (!printed) {
11661                    if (needSep) pw.println();
11662                    needSep = true;
11663                    pw.println("  Processes that are waiting to GC:");
11664                    printed = true;
11665                }
11666                pw.print("    Process "); pw.println(proc);
11667                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11668                        pw.print(", last gced=");
11669                        pw.print(now-proc.lastRequestedGc);
11670                        pw.print(" ms ago, last lowMem=");
11671                        pw.print(now-proc.lastLowMemory);
11672                        pw.println(" ms ago");
11673
11674            }
11675        }
11676        return needSep;
11677    }
11678
11679    void printOomLevel(PrintWriter pw, String name, int adj) {
11680        pw.print("    ");
11681        if (adj >= 0) {
11682            pw.print(' ');
11683            if (adj < 10) pw.print(' ');
11684        } else {
11685            if (adj > -10) pw.print(' ');
11686        }
11687        pw.print(adj);
11688        pw.print(": ");
11689        pw.print(name);
11690        pw.print(" (");
11691        pw.print(mProcessList.getMemLevel(adj)/1024);
11692        pw.println(" kB)");
11693    }
11694
11695    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11696            int opti, boolean dumpAll) {
11697        boolean needSep = false;
11698
11699        if (mLruProcesses.size() > 0) {
11700            if (needSep) pw.println();
11701            needSep = true;
11702            pw.println("  OOM levels:");
11703            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11704            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11705            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11706            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11707            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11708            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11709            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11710            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11711            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11712            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11713            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11714            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11715            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11716
11717            if (needSep) pw.println();
11718            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11719                    pw.print(" total, non-act at ");
11720                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11721                    pw.print(", non-svc at ");
11722                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11723                    pw.println("):");
11724            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11725            needSep = true;
11726        }
11727
11728        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11729
11730        pw.println();
11731        pw.println("  mHomeProcess: " + mHomeProcess);
11732        pw.println("  mPreviousProcess: " + mPreviousProcess);
11733        if (mHeavyWeightProcess != null) {
11734            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11735        }
11736
11737        return true;
11738    }
11739
11740    /**
11741     * There are three ways to call this:
11742     *  - no provider specified: dump all the providers
11743     *  - a flattened component name that matched an existing provider was specified as the
11744     *    first arg: dump that one provider
11745     *  - the first arg isn't the flattened component name of an existing provider:
11746     *    dump all providers whose component contains the first arg as a substring
11747     */
11748    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11749            int opti, boolean dumpAll) {
11750        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11751    }
11752
11753    static class ItemMatcher {
11754        ArrayList<ComponentName> components;
11755        ArrayList<String> strings;
11756        ArrayList<Integer> objects;
11757        boolean all;
11758
11759        ItemMatcher() {
11760            all = true;
11761        }
11762
11763        void build(String name) {
11764            ComponentName componentName = ComponentName.unflattenFromString(name);
11765            if (componentName != null) {
11766                if (components == null) {
11767                    components = new ArrayList<ComponentName>();
11768                }
11769                components.add(componentName);
11770                all = false;
11771            } else {
11772                int objectId = 0;
11773                // Not a '/' separated full component name; maybe an object ID?
11774                try {
11775                    objectId = Integer.parseInt(name, 16);
11776                    if (objects == null) {
11777                        objects = new ArrayList<Integer>();
11778                    }
11779                    objects.add(objectId);
11780                    all = false;
11781                } catch (RuntimeException e) {
11782                    // Not an integer; just do string match.
11783                    if (strings == null) {
11784                        strings = new ArrayList<String>();
11785                    }
11786                    strings.add(name);
11787                    all = false;
11788                }
11789            }
11790        }
11791
11792        int build(String[] args, int opti) {
11793            for (; opti<args.length; opti++) {
11794                String name = args[opti];
11795                if ("--".equals(name)) {
11796                    return opti+1;
11797                }
11798                build(name);
11799            }
11800            return opti;
11801        }
11802
11803        boolean match(Object object, ComponentName comp) {
11804            if (all) {
11805                return true;
11806            }
11807            if (components != null) {
11808                for (int i=0; i<components.size(); i++) {
11809                    if (components.get(i).equals(comp)) {
11810                        return true;
11811                    }
11812                }
11813            }
11814            if (objects != null) {
11815                for (int i=0; i<objects.size(); i++) {
11816                    if (System.identityHashCode(object) == objects.get(i)) {
11817                        return true;
11818                    }
11819                }
11820            }
11821            if (strings != null) {
11822                String flat = comp.flattenToString();
11823                for (int i=0; i<strings.size(); i++) {
11824                    if (flat.contains(strings.get(i))) {
11825                        return true;
11826                    }
11827                }
11828            }
11829            return false;
11830        }
11831    }
11832
11833    /**
11834     * There are three things that cmd can be:
11835     *  - a flattened component name that matches an existing activity
11836     *  - the cmd arg isn't the flattened component name of an existing activity:
11837     *    dump all activity whose component contains the cmd as a substring
11838     *  - A hex number of the ActivityRecord object instance.
11839     */
11840    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11841            int opti, boolean dumpAll) {
11842        ArrayList<ActivityRecord> activities;
11843
11844        synchronized (this) {
11845            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11846        }
11847
11848        if (activities.size() <= 0) {
11849            return false;
11850        }
11851
11852        String[] newArgs = new String[args.length - opti];
11853        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11854
11855        TaskRecord lastTask = null;
11856        boolean needSep = false;
11857        for (int i=activities.size()-1; i>=0; i--) {
11858            ActivityRecord r = activities.get(i);
11859            if (needSep) {
11860                pw.println();
11861            }
11862            needSep = true;
11863            synchronized (this) {
11864                if (lastTask != r.task) {
11865                    lastTask = r.task;
11866                    pw.print("TASK "); pw.print(lastTask.affinity);
11867                            pw.print(" id="); pw.println(lastTask.taskId);
11868                    if (dumpAll) {
11869                        lastTask.dump(pw, "  ");
11870                    }
11871                }
11872            }
11873            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11874        }
11875        return true;
11876    }
11877
11878    /**
11879     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11880     * there is a thread associated with the activity.
11881     */
11882    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11883            final ActivityRecord r, String[] args, boolean dumpAll) {
11884        String innerPrefix = prefix + "  ";
11885        synchronized (this) {
11886            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11887                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11888                    pw.print(" pid=");
11889                    if (r.app != null) pw.println(r.app.pid);
11890                    else pw.println("(not running)");
11891            if (dumpAll) {
11892                r.dump(pw, innerPrefix);
11893            }
11894        }
11895        if (r.app != null && r.app.thread != null) {
11896            // flush anything that is already in the PrintWriter since the thread is going
11897            // to write to the file descriptor directly
11898            pw.flush();
11899            try {
11900                TransferPipe tp = new TransferPipe();
11901                try {
11902                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11903                            r.appToken, innerPrefix, args);
11904                    tp.go(fd);
11905                } finally {
11906                    tp.kill();
11907                }
11908            } catch (IOException e) {
11909                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11910            } catch (RemoteException e) {
11911                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11912            }
11913        }
11914    }
11915
11916    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11917            int opti, boolean dumpAll, String dumpPackage) {
11918        boolean needSep = false;
11919        boolean onlyHistory = false;
11920        boolean printedAnything = false;
11921
11922        if ("history".equals(dumpPackage)) {
11923            if (opti < args.length && "-s".equals(args[opti])) {
11924                dumpAll = false;
11925            }
11926            onlyHistory = true;
11927            dumpPackage = null;
11928        }
11929
11930        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11931        if (!onlyHistory && dumpAll) {
11932            if (mRegisteredReceivers.size() > 0) {
11933                boolean printed = false;
11934                Iterator it = mRegisteredReceivers.values().iterator();
11935                while (it.hasNext()) {
11936                    ReceiverList r = (ReceiverList)it.next();
11937                    if (dumpPackage != null && (r.app == null ||
11938                            !dumpPackage.equals(r.app.info.packageName))) {
11939                        continue;
11940                    }
11941                    if (!printed) {
11942                        pw.println("  Registered Receivers:");
11943                        needSep = true;
11944                        printed = true;
11945                        printedAnything = true;
11946                    }
11947                    pw.print("  * "); pw.println(r);
11948                    r.dump(pw, "    ");
11949                }
11950            }
11951
11952            if (mReceiverResolver.dump(pw, needSep ?
11953                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11954                    "    ", dumpPackage, false)) {
11955                needSep = true;
11956                printedAnything = true;
11957            }
11958        }
11959
11960        for (BroadcastQueue q : mBroadcastQueues) {
11961            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11962            printedAnything |= needSep;
11963        }
11964
11965        needSep = true;
11966
11967        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11968            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11969                if (needSep) {
11970                    pw.println();
11971                }
11972                needSep = true;
11973                printedAnything = true;
11974                pw.print("  Sticky broadcasts for user ");
11975                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11976                StringBuilder sb = new StringBuilder(128);
11977                for (Map.Entry<String, ArrayList<Intent>> ent
11978                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11979                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11980                    if (dumpAll) {
11981                        pw.println(":");
11982                        ArrayList<Intent> intents = ent.getValue();
11983                        final int N = intents.size();
11984                        for (int i=0; i<N; i++) {
11985                            sb.setLength(0);
11986                            sb.append("    Intent: ");
11987                            intents.get(i).toShortString(sb, false, true, false, false);
11988                            pw.println(sb.toString());
11989                            Bundle bundle = intents.get(i).getExtras();
11990                            if (bundle != null) {
11991                                pw.print("      ");
11992                                pw.println(bundle.toString());
11993                            }
11994                        }
11995                    } else {
11996                        pw.println("");
11997                    }
11998                }
11999            }
12000        }
12001
12002        if (!onlyHistory && dumpAll) {
12003            pw.println();
12004            for (BroadcastQueue queue : mBroadcastQueues) {
12005                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12006                        + queue.mBroadcastsScheduled);
12007            }
12008            pw.println("  mHandler:");
12009            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12010            needSep = true;
12011            printedAnything = true;
12012        }
12013
12014        if (!printedAnything) {
12015            pw.println("  (nothing)");
12016        }
12017    }
12018
12019    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12020            int opti, boolean dumpAll, String dumpPackage) {
12021        boolean needSep;
12022        boolean printedAnything = false;
12023
12024        ItemMatcher matcher = new ItemMatcher();
12025        matcher.build(args, opti);
12026
12027        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12028
12029        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12030        printedAnything |= needSep;
12031
12032        if (mLaunchingProviders.size() > 0) {
12033            boolean printed = false;
12034            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12035                ContentProviderRecord r = mLaunchingProviders.get(i);
12036                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12037                    continue;
12038                }
12039                if (!printed) {
12040                    if (needSep) pw.println();
12041                    needSep = true;
12042                    pw.println("  Launching content providers:");
12043                    printed = true;
12044                    printedAnything = true;
12045                }
12046                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12047                        pw.println(r);
12048            }
12049        }
12050
12051        if (mGrantedUriPermissions.size() > 0) {
12052            boolean printed = false;
12053            int dumpUid = -2;
12054            if (dumpPackage != null) {
12055                try {
12056                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12057                } catch (NameNotFoundException e) {
12058                    dumpUid = -1;
12059                }
12060            }
12061            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12062                int uid = mGrantedUriPermissions.keyAt(i);
12063                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12064                    continue;
12065                }
12066                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12067                if (!printed) {
12068                    if (needSep) pw.println();
12069                    needSep = true;
12070                    pw.println("  Granted Uri Permissions:");
12071                    printed = true;
12072                    printedAnything = true;
12073                }
12074                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12075                for (UriPermission perm : perms.values()) {
12076                    pw.print("    "); pw.println(perm);
12077                    if (dumpAll) {
12078                        perm.dump(pw, "      ");
12079                    }
12080                }
12081            }
12082        }
12083
12084        if (!printedAnything) {
12085            pw.println("  (nothing)");
12086        }
12087    }
12088
12089    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12090            int opti, boolean dumpAll, String dumpPackage) {
12091        boolean printed = false;
12092
12093        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12094
12095        if (mIntentSenderRecords.size() > 0) {
12096            Iterator<WeakReference<PendingIntentRecord>> it
12097                    = mIntentSenderRecords.values().iterator();
12098            while (it.hasNext()) {
12099                WeakReference<PendingIntentRecord> ref = it.next();
12100                PendingIntentRecord rec = ref != null ? ref.get(): null;
12101                if (dumpPackage != null && (rec == null
12102                        || !dumpPackage.equals(rec.key.packageName))) {
12103                    continue;
12104                }
12105                printed = true;
12106                if (rec != null) {
12107                    pw.print("  * "); pw.println(rec);
12108                    if (dumpAll) {
12109                        rec.dump(pw, "    ");
12110                    }
12111                } else {
12112                    pw.print("  * "); pw.println(ref);
12113                }
12114            }
12115        }
12116
12117        if (!printed) {
12118            pw.println("  (nothing)");
12119        }
12120    }
12121
12122    private static final int dumpProcessList(PrintWriter pw,
12123            ActivityManagerService service, List list,
12124            String prefix, String normalLabel, String persistentLabel,
12125            String dumpPackage) {
12126        int numPers = 0;
12127        final int N = list.size()-1;
12128        for (int i=N; i>=0; i--) {
12129            ProcessRecord r = (ProcessRecord)list.get(i);
12130            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12131                continue;
12132            }
12133            pw.println(String.format("%s%s #%2d: %s",
12134                    prefix, (r.persistent ? persistentLabel : normalLabel),
12135                    i, r.toString()));
12136            if (r.persistent) {
12137                numPers++;
12138            }
12139        }
12140        return numPers;
12141    }
12142
12143    private static final boolean dumpProcessOomList(PrintWriter pw,
12144            ActivityManagerService service, List<ProcessRecord> origList,
12145            String prefix, String normalLabel, String persistentLabel,
12146            boolean inclDetails, String dumpPackage) {
12147
12148        ArrayList<Pair<ProcessRecord, Integer>> list
12149                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12150        for (int i=0; i<origList.size(); i++) {
12151            ProcessRecord r = origList.get(i);
12152            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12153                continue;
12154            }
12155            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12156        }
12157
12158        if (list.size() <= 0) {
12159            return false;
12160        }
12161
12162        Comparator<Pair<ProcessRecord, Integer>> comparator
12163                = new Comparator<Pair<ProcessRecord, Integer>>() {
12164            @Override
12165            public int compare(Pair<ProcessRecord, Integer> object1,
12166                    Pair<ProcessRecord, Integer> object2) {
12167                if (object1.first.setAdj != object2.first.setAdj) {
12168                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12169                }
12170                if (object1.second.intValue() != object2.second.intValue()) {
12171                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12172                }
12173                return 0;
12174            }
12175        };
12176
12177        Collections.sort(list, comparator);
12178
12179        final long curRealtime = SystemClock.elapsedRealtime();
12180        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12181        final long curUptime = SystemClock.uptimeMillis();
12182        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12183
12184        for (int i=list.size()-1; i>=0; i--) {
12185            ProcessRecord r = list.get(i).first;
12186            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12187            char schedGroup;
12188            switch (r.setSchedGroup) {
12189                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12190                    schedGroup = 'B';
12191                    break;
12192                case Process.THREAD_GROUP_DEFAULT:
12193                    schedGroup = 'F';
12194                    break;
12195                default:
12196                    schedGroup = '?';
12197                    break;
12198            }
12199            char foreground;
12200            if (r.foregroundActivities) {
12201                foreground = 'A';
12202            } else if (r.foregroundServices) {
12203                foreground = 'S';
12204            } else {
12205                foreground = ' ';
12206            }
12207            String procState = ProcessList.makeProcStateString(r.curProcState);
12208            pw.print(prefix);
12209            pw.print(r.persistent ? persistentLabel : normalLabel);
12210            pw.print(" #");
12211            int num = (origList.size()-1)-list.get(i).second;
12212            if (num < 10) pw.print(' ');
12213            pw.print(num);
12214            pw.print(": ");
12215            pw.print(oomAdj);
12216            pw.print(' ');
12217            pw.print(schedGroup);
12218            pw.print('/');
12219            pw.print(foreground);
12220            pw.print('/');
12221            pw.print(procState);
12222            pw.print(" trm:");
12223            if (r.trimMemoryLevel < 10) pw.print(' ');
12224            pw.print(r.trimMemoryLevel);
12225            pw.print(' ');
12226            pw.print(r.toShortString());
12227            pw.print(" (");
12228            pw.print(r.adjType);
12229            pw.println(')');
12230            if (r.adjSource != null || r.adjTarget != null) {
12231                pw.print(prefix);
12232                pw.print("    ");
12233                if (r.adjTarget instanceof ComponentName) {
12234                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12235                } else if (r.adjTarget != null) {
12236                    pw.print(r.adjTarget.toString());
12237                } else {
12238                    pw.print("{null}");
12239                }
12240                pw.print("<=");
12241                if (r.adjSource instanceof ProcessRecord) {
12242                    pw.print("Proc{");
12243                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12244                    pw.println("}");
12245                } else if (r.adjSource != null) {
12246                    pw.println(r.adjSource.toString());
12247                } else {
12248                    pw.println("{null}");
12249                }
12250            }
12251            if (inclDetails) {
12252                pw.print(prefix);
12253                pw.print("    ");
12254                pw.print("oom: max="); pw.print(r.maxAdj);
12255                pw.print(" curRaw="); pw.print(r.curRawAdj);
12256                pw.print(" setRaw="); pw.print(r.setRawAdj);
12257                pw.print(" cur="); pw.print(r.curAdj);
12258                pw.print(" set="); pw.println(r.setAdj);
12259                pw.print(prefix);
12260                pw.print("    ");
12261                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12262                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12263                pw.print(" lastPss="); pw.print(r.lastPss);
12264                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12265                pw.print(prefix);
12266                pw.print("    ");
12267                pw.print("keeping="); pw.print(r.keeping);
12268                pw.print(" cached="); pw.print(r.cached);
12269                pw.print(" empty="); pw.print(r.empty);
12270                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12271
12272                if (!r.keeping) {
12273                    if (r.lastWakeTime != 0) {
12274                        long wtime;
12275                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12276                        synchronized (stats) {
12277                            wtime = stats.getProcessWakeTime(r.info.uid,
12278                                    r.pid, curRealtime);
12279                        }
12280                        long timeUsed = wtime - r.lastWakeTime;
12281                        pw.print(prefix);
12282                        pw.print("    ");
12283                        pw.print("keep awake over ");
12284                        TimeUtils.formatDuration(realtimeSince, pw);
12285                        pw.print(" used ");
12286                        TimeUtils.formatDuration(timeUsed, pw);
12287                        pw.print(" (");
12288                        pw.print((timeUsed*100)/realtimeSince);
12289                        pw.println("%)");
12290                    }
12291                    if (r.lastCpuTime != 0) {
12292                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12293                        pw.print(prefix);
12294                        pw.print("    ");
12295                        pw.print("run cpu over ");
12296                        TimeUtils.formatDuration(uptimeSince, pw);
12297                        pw.print(" used ");
12298                        TimeUtils.formatDuration(timeUsed, pw);
12299                        pw.print(" (");
12300                        pw.print((timeUsed*100)/uptimeSince);
12301                        pw.println("%)");
12302                    }
12303                }
12304            }
12305        }
12306        return true;
12307    }
12308
12309    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12310        ArrayList<ProcessRecord> procs;
12311        synchronized (this) {
12312            if (args != null && args.length > start
12313                    && args[start].charAt(0) != '-') {
12314                procs = new ArrayList<ProcessRecord>();
12315                int pid = -1;
12316                try {
12317                    pid = Integer.parseInt(args[start]);
12318                } catch (NumberFormatException e) {
12319                }
12320                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12321                    ProcessRecord proc = mLruProcesses.get(i);
12322                    if (proc.pid == pid) {
12323                        procs.add(proc);
12324                    } else if (proc.processName.equals(args[start])) {
12325                        procs.add(proc);
12326                    }
12327                }
12328                if (procs.size() <= 0) {
12329                    return null;
12330                }
12331            } else {
12332                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12333            }
12334        }
12335        return procs;
12336    }
12337
12338    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12339            PrintWriter pw, String[] args) {
12340        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12341        if (procs == null) {
12342            pw.println("No process found for: " + args[0]);
12343            return;
12344        }
12345
12346        long uptime = SystemClock.uptimeMillis();
12347        long realtime = SystemClock.elapsedRealtime();
12348        pw.println("Applications Graphics Acceleration Info:");
12349        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12350
12351        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12352            ProcessRecord r = procs.get(i);
12353            if (r.thread != null) {
12354                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12355                pw.flush();
12356                try {
12357                    TransferPipe tp = new TransferPipe();
12358                    try {
12359                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12360                        tp.go(fd);
12361                    } finally {
12362                        tp.kill();
12363                    }
12364                } catch (IOException e) {
12365                    pw.println("Failure while dumping the app: " + r);
12366                    pw.flush();
12367                } catch (RemoteException e) {
12368                    pw.println("Got a RemoteException while dumping the app " + r);
12369                    pw.flush();
12370                }
12371            }
12372        }
12373    }
12374
12375    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12376        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12377        if (procs == null) {
12378            pw.println("No process found for: " + args[0]);
12379            return;
12380        }
12381
12382        pw.println("Applications Database Info:");
12383
12384        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12385            ProcessRecord r = procs.get(i);
12386            if (r.thread != null) {
12387                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12388                pw.flush();
12389                try {
12390                    TransferPipe tp = new TransferPipe();
12391                    try {
12392                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12393                        tp.go(fd);
12394                    } finally {
12395                        tp.kill();
12396                    }
12397                } catch (IOException e) {
12398                    pw.println("Failure while dumping the app: " + r);
12399                    pw.flush();
12400                } catch (RemoteException e) {
12401                    pw.println("Got a RemoteException while dumping the app " + r);
12402                    pw.flush();
12403                }
12404            }
12405        }
12406    }
12407
12408    final static class MemItem {
12409        final boolean isProc;
12410        final String label;
12411        final String shortLabel;
12412        final long pss;
12413        final int id;
12414        final boolean hasActivities;
12415        ArrayList<MemItem> subitems;
12416
12417        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12418                boolean _hasActivities) {
12419            isProc = true;
12420            label = _label;
12421            shortLabel = _shortLabel;
12422            pss = _pss;
12423            id = _id;
12424            hasActivities = _hasActivities;
12425        }
12426
12427        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12428            isProc = false;
12429            label = _label;
12430            shortLabel = _shortLabel;
12431            pss = _pss;
12432            id = _id;
12433            hasActivities = false;
12434        }
12435    }
12436
12437    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12438            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12439        if (sort && !isCompact) {
12440            Collections.sort(items, new Comparator<MemItem>() {
12441                @Override
12442                public int compare(MemItem lhs, MemItem rhs) {
12443                    if (lhs.pss < rhs.pss) {
12444                        return 1;
12445                    } else if (lhs.pss > rhs.pss) {
12446                        return -1;
12447                    }
12448                    return 0;
12449                }
12450            });
12451        }
12452
12453        for (int i=0; i<items.size(); i++) {
12454            MemItem mi = items.get(i);
12455            if (!isCompact) {
12456                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12457            } else if (mi.isProc) {
12458                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12459                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12460                pw.println(mi.hasActivities ? ",a" : ",e");
12461            } else {
12462                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12463                pw.println(mi.pss);
12464            }
12465            if (mi.subitems != null) {
12466                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12467                        true, isCompact);
12468            }
12469        }
12470    }
12471
12472    // These are in KB.
12473    static final long[] DUMP_MEM_BUCKETS = new long[] {
12474        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12475        120*1024, 160*1024, 200*1024,
12476        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12477        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12478    };
12479
12480    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12481            boolean stackLike) {
12482        int start = label.lastIndexOf('.');
12483        if (start >= 0) start++;
12484        else start = 0;
12485        int end = label.length();
12486        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12487            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12488                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12489                out.append(bucket);
12490                out.append(stackLike ? "MB." : "MB ");
12491                out.append(label, start, end);
12492                return;
12493            }
12494        }
12495        out.append(memKB/1024);
12496        out.append(stackLike ? "MB." : "MB ");
12497        out.append(label, start, end);
12498    }
12499
12500    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12501            ProcessList.NATIVE_ADJ,
12502            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12503            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12504            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12505            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12506            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12507    };
12508    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12509            "Native",
12510            "System", "Persistent", "Foreground",
12511            "Visible", "Perceptible",
12512            "Heavy Weight", "Backup",
12513            "A Services", "Home",
12514            "Previous", "B Services", "Cached"
12515    };
12516    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12517            "native",
12518            "sys", "pers", "fore",
12519            "vis", "percept",
12520            "heavy", "backup",
12521            "servicea", "home",
12522            "prev", "serviceb", "cached"
12523    };
12524
12525    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12526            long realtime, boolean isCheckinRequest, boolean isCompact) {
12527        if (isCheckinRequest || isCompact) {
12528            // short checkin version
12529            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12530        } else {
12531            pw.println("Applications Memory Usage (kB):");
12532            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12533        }
12534    }
12535
12536    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12537            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12538        boolean dumpDetails = false;
12539        boolean dumpFullDetails = false;
12540        boolean dumpDalvik = false;
12541        boolean oomOnly = false;
12542        boolean isCompact = false;
12543        boolean localOnly = false;
12544
12545        int opti = 0;
12546        while (opti < args.length) {
12547            String opt = args[opti];
12548            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12549                break;
12550            }
12551            opti++;
12552            if ("-a".equals(opt)) {
12553                dumpDetails = true;
12554                dumpFullDetails = true;
12555                dumpDalvik = true;
12556            } else if ("-d".equals(opt)) {
12557                dumpDalvik = true;
12558            } else if ("-c".equals(opt)) {
12559                isCompact = true;
12560            } else if ("--oom".equals(opt)) {
12561                oomOnly = true;
12562            } else if ("--local".equals(opt)) {
12563                localOnly = true;
12564            } else if ("-h".equals(opt)) {
12565                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12566                pw.println("  -a: include all available information for each process.");
12567                pw.println("  -d: include dalvik details when dumping process details.");
12568                pw.println("  -c: dump in a compact machine-parseable representation.");
12569                pw.println("  --oom: only show processes organized by oom adj.");
12570                pw.println("  --local: only collect details locally, don't call process.");
12571                pw.println("If [process] is specified it can be the name or ");
12572                pw.println("pid of a specific process to dump.");
12573                return;
12574            } else {
12575                pw.println("Unknown argument: " + opt + "; use -h for help");
12576            }
12577        }
12578
12579        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12580        long uptime = SystemClock.uptimeMillis();
12581        long realtime = SystemClock.elapsedRealtime();
12582        final long[] tmpLong = new long[1];
12583
12584        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12585        if (procs == null) {
12586            // No Java processes.  Maybe they want to print a native process.
12587            if (args != null && args.length > opti
12588                    && args[opti].charAt(0) != '-') {
12589                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12590                        = new ArrayList<ProcessCpuTracker.Stats>();
12591                updateCpuStatsNow();
12592                int findPid = -1;
12593                try {
12594                    findPid = Integer.parseInt(args[opti]);
12595                } catch (NumberFormatException e) {
12596                }
12597                synchronized (mProcessCpuThread) {
12598                    final int N = mProcessCpuTracker.countStats();
12599                    for (int i=0; i<N; i++) {
12600                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12601                        if (st.pid == findPid || (st.baseName != null
12602                                && st.baseName.equals(args[opti]))) {
12603                            nativeProcs.add(st);
12604                        }
12605                    }
12606                }
12607                if (nativeProcs.size() > 0) {
12608                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12609                            isCompact);
12610                    Debug.MemoryInfo mi = null;
12611                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12612                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12613                        final int pid = r.pid;
12614                        if (!isCheckinRequest && dumpDetails) {
12615                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12616                        }
12617                        if (mi == null) {
12618                            mi = new Debug.MemoryInfo();
12619                        }
12620                        if (dumpDetails || (!brief && !oomOnly)) {
12621                            Debug.getMemoryInfo(pid, mi);
12622                        } else {
12623                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12624                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12625                        }
12626                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12627                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12628                        if (isCheckinRequest) {
12629                            pw.println();
12630                        }
12631                    }
12632                    return;
12633                }
12634            }
12635            pw.println("No process found for: " + args[opti]);
12636            return;
12637        }
12638
12639        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12640            dumpDetails = true;
12641        }
12642
12643        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12644
12645        String[] innerArgs = new String[args.length-opti];
12646        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12647
12648        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12649        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12650        long nativePss=0, dalvikPss=0, otherPss=0;
12651        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12652
12653        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12654        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12655                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12656
12657        long totalPss = 0;
12658        long cachedPss = 0;
12659
12660        Debug.MemoryInfo mi = null;
12661        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12662            final ProcessRecord r = procs.get(i);
12663            final IApplicationThread thread;
12664            final int pid;
12665            final int oomAdj;
12666            final boolean hasActivities;
12667            synchronized (this) {
12668                thread = r.thread;
12669                pid = r.pid;
12670                oomAdj = r.getSetAdjWithServices();
12671                hasActivities = r.activities.size() > 0;
12672            }
12673            if (thread != null) {
12674                if (!isCheckinRequest && dumpDetails) {
12675                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12676                }
12677                if (mi == null) {
12678                    mi = new Debug.MemoryInfo();
12679                }
12680                if (dumpDetails || (!brief && !oomOnly)) {
12681                    Debug.getMemoryInfo(pid, mi);
12682                } else {
12683                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12684                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12685                }
12686                if (dumpDetails) {
12687                    if (localOnly) {
12688                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12689                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12690                        if (isCheckinRequest) {
12691                            pw.println();
12692                        }
12693                    } else {
12694                        try {
12695                            pw.flush();
12696                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12697                                    dumpDalvik, innerArgs);
12698                        } catch (RemoteException e) {
12699                            if (!isCheckinRequest) {
12700                                pw.println("Got RemoteException!");
12701                                pw.flush();
12702                            }
12703                        }
12704                    }
12705                }
12706
12707                final long myTotalPss = mi.getTotalPss();
12708                final long myTotalUss = mi.getTotalUss();
12709
12710                synchronized (this) {
12711                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12712                        // Record this for posterity if the process has been stable.
12713                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12714                    }
12715                }
12716
12717                if (!isCheckinRequest && mi != null) {
12718                    totalPss += myTotalPss;
12719                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12720                            (hasActivities ? " / activities)" : ")"),
12721                            r.processName, myTotalPss, pid, hasActivities);
12722                    procMems.add(pssItem);
12723                    procMemsMap.put(pid, pssItem);
12724
12725                    nativePss += mi.nativePss;
12726                    dalvikPss += mi.dalvikPss;
12727                    otherPss += mi.otherPss;
12728                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12729                        long mem = mi.getOtherPss(j);
12730                        miscPss[j] += mem;
12731                        otherPss -= mem;
12732                    }
12733
12734                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12735                        cachedPss += myTotalPss;
12736                    }
12737
12738                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12739                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12740                                || oomIndex == (oomPss.length-1)) {
12741                            oomPss[oomIndex] += myTotalPss;
12742                            if (oomProcs[oomIndex] == null) {
12743                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12744                            }
12745                            oomProcs[oomIndex].add(pssItem);
12746                            break;
12747                        }
12748                    }
12749                }
12750            }
12751        }
12752
12753        long nativeProcTotalPss = 0;
12754
12755        if (!isCheckinRequest && procs.size() > 1) {
12756            // If we are showing aggregations, also look for native processes to
12757            // include so that our aggregations are more accurate.
12758            updateCpuStatsNow();
12759            synchronized (mProcessCpuThread) {
12760                final int N = mProcessCpuTracker.countStats();
12761                for (int i=0; i<N; i++) {
12762                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12763                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12764                        if (mi == null) {
12765                            mi = new Debug.MemoryInfo();
12766                        }
12767                        if (!brief && !oomOnly) {
12768                            Debug.getMemoryInfo(st.pid, mi);
12769                        } else {
12770                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12771                            mi.nativePrivateDirty = (int)tmpLong[0];
12772                        }
12773
12774                        final long myTotalPss = mi.getTotalPss();
12775                        totalPss += myTotalPss;
12776                        nativeProcTotalPss += myTotalPss;
12777
12778                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12779                                st.name, myTotalPss, st.pid, false);
12780                        procMems.add(pssItem);
12781
12782                        nativePss += mi.nativePss;
12783                        dalvikPss += mi.dalvikPss;
12784                        otherPss += mi.otherPss;
12785                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12786                            long mem = mi.getOtherPss(j);
12787                            miscPss[j] += mem;
12788                            otherPss -= mem;
12789                        }
12790                        oomPss[0] += myTotalPss;
12791                        if (oomProcs[0] == null) {
12792                            oomProcs[0] = new ArrayList<MemItem>();
12793                        }
12794                        oomProcs[0].add(pssItem);
12795                    }
12796                }
12797            }
12798
12799            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12800
12801            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12802            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12803            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12804            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12805                String label = Debug.MemoryInfo.getOtherLabel(j);
12806                catMems.add(new MemItem(label, label, miscPss[j], j));
12807            }
12808
12809            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12810            for (int j=0; j<oomPss.length; j++) {
12811                if (oomPss[j] != 0) {
12812                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12813                            : DUMP_MEM_OOM_LABEL[j];
12814                    MemItem item = new MemItem(label, label, oomPss[j],
12815                            DUMP_MEM_OOM_ADJ[j]);
12816                    item.subitems = oomProcs[j];
12817                    oomMems.add(item);
12818                }
12819            }
12820
12821            if (!brief && !oomOnly && !isCompact) {
12822                pw.println();
12823                pw.println("Total PSS by process:");
12824                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12825                pw.println();
12826            }
12827            if (!isCompact) {
12828                pw.println("Total PSS by OOM adjustment:");
12829            }
12830            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12831            if (!brief && !oomOnly) {
12832                PrintWriter out = categoryPw != null ? categoryPw : pw;
12833                if (!isCompact) {
12834                    out.println();
12835                    out.println("Total PSS by category:");
12836                }
12837                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12838            }
12839            if (!isCompact) {
12840                pw.println();
12841            }
12842            MemInfoReader memInfo = new MemInfoReader();
12843            memInfo.readMemInfo();
12844            if (nativeProcTotalPss > 0) {
12845                synchronized (this) {
12846                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
12847                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
12848                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
12849                            nativeProcTotalPss);
12850                }
12851            }
12852            if (!brief) {
12853                if (!isCompact) {
12854                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12855                    pw.print(" kB (status ");
12856                    switch (mLastMemoryLevel) {
12857                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12858                            pw.println("normal)");
12859                            break;
12860                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12861                            pw.println("moderate)");
12862                            break;
12863                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12864                            pw.println("low)");
12865                            break;
12866                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12867                            pw.println("critical)");
12868                            break;
12869                        default:
12870                            pw.print(mLastMemoryLevel);
12871                            pw.println(")");
12872                            break;
12873                    }
12874                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12875                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12876                            pw.print(cachedPss); pw.print(" cached pss + ");
12877                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12878                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12879                } else {
12880                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12881                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12882                            + memInfo.getFreeSizeKb()); pw.print(",");
12883                    pw.println(totalPss - cachedPss);
12884                }
12885            }
12886            if (!isCompact) {
12887                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12888                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12889                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12890                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12891                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12892                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12893                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12894                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12895                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12896                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12897                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12898            }
12899            if (!brief) {
12900                if (memInfo.getZramTotalSizeKb() != 0) {
12901                    if (!isCompact) {
12902                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12903                                pw.print(" kB physical used for ");
12904                                pw.print(memInfo.getSwapTotalSizeKb()
12905                                        - memInfo.getSwapFreeSizeKb());
12906                                pw.print(" kB in swap (");
12907                                pw.print(memInfo.getSwapTotalSizeKb());
12908                                pw.println(" kB total swap)");
12909                    } else {
12910                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12911                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12912                                pw.println(memInfo.getSwapFreeSizeKb());
12913                    }
12914                }
12915                final int[] SINGLE_LONG_FORMAT = new int[] {
12916                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12917                };
12918                long[] longOut = new long[1];
12919                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12920                        SINGLE_LONG_FORMAT, null, longOut, null);
12921                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12922                longOut[0] = 0;
12923                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12924                        SINGLE_LONG_FORMAT, null, longOut, null);
12925                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12926                longOut[0] = 0;
12927                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12928                        SINGLE_LONG_FORMAT, null, longOut, null);
12929                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12930                longOut[0] = 0;
12931                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12932                        SINGLE_LONG_FORMAT, null, longOut, null);
12933                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12934                if (!isCompact) {
12935                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12936                        pw.print("      KSM: "); pw.print(sharing);
12937                                pw.print(" kB saved from shared ");
12938                                pw.print(shared); pw.println(" kB");
12939                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12940                                pw.print(voltile); pw.println(" kB volatile");
12941                    }
12942                    pw.print("   Tuning: ");
12943                    pw.print(ActivityManager.staticGetMemoryClass());
12944                    pw.print(" (large ");
12945                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12946                    pw.print("), oom ");
12947                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12948                    pw.print(" kB");
12949                    pw.print(", restore limit ");
12950                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12951                    pw.print(" kB");
12952                    if (ActivityManager.isLowRamDeviceStatic()) {
12953                        pw.print(" (low-ram)");
12954                    }
12955                    if (ActivityManager.isHighEndGfx()) {
12956                        pw.print(" (high-end-gfx)");
12957                    }
12958                    pw.println();
12959                } else {
12960                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12961                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12962                    pw.println(voltile);
12963                    pw.print("tuning,");
12964                    pw.print(ActivityManager.staticGetMemoryClass());
12965                    pw.print(',');
12966                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12967                    pw.print(',');
12968                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12969                    if (ActivityManager.isLowRamDeviceStatic()) {
12970                        pw.print(",low-ram");
12971                    }
12972                    if (ActivityManager.isHighEndGfx()) {
12973                        pw.print(",high-end-gfx");
12974                    }
12975                    pw.println();
12976                }
12977            }
12978        }
12979    }
12980
12981    /**
12982     * Searches array of arguments for the specified string
12983     * @param args array of argument strings
12984     * @param value value to search for
12985     * @return true if the value is contained in the array
12986     */
12987    private static boolean scanArgs(String[] args, String value) {
12988        if (args != null) {
12989            for (String arg : args) {
12990                if (value.equals(arg)) {
12991                    return true;
12992                }
12993            }
12994        }
12995        return false;
12996    }
12997
12998    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12999            ContentProviderRecord cpr, boolean always) {
13000        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13001
13002        if (!inLaunching || always) {
13003            synchronized (cpr) {
13004                cpr.launchingApp = null;
13005                cpr.notifyAll();
13006            }
13007            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13008            String names[] = cpr.info.authority.split(";");
13009            for (int j = 0; j < names.length; j++) {
13010                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13011            }
13012        }
13013
13014        for (int i=0; i<cpr.connections.size(); i++) {
13015            ContentProviderConnection conn = cpr.connections.get(i);
13016            if (conn.waiting) {
13017                // If this connection is waiting for the provider, then we don't
13018                // need to mess with its process unless we are always removing
13019                // or for some reason the provider is not currently launching.
13020                if (inLaunching && !always) {
13021                    continue;
13022                }
13023            }
13024            ProcessRecord capp = conn.client;
13025            conn.dead = true;
13026            if (conn.stableCount > 0) {
13027                if (!capp.persistent && capp.thread != null
13028                        && capp.pid != 0
13029                        && capp.pid != MY_PID) {
13030                    killUnneededProcessLocked(capp, "depends on provider "
13031                            + cpr.name.flattenToShortString()
13032                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13033                }
13034            } else if (capp.thread != null && conn.provider.provider != null) {
13035                try {
13036                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13037                } catch (RemoteException e) {
13038                }
13039                // In the protocol here, we don't expect the client to correctly
13040                // clean up this connection, we'll just remove it.
13041                cpr.connections.remove(i);
13042                conn.client.conProviders.remove(conn);
13043            }
13044        }
13045
13046        if (inLaunching && always) {
13047            mLaunchingProviders.remove(cpr);
13048        }
13049        return inLaunching;
13050    }
13051
13052    /**
13053     * Main code for cleaning up a process when it has gone away.  This is
13054     * called both as a result of the process dying, or directly when stopping
13055     * a process when running in single process mode.
13056     */
13057    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13058            boolean restarting, boolean allowRestart, int index) {
13059        if (index >= 0) {
13060            removeLruProcessLocked(app);
13061            ProcessList.remove(app.pid);
13062        }
13063
13064        mProcessesToGc.remove(app);
13065        mPendingPssProcesses.remove(app);
13066
13067        // Dismiss any open dialogs.
13068        if (app.crashDialog != null && !app.forceCrashReport) {
13069            app.crashDialog.dismiss();
13070            app.crashDialog = null;
13071        }
13072        if (app.anrDialog != null) {
13073            app.anrDialog.dismiss();
13074            app.anrDialog = null;
13075        }
13076        if (app.waitDialog != null) {
13077            app.waitDialog.dismiss();
13078            app.waitDialog = null;
13079        }
13080
13081        app.crashing = false;
13082        app.notResponding = false;
13083
13084        app.resetPackageList(mProcessStats);
13085        app.unlinkDeathRecipient();
13086        app.makeInactive(mProcessStats);
13087        app.waitingToKill = null;
13088        app.forcingToForeground = null;
13089        updateProcessForegroundLocked(app, false, false);
13090        app.foregroundActivities = false;
13091        app.hasShownUi = false;
13092        app.treatLikeActivity = false;
13093        app.hasAboveClient = false;
13094        app.hasClientActivities = false;
13095
13096        mServices.killServicesLocked(app, allowRestart);
13097
13098        boolean restart = false;
13099
13100        // Remove published content providers.
13101        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13102            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13103            final boolean always = app.bad || !allowRestart;
13104            if (removeDyingProviderLocked(app, cpr, always) || always) {
13105                // We left the provider in the launching list, need to
13106                // restart it.
13107                restart = true;
13108            }
13109
13110            cpr.provider = null;
13111            cpr.proc = null;
13112        }
13113        app.pubProviders.clear();
13114
13115        // Take care of any launching providers waiting for this process.
13116        if (checkAppInLaunchingProvidersLocked(app, false)) {
13117            restart = true;
13118        }
13119
13120        // Unregister from connected content providers.
13121        if (!app.conProviders.isEmpty()) {
13122            for (int i=0; i<app.conProviders.size(); i++) {
13123                ContentProviderConnection conn = app.conProviders.get(i);
13124                conn.provider.connections.remove(conn);
13125            }
13126            app.conProviders.clear();
13127        }
13128
13129        // At this point there may be remaining entries in mLaunchingProviders
13130        // where we were the only one waiting, so they are no longer of use.
13131        // Look for these and clean up if found.
13132        // XXX Commented out for now.  Trying to figure out a way to reproduce
13133        // the actual situation to identify what is actually going on.
13134        if (false) {
13135            for (int i=0; i<mLaunchingProviders.size(); i++) {
13136                ContentProviderRecord cpr = (ContentProviderRecord)
13137                        mLaunchingProviders.get(i);
13138                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13139                    synchronized (cpr) {
13140                        cpr.launchingApp = null;
13141                        cpr.notifyAll();
13142                    }
13143                }
13144            }
13145        }
13146
13147        skipCurrentReceiverLocked(app);
13148
13149        // Unregister any receivers.
13150        for (int i=app.receivers.size()-1; i>=0; i--) {
13151            removeReceiverLocked(app.receivers.valueAt(i));
13152        }
13153        app.receivers.clear();
13154
13155        // If the app is undergoing backup, tell the backup manager about it
13156        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13157            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13158                    + mBackupTarget.appInfo + " died during backup");
13159            try {
13160                IBackupManager bm = IBackupManager.Stub.asInterface(
13161                        ServiceManager.getService(Context.BACKUP_SERVICE));
13162                bm.agentDisconnected(app.info.packageName);
13163            } catch (RemoteException e) {
13164                // can't happen; backup manager is local
13165            }
13166        }
13167
13168        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13169            ProcessChangeItem item = mPendingProcessChanges.get(i);
13170            if (item.pid == app.pid) {
13171                mPendingProcessChanges.remove(i);
13172                mAvailProcessChanges.add(item);
13173            }
13174        }
13175        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13176
13177        // If the caller is restarting this app, then leave it in its
13178        // current lists and let the caller take care of it.
13179        if (restarting) {
13180            return;
13181        }
13182
13183        if (!app.persistent || app.isolated) {
13184            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13185                    "Removing non-persistent process during cleanup: " + app);
13186            mProcessNames.remove(app.processName, app.uid);
13187            mIsolatedProcesses.remove(app.uid);
13188            if (mHeavyWeightProcess == app) {
13189                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13190                        mHeavyWeightProcess.userId, 0));
13191                mHeavyWeightProcess = null;
13192            }
13193        } else if (!app.removed) {
13194            // This app is persistent, so we need to keep its record around.
13195            // If it is not already on the pending app list, add it there
13196            // and start a new process for it.
13197            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13198                mPersistentStartingProcesses.add(app);
13199                restart = true;
13200            }
13201        }
13202        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13203                "Clean-up removing on hold: " + app);
13204        mProcessesOnHold.remove(app);
13205
13206        if (app == mHomeProcess) {
13207            mHomeProcess = null;
13208        }
13209        if (app == mPreviousProcess) {
13210            mPreviousProcess = null;
13211        }
13212
13213        if (restart && !app.isolated) {
13214            // We have components that still need to be running in the
13215            // process, so re-launch it.
13216            mProcessNames.put(app.processName, app.uid, app);
13217            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13218        } else if (app.pid > 0 && app.pid != MY_PID) {
13219            // Goodbye!
13220            boolean removed;
13221            synchronized (mPidsSelfLocked) {
13222                mPidsSelfLocked.remove(app.pid);
13223                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13224            }
13225            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13226                    app.processName, app.info.uid);
13227            if (app.isolated) {
13228                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13229            }
13230            app.setPid(0);
13231        }
13232    }
13233
13234    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13235        // Look through the content providers we are waiting to have launched,
13236        // and if any run in this process then either schedule a restart of
13237        // the process or kill the client waiting for it if this process has
13238        // gone bad.
13239        int NL = mLaunchingProviders.size();
13240        boolean restart = false;
13241        for (int i=0; i<NL; i++) {
13242            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13243            if (cpr.launchingApp == app) {
13244                if (!alwaysBad && !app.bad) {
13245                    restart = true;
13246                } else {
13247                    removeDyingProviderLocked(app, cpr, true);
13248                    // cpr should have been removed from mLaunchingProviders
13249                    NL = mLaunchingProviders.size();
13250                    i--;
13251                }
13252            }
13253        }
13254        return restart;
13255    }
13256
13257    // =========================================================
13258    // SERVICES
13259    // =========================================================
13260
13261    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13262            int flags) {
13263        enforceNotIsolatedCaller("getServices");
13264        synchronized (this) {
13265            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13266        }
13267    }
13268
13269    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13270        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13271        synchronized (this) {
13272            return mServices.getRunningServiceControlPanelLocked(name);
13273        }
13274    }
13275
13276    public ComponentName startService(IApplicationThread caller, Intent service,
13277            String resolvedType, int userId) {
13278        enforceNotIsolatedCaller("startService");
13279        // Refuse possible leaked file descriptors
13280        if (service != null && service.hasFileDescriptors() == true) {
13281            throw new IllegalArgumentException("File descriptors passed in Intent");
13282        }
13283
13284        if (DEBUG_SERVICE)
13285            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13286        synchronized(this) {
13287            final int callingPid = Binder.getCallingPid();
13288            final int callingUid = Binder.getCallingUid();
13289            final long origId = Binder.clearCallingIdentity();
13290            ComponentName res = mServices.startServiceLocked(caller, service,
13291                    resolvedType, callingPid, callingUid, userId);
13292            Binder.restoreCallingIdentity(origId);
13293            return res;
13294        }
13295    }
13296
13297    ComponentName startServiceInPackage(int uid,
13298            Intent service, String resolvedType, int userId) {
13299        synchronized(this) {
13300            if (DEBUG_SERVICE)
13301                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13302            final long origId = Binder.clearCallingIdentity();
13303            ComponentName res = mServices.startServiceLocked(null, service,
13304                    resolvedType, -1, uid, userId);
13305            Binder.restoreCallingIdentity(origId);
13306            return res;
13307        }
13308    }
13309
13310    public int stopService(IApplicationThread caller, Intent service,
13311            String resolvedType, int userId) {
13312        enforceNotIsolatedCaller("stopService");
13313        // Refuse possible leaked file descriptors
13314        if (service != null && service.hasFileDescriptors() == true) {
13315            throw new IllegalArgumentException("File descriptors passed in Intent");
13316        }
13317
13318        synchronized(this) {
13319            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13320        }
13321    }
13322
13323    public IBinder peekService(Intent service, String resolvedType) {
13324        enforceNotIsolatedCaller("peekService");
13325        // Refuse possible leaked file descriptors
13326        if (service != null && service.hasFileDescriptors() == true) {
13327            throw new IllegalArgumentException("File descriptors passed in Intent");
13328        }
13329        synchronized(this) {
13330            return mServices.peekServiceLocked(service, resolvedType);
13331        }
13332    }
13333
13334    public boolean stopServiceToken(ComponentName className, IBinder token,
13335            int startId) {
13336        synchronized(this) {
13337            return mServices.stopServiceTokenLocked(className, token, startId);
13338        }
13339    }
13340
13341    public void setServiceForeground(ComponentName className, IBinder token,
13342            int id, Notification notification, boolean removeNotification) {
13343        synchronized(this) {
13344            mServices.setServiceForegroundLocked(className, token, id, notification,
13345                    removeNotification);
13346        }
13347    }
13348
13349    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13350            boolean requireFull, String name, String callerPackage) {
13351        final int callingUserId = UserHandle.getUserId(callingUid);
13352        if (callingUserId != userId) {
13353            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13354                if ((requireFull || checkComponentPermission(
13355                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13356                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13357                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13358                                callingPid, callingUid, -1, true)
13359                                != PackageManager.PERMISSION_GRANTED) {
13360                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13361                        // In this case, they would like to just execute as their
13362                        // owner user instead of failing.
13363                        userId = callingUserId;
13364                    } else {
13365                        StringBuilder builder = new StringBuilder(128);
13366                        builder.append("Permission Denial: ");
13367                        builder.append(name);
13368                        if (callerPackage != null) {
13369                            builder.append(" from ");
13370                            builder.append(callerPackage);
13371                        }
13372                        builder.append(" asks to run as user ");
13373                        builder.append(userId);
13374                        builder.append(" but is calling from user ");
13375                        builder.append(UserHandle.getUserId(callingUid));
13376                        builder.append("; this requires ");
13377                        builder.append(INTERACT_ACROSS_USERS_FULL);
13378                        if (!requireFull) {
13379                            builder.append(" or ");
13380                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13381                        }
13382                        String msg = builder.toString();
13383                        Slog.w(TAG, msg);
13384                        throw new SecurityException(msg);
13385                    }
13386                }
13387            }
13388            if (userId == UserHandle.USER_CURRENT
13389                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13390                // Note that we may be accessing this outside of a lock...
13391                // shouldn't be a big deal, if this is being called outside
13392                // of a locked context there is intrinsically a race with
13393                // the value the caller will receive and someone else changing it.
13394                userId = mCurrentUserId;
13395            }
13396            if (!allowAll && userId < 0) {
13397                throw new IllegalArgumentException(
13398                        "Call does not support special user #" + userId);
13399            }
13400        }
13401        return userId;
13402    }
13403
13404    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13405            String className, int flags) {
13406        boolean result = false;
13407        // For apps that don't have pre-defined UIDs, check for permission
13408        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13409            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13410                if (ActivityManager.checkUidPermission(
13411                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13412                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13413                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13414                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13415                            + " requests FLAG_SINGLE_USER, but app does not hold "
13416                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13417                    Slog.w(TAG, msg);
13418                    throw new SecurityException(msg);
13419                }
13420                // Permission passed
13421                result = true;
13422            }
13423        } else if ("system".equals(componentProcessName)) {
13424            result = true;
13425        } else {
13426            // App with pre-defined UID, check if it's a persistent app
13427            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13428        }
13429        if (DEBUG_MU) {
13430            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13431                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13432        }
13433        return result;
13434    }
13435
13436    /**
13437     * Checks to see if the caller is in the same app as the singleton
13438     * component, or the component is in a special app. It allows special apps
13439     * to export singleton components but prevents exporting singleton
13440     * components for regular apps.
13441     */
13442    boolean isValidSingletonCall(int callingUid, int componentUid) {
13443        int componentAppId = UserHandle.getAppId(componentUid);
13444        return UserHandle.isSameApp(callingUid, componentUid)
13445                || componentAppId == Process.SYSTEM_UID
13446                || componentAppId == Process.PHONE_UID
13447                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13448                        == PackageManager.PERMISSION_GRANTED;
13449    }
13450
13451    public int bindService(IApplicationThread caller, IBinder token,
13452            Intent service, String resolvedType,
13453            IServiceConnection connection, int flags, int userId) {
13454        enforceNotIsolatedCaller("bindService");
13455        // Refuse possible leaked file descriptors
13456        if (service != null && service.hasFileDescriptors() == true) {
13457            throw new IllegalArgumentException("File descriptors passed in Intent");
13458        }
13459
13460        synchronized(this) {
13461            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13462                    connection, flags, userId);
13463        }
13464    }
13465
13466    public boolean unbindService(IServiceConnection connection) {
13467        synchronized (this) {
13468            return mServices.unbindServiceLocked(connection);
13469        }
13470    }
13471
13472    public void publishService(IBinder token, Intent intent, IBinder service) {
13473        // Refuse possible leaked file descriptors
13474        if (intent != null && intent.hasFileDescriptors() == true) {
13475            throw new IllegalArgumentException("File descriptors passed in Intent");
13476        }
13477
13478        synchronized(this) {
13479            if (!(token instanceof ServiceRecord)) {
13480                throw new IllegalArgumentException("Invalid service token");
13481            }
13482            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13483        }
13484    }
13485
13486    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13487        // Refuse possible leaked file descriptors
13488        if (intent != null && intent.hasFileDescriptors() == true) {
13489            throw new IllegalArgumentException("File descriptors passed in Intent");
13490        }
13491
13492        synchronized(this) {
13493            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13494        }
13495    }
13496
13497    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13498        synchronized(this) {
13499            if (!(token instanceof ServiceRecord)) {
13500                throw new IllegalArgumentException("Invalid service token");
13501            }
13502            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13503        }
13504    }
13505
13506    // =========================================================
13507    // BACKUP AND RESTORE
13508    // =========================================================
13509
13510    // Cause the target app to be launched if necessary and its backup agent
13511    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13512    // activity manager to announce its creation.
13513    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13514        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13515        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13516
13517        synchronized(this) {
13518            // !!! TODO: currently no check here that we're already bound
13519            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13520            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13521            synchronized (stats) {
13522                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13523            }
13524
13525            // Backup agent is now in use, its package can't be stopped.
13526            try {
13527                AppGlobals.getPackageManager().setPackageStoppedState(
13528                        app.packageName, false, UserHandle.getUserId(app.uid));
13529            } catch (RemoteException e) {
13530            } catch (IllegalArgumentException e) {
13531                Slog.w(TAG, "Failed trying to unstop package "
13532                        + app.packageName + ": " + e);
13533            }
13534
13535            BackupRecord r = new BackupRecord(ss, app, backupMode);
13536            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13537                    ? new ComponentName(app.packageName, app.backupAgentName)
13538                    : new ComponentName("android", "FullBackupAgent");
13539            // startProcessLocked() returns existing proc's record if it's already running
13540            ProcessRecord proc = startProcessLocked(app.processName, app,
13541                    false, 0, "backup", hostingName, false, false, false);
13542            if (proc == null) {
13543                Slog.e(TAG, "Unable to start backup agent process " + r);
13544                return false;
13545            }
13546
13547            r.app = proc;
13548            mBackupTarget = r;
13549            mBackupAppName = app.packageName;
13550
13551            // Try not to kill the process during backup
13552            updateOomAdjLocked(proc);
13553
13554            // If the process is already attached, schedule the creation of the backup agent now.
13555            // If it is not yet live, this will be done when it attaches to the framework.
13556            if (proc.thread != null) {
13557                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13558                try {
13559                    proc.thread.scheduleCreateBackupAgent(app,
13560                            compatibilityInfoForPackageLocked(app), backupMode);
13561                } catch (RemoteException e) {
13562                    // Will time out on the backup manager side
13563                }
13564            } else {
13565                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13566            }
13567            // Invariants: at this point, the target app process exists and the application
13568            // is either already running or in the process of coming up.  mBackupTarget and
13569            // mBackupAppName describe the app, so that when it binds back to the AM we
13570            // know that it's scheduled for a backup-agent operation.
13571        }
13572
13573        return true;
13574    }
13575
13576    @Override
13577    public void clearPendingBackup() {
13578        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13579        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13580
13581        synchronized (this) {
13582            mBackupTarget = null;
13583            mBackupAppName = null;
13584        }
13585    }
13586
13587    // A backup agent has just come up
13588    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13589        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13590                + " = " + agent);
13591
13592        synchronized(this) {
13593            if (!agentPackageName.equals(mBackupAppName)) {
13594                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13595                return;
13596            }
13597        }
13598
13599        long oldIdent = Binder.clearCallingIdentity();
13600        try {
13601            IBackupManager bm = IBackupManager.Stub.asInterface(
13602                    ServiceManager.getService(Context.BACKUP_SERVICE));
13603            bm.agentConnected(agentPackageName, agent);
13604        } catch (RemoteException e) {
13605            // can't happen; the backup manager service is local
13606        } catch (Exception e) {
13607            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13608            e.printStackTrace();
13609        } finally {
13610            Binder.restoreCallingIdentity(oldIdent);
13611        }
13612    }
13613
13614    // done with this agent
13615    public void unbindBackupAgent(ApplicationInfo appInfo) {
13616        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13617        if (appInfo == null) {
13618            Slog.w(TAG, "unbind backup agent for null app");
13619            return;
13620        }
13621
13622        synchronized(this) {
13623            try {
13624                if (mBackupAppName == null) {
13625                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13626                    return;
13627                }
13628
13629                if (!mBackupAppName.equals(appInfo.packageName)) {
13630                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13631                    return;
13632                }
13633
13634                // Not backing this app up any more; reset its OOM adjustment
13635                final ProcessRecord proc = mBackupTarget.app;
13636                updateOomAdjLocked(proc);
13637
13638                // If the app crashed during backup, 'thread' will be null here
13639                if (proc.thread != null) {
13640                    try {
13641                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13642                                compatibilityInfoForPackageLocked(appInfo));
13643                    } catch (Exception e) {
13644                        Slog.e(TAG, "Exception when unbinding backup agent:");
13645                        e.printStackTrace();
13646                    }
13647                }
13648            } finally {
13649                mBackupTarget = null;
13650                mBackupAppName = null;
13651            }
13652        }
13653    }
13654    // =========================================================
13655    // BROADCASTS
13656    // =========================================================
13657
13658    private final List getStickiesLocked(String action, IntentFilter filter,
13659            List cur, int userId) {
13660        final ContentResolver resolver = mContext.getContentResolver();
13661        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13662        if (stickies == null) {
13663            return cur;
13664        }
13665        final ArrayList<Intent> list = stickies.get(action);
13666        if (list == null) {
13667            return cur;
13668        }
13669        int N = list.size();
13670        for (int i=0; i<N; i++) {
13671            Intent intent = list.get(i);
13672            if (filter.match(resolver, intent, true, TAG) >= 0) {
13673                if (cur == null) {
13674                    cur = new ArrayList<Intent>();
13675                }
13676                cur.add(intent);
13677            }
13678        }
13679        return cur;
13680    }
13681
13682    boolean isPendingBroadcastProcessLocked(int pid) {
13683        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13684                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13685    }
13686
13687    void skipPendingBroadcastLocked(int pid) {
13688            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13689            for (BroadcastQueue queue : mBroadcastQueues) {
13690                queue.skipPendingBroadcastLocked(pid);
13691            }
13692    }
13693
13694    // The app just attached; send any pending broadcasts that it should receive
13695    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13696        boolean didSomething = false;
13697        for (BroadcastQueue queue : mBroadcastQueues) {
13698            didSomething |= queue.sendPendingBroadcastsLocked(app);
13699        }
13700        return didSomething;
13701    }
13702
13703    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13704            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13705        enforceNotIsolatedCaller("registerReceiver");
13706        int callingUid;
13707        int callingPid;
13708        synchronized(this) {
13709            ProcessRecord callerApp = null;
13710            if (caller != null) {
13711                callerApp = getRecordForAppLocked(caller);
13712                if (callerApp == null) {
13713                    throw new SecurityException(
13714                            "Unable to find app for caller " + caller
13715                            + " (pid=" + Binder.getCallingPid()
13716                            + ") when registering receiver " + receiver);
13717                }
13718                if (callerApp.info.uid != Process.SYSTEM_UID &&
13719                        !callerApp.pkgList.containsKey(callerPackage) &&
13720                        !"android".equals(callerPackage)) {
13721                    throw new SecurityException("Given caller package " + callerPackage
13722                            + " is not running in process " + callerApp);
13723                }
13724                callingUid = callerApp.info.uid;
13725                callingPid = callerApp.pid;
13726            } else {
13727                callerPackage = null;
13728                callingUid = Binder.getCallingUid();
13729                callingPid = Binder.getCallingPid();
13730            }
13731
13732            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13733                    true, true, "registerReceiver", callerPackage);
13734
13735            List allSticky = null;
13736
13737            // Look for any matching sticky broadcasts...
13738            Iterator actions = filter.actionsIterator();
13739            if (actions != null) {
13740                while (actions.hasNext()) {
13741                    String action = (String)actions.next();
13742                    allSticky = getStickiesLocked(action, filter, allSticky,
13743                            UserHandle.USER_ALL);
13744                    allSticky = getStickiesLocked(action, filter, allSticky,
13745                            UserHandle.getUserId(callingUid));
13746                }
13747            } else {
13748                allSticky = getStickiesLocked(null, filter, allSticky,
13749                        UserHandle.USER_ALL);
13750                allSticky = getStickiesLocked(null, filter, allSticky,
13751                        UserHandle.getUserId(callingUid));
13752            }
13753
13754            // The first sticky in the list is returned directly back to
13755            // the client.
13756            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13757
13758            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13759                    + ": " + sticky);
13760
13761            if (receiver == null) {
13762                return sticky;
13763            }
13764
13765            ReceiverList rl
13766                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13767            if (rl == null) {
13768                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13769                        userId, receiver);
13770                if (rl.app != null) {
13771                    rl.app.receivers.add(rl);
13772                } else {
13773                    try {
13774                        receiver.asBinder().linkToDeath(rl, 0);
13775                    } catch (RemoteException e) {
13776                        return sticky;
13777                    }
13778                    rl.linkedToDeath = true;
13779                }
13780                mRegisteredReceivers.put(receiver.asBinder(), rl);
13781            } else if (rl.uid != callingUid) {
13782                throw new IllegalArgumentException(
13783                        "Receiver requested to register for uid " + callingUid
13784                        + " was previously registered for uid " + rl.uid);
13785            } else if (rl.pid != callingPid) {
13786                throw new IllegalArgumentException(
13787                        "Receiver requested to register for pid " + callingPid
13788                        + " was previously registered for pid " + rl.pid);
13789            } else if (rl.userId != userId) {
13790                throw new IllegalArgumentException(
13791                        "Receiver requested to register for user " + userId
13792                        + " was previously registered for user " + rl.userId);
13793            }
13794            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13795                    permission, callingUid, userId);
13796            rl.add(bf);
13797            if (!bf.debugCheck()) {
13798                Slog.w(TAG, "==> For Dynamic broadast");
13799            }
13800            mReceiverResolver.addFilter(bf);
13801
13802            // Enqueue broadcasts for all existing stickies that match
13803            // this filter.
13804            if (allSticky != null) {
13805                ArrayList receivers = new ArrayList();
13806                receivers.add(bf);
13807
13808                int N = allSticky.size();
13809                for (int i=0; i<N; i++) {
13810                    Intent intent = (Intent)allSticky.get(i);
13811                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13812                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13813                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13814                            null, null, false, true, true, -1);
13815                    queue.enqueueParallelBroadcastLocked(r);
13816                    queue.scheduleBroadcastsLocked();
13817                }
13818            }
13819
13820            return sticky;
13821        }
13822    }
13823
13824    public void unregisterReceiver(IIntentReceiver receiver) {
13825        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13826
13827        final long origId = Binder.clearCallingIdentity();
13828        try {
13829            boolean doTrim = false;
13830
13831            synchronized(this) {
13832                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13833                if (rl != null) {
13834                    if (rl.curBroadcast != null) {
13835                        BroadcastRecord r = rl.curBroadcast;
13836                        final boolean doNext = finishReceiverLocked(
13837                                receiver.asBinder(), r.resultCode, r.resultData,
13838                                r.resultExtras, r.resultAbort);
13839                        if (doNext) {
13840                            doTrim = true;
13841                            r.queue.processNextBroadcast(false);
13842                        }
13843                    }
13844
13845                    if (rl.app != null) {
13846                        rl.app.receivers.remove(rl);
13847                    }
13848                    removeReceiverLocked(rl);
13849                    if (rl.linkedToDeath) {
13850                        rl.linkedToDeath = false;
13851                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13852                    }
13853                }
13854            }
13855
13856            // If we actually concluded any broadcasts, we might now be able
13857            // to trim the recipients' apps from our working set
13858            if (doTrim) {
13859                trimApplications();
13860                return;
13861            }
13862
13863        } finally {
13864            Binder.restoreCallingIdentity(origId);
13865        }
13866    }
13867
13868    void removeReceiverLocked(ReceiverList rl) {
13869        mRegisteredReceivers.remove(rl.receiver.asBinder());
13870        int N = rl.size();
13871        for (int i=0; i<N; i++) {
13872            mReceiverResolver.removeFilter(rl.get(i));
13873        }
13874    }
13875
13876    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13877        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13878            ProcessRecord r = mLruProcesses.get(i);
13879            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13880                try {
13881                    r.thread.dispatchPackageBroadcast(cmd, packages);
13882                } catch (RemoteException ex) {
13883                }
13884            }
13885        }
13886    }
13887
13888    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13889            int[] users) {
13890        List<ResolveInfo> receivers = null;
13891        try {
13892            HashSet<ComponentName> singleUserReceivers = null;
13893            boolean scannedFirstReceivers = false;
13894            for (int user : users) {
13895                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13896                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13897                if (user != 0 && newReceivers != null) {
13898                    // If this is not the primary user, we need to check for
13899                    // any receivers that should be filtered out.
13900                    for (int i=0; i<newReceivers.size(); i++) {
13901                        ResolveInfo ri = newReceivers.get(i);
13902                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13903                            newReceivers.remove(i);
13904                            i--;
13905                        }
13906                    }
13907                }
13908                if (newReceivers != null && newReceivers.size() == 0) {
13909                    newReceivers = null;
13910                }
13911                if (receivers == null) {
13912                    receivers = newReceivers;
13913                } else if (newReceivers != null) {
13914                    // We need to concatenate the additional receivers
13915                    // found with what we have do far.  This would be easy,
13916                    // but we also need to de-dup any receivers that are
13917                    // singleUser.
13918                    if (!scannedFirstReceivers) {
13919                        // Collect any single user receivers we had already retrieved.
13920                        scannedFirstReceivers = true;
13921                        for (int i=0; i<receivers.size(); i++) {
13922                            ResolveInfo ri = receivers.get(i);
13923                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13924                                ComponentName cn = new ComponentName(
13925                                        ri.activityInfo.packageName, ri.activityInfo.name);
13926                                if (singleUserReceivers == null) {
13927                                    singleUserReceivers = new HashSet<ComponentName>();
13928                                }
13929                                singleUserReceivers.add(cn);
13930                            }
13931                        }
13932                    }
13933                    // Add the new results to the existing results, tracking
13934                    // and de-dupping single user receivers.
13935                    for (int i=0; i<newReceivers.size(); i++) {
13936                        ResolveInfo ri = newReceivers.get(i);
13937                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13938                            ComponentName cn = new ComponentName(
13939                                    ri.activityInfo.packageName, ri.activityInfo.name);
13940                            if (singleUserReceivers == null) {
13941                                singleUserReceivers = new HashSet<ComponentName>();
13942                            }
13943                            if (!singleUserReceivers.contains(cn)) {
13944                                singleUserReceivers.add(cn);
13945                                receivers.add(ri);
13946                            }
13947                        } else {
13948                            receivers.add(ri);
13949                        }
13950                    }
13951                }
13952            }
13953        } catch (RemoteException ex) {
13954            // pm is in same process, this will never happen.
13955        }
13956        return receivers;
13957    }
13958
13959    private final int broadcastIntentLocked(ProcessRecord callerApp,
13960            String callerPackage, Intent intent, String resolvedType,
13961            IIntentReceiver resultTo, int resultCode, String resultData,
13962            Bundle map, String requiredPermission, int appOp,
13963            boolean ordered, boolean sticky, int callingPid, int callingUid,
13964            int userId) {
13965        intent = new Intent(intent);
13966
13967        // By default broadcasts do not go to stopped apps.
13968        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13969
13970        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13971            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13972            + " ordered=" + ordered + " userid=" + userId);
13973        if ((resultTo != null) && !ordered) {
13974            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13975        }
13976
13977        userId = handleIncomingUser(callingPid, callingUid, userId,
13978                true, false, "broadcast", callerPackage);
13979
13980        // Make sure that the user who is receiving this broadcast is started.
13981        // If not, we will just skip it.
13982
13983
13984        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13985            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13986                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13987                Slog.w(TAG, "Skipping broadcast of " + intent
13988                        + ": user " + userId + " is stopped");
13989                return ActivityManager.BROADCAST_SUCCESS;
13990            }
13991        }
13992
13993        /*
13994         * Prevent non-system code (defined here to be non-persistent
13995         * processes) from sending protected broadcasts.
13996         */
13997        int callingAppId = UserHandle.getAppId(callingUid);
13998        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13999            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14000            || callingAppId == Process.NFC_UID || callingUid == 0) {
14001            // Always okay.
14002        } else if (callerApp == null || !callerApp.persistent) {
14003            try {
14004                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14005                        intent.getAction())) {
14006                    String msg = "Permission Denial: not allowed to send broadcast "
14007                            + intent.getAction() + " from pid="
14008                            + callingPid + ", uid=" + callingUid;
14009                    Slog.w(TAG, msg);
14010                    throw new SecurityException(msg);
14011                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14012                    // Special case for compatibility: we don't want apps to send this,
14013                    // but historically it has not been protected and apps may be using it
14014                    // to poke their own app widget.  So, instead of making it protected,
14015                    // just limit it to the caller.
14016                    if (callerApp == null) {
14017                        String msg = "Permission Denial: not allowed to send broadcast "
14018                                + intent.getAction() + " from unknown caller.";
14019                        Slog.w(TAG, msg);
14020                        throw new SecurityException(msg);
14021                    } else if (intent.getComponent() != null) {
14022                        // They are good enough to send to an explicit component...  verify
14023                        // it is being sent to the calling app.
14024                        if (!intent.getComponent().getPackageName().equals(
14025                                callerApp.info.packageName)) {
14026                            String msg = "Permission Denial: not allowed to send broadcast "
14027                                    + intent.getAction() + " to "
14028                                    + intent.getComponent().getPackageName() + " from "
14029                                    + callerApp.info.packageName;
14030                            Slog.w(TAG, msg);
14031                            throw new SecurityException(msg);
14032                        }
14033                    } else {
14034                        // Limit broadcast to their own package.
14035                        intent.setPackage(callerApp.info.packageName);
14036                    }
14037                }
14038            } catch (RemoteException e) {
14039                Slog.w(TAG, "Remote exception", e);
14040                return ActivityManager.BROADCAST_SUCCESS;
14041            }
14042        }
14043
14044        // Handle special intents: if this broadcast is from the package
14045        // manager about a package being removed, we need to remove all of
14046        // its activities from the history stack.
14047        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14048                intent.getAction());
14049        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14050                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14051                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14052                || uidRemoved) {
14053            if (checkComponentPermission(
14054                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14055                    callingPid, callingUid, -1, true)
14056                    == PackageManager.PERMISSION_GRANTED) {
14057                if (uidRemoved) {
14058                    final Bundle intentExtras = intent.getExtras();
14059                    final int uid = intentExtras != null
14060                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14061                    if (uid >= 0) {
14062                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14063                        synchronized (bs) {
14064                            bs.removeUidStatsLocked(uid);
14065                        }
14066                        mAppOpsService.uidRemoved(uid);
14067                    }
14068                } else {
14069                    // If resources are unavailable just force stop all
14070                    // those packages and flush the attribute cache as well.
14071                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14072                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14073                        if (list != null && (list.length > 0)) {
14074                            for (String pkg : list) {
14075                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14076                                        "storage unmount");
14077                            }
14078                            sendPackageBroadcastLocked(
14079                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14080                        }
14081                    } else {
14082                        Uri data = intent.getData();
14083                        String ssp;
14084                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14085                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14086                                    intent.getAction());
14087                            boolean fullUninstall = removed &&
14088                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14089                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14090                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14091                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14092                                        false, fullUninstall, userId,
14093                                        removed ? "pkg removed" : "pkg changed");
14094                            }
14095                            if (removed) {
14096                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14097                                        new String[] {ssp}, userId);
14098                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14099                                    mAppOpsService.packageRemoved(
14100                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14101
14102                                    // Remove all permissions granted from/to this package
14103                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14104                                }
14105                            }
14106                        }
14107                    }
14108                }
14109            } else {
14110                String msg = "Permission Denial: " + intent.getAction()
14111                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14112                        + ", uid=" + callingUid + ")"
14113                        + " requires "
14114                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14115                Slog.w(TAG, msg);
14116                throw new SecurityException(msg);
14117            }
14118
14119        // Special case for adding a package: by default turn on compatibility
14120        // mode.
14121        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14122            Uri data = intent.getData();
14123            String ssp;
14124            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14125                mCompatModePackages.handlePackageAddedLocked(ssp,
14126                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14127            }
14128        }
14129
14130        /*
14131         * If this is the time zone changed action, queue up a message that will reset the timezone
14132         * of all currently running processes. This message will get queued up before the broadcast
14133         * happens.
14134         */
14135        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14136            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14137        }
14138
14139        /*
14140         * If the user set the time, let all running processes know.
14141         */
14142        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14143            final int is24Hour = intent.getBooleanExtra(
14144                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14145            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14146        }
14147
14148        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14149            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14150        }
14151
14152        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14153            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14154            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14155        }
14156
14157        // Add to the sticky list if requested.
14158        if (sticky) {
14159            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14160                    callingPid, callingUid)
14161                    != PackageManager.PERMISSION_GRANTED) {
14162                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14163                        + callingPid + ", uid=" + callingUid
14164                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14165                Slog.w(TAG, msg);
14166                throw new SecurityException(msg);
14167            }
14168            if (requiredPermission != null) {
14169                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14170                        + " and enforce permission " + requiredPermission);
14171                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14172            }
14173            if (intent.getComponent() != null) {
14174                throw new SecurityException(
14175                        "Sticky broadcasts can't target a specific component");
14176            }
14177            // We use userId directly here, since the "all" target is maintained
14178            // as a separate set of sticky broadcasts.
14179            if (userId != UserHandle.USER_ALL) {
14180                // But first, if this is not a broadcast to all users, then
14181                // make sure it doesn't conflict with an existing broadcast to
14182                // all users.
14183                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14184                        UserHandle.USER_ALL);
14185                if (stickies != null) {
14186                    ArrayList<Intent> list = stickies.get(intent.getAction());
14187                    if (list != null) {
14188                        int N = list.size();
14189                        int i;
14190                        for (i=0; i<N; i++) {
14191                            if (intent.filterEquals(list.get(i))) {
14192                                throw new IllegalArgumentException(
14193                                        "Sticky broadcast " + intent + " for user "
14194                                        + userId + " conflicts with existing global broadcast");
14195                            }
14196                        }
14197                    }
14198                }
14199            }
14200            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14201            if (stickies == null) {
14202                stickies = new ArrayMap<String, ArrayList<Intent>>();
14203                mStickyBroadcasts.put(userId, stickies);
14204            }
14205            ArrayList<Intent> list = stickies.get(intent.getAction());
14206            if (list == null) {
14207                list = new ArrayList<Intent>();
14208                stickies.put(intent.getAction(), list);
14209            }
14210            int N = list.size();
14211            int i;
14212            for (i=0; i<N; i++) {
14213                if (intent.filterEquals(list.get(i))) {
14214                    // This sticky already exists, replace it.
14215                    list.set(i, new Intent(intent));
14216                    break;
14217                }
14218            }
14219            if (i >= N) {
14220                list.add(new Intent(intent));
14221            }
14222        }
14223
14224        int[] users;
14225        if (userId == UserHandle.USER_ALL) {
14226            // Caller wants broadcast to go to all started users.
14227            users = mStartedUserArray;
14228        } else {
14229            // Caller wants broadcast to go to one specific user.
14230            users = new int[] {userId};
14231        }
14232
14233        // Figure out who all will receive this broadcast.
14234        List receivers = null;
14235        List<BroadcastFilter> registeredReceivers = null;
14236        // Need to resolve the intent to interested receivers...
14237        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14238                 == 0) {
14239            receivers = collectReceiverComponents(intent, resolvedType, users);
14240        }
14241        if (intent.getComponent() == null) {
14242            registeredReceivers = mReceiverResolver.queryIntent(intent,
14243                    resolvedType, false, userId);
14244        }
14245
14246        final boolean replacePending =
14247                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14248
14249        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14250                + " replacePending=" + replacePending);
14251
14252        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14253        if (!ordered && NR > 0) {
14254            // If we are not serializing this broadcast, then send the
14255            // registered receivers separately so they don't wait for the
14256            // components to be launched.
14257            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14258            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14259                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14260                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14261                    ordered, sticky, false, userId);
14262            if (DEBUG_BROADCAST) Slog.v(
14263                    TAG, "Enqueueing parallel broadcast " + r);
14264            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14265            if (!replaced) {
14266                queue.enqueueParallelBroadcastLocked(r);
14267                queue.scheduleBroadcastsLocked();
14268            }
14269            registeredReceivers = null;
14270            NR = 0;
14271        }
14272
14273        // Merge into one list.
14274        int ir = 0;
14275        if (receivers != null) {
14276            // A special case for PACKAGE_ADDED: do not allow the package
14277            // being added to see this broadcast.  This prevents them from
14278            // using this as a back door to get run as soon as they are
14279            // installed.  Maybe in the future we want to have a special install
14280            // broadcast or such for apps, but we'd like to deliberately make
14281            // this decision.
14282            String skipPackages[] = null;
14283            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14284                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14285                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14286                Uri data = intent.getData();
14287                if (data != null) {
14288                    String pkgName = data.getSchemeSpecificPart();
14289                    if (pkgName != null) {
14290                        skipPackages = new String[] { pkgName };
14291                    }
14292                }
14293            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14294                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14295            }
14296            if (skipPackages != null && (skipPackages.length > 0)) {
14297                for (String skipPackage : skipPackages) {
14298                    if (skipPackage != null) {
14299                        int NT = receivers.size();
14300                        for (int it=0; it<NT; it++) {
14301                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14302                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14303                                receivers.remove(it);
14304                                it--;
14305                                NT--;
14306                            }
14307                        }
14308                    }
14309                }
14310            }
14311
14312            int NT = receivers != null ? receivers.size() : 0;
14313            int it = 0;
14314            ResolveInfo curt = null;
14315            BroadcastFilter curr = null;
14316            while (it < NT && ir < NR) {
14317                if (curt == null) {
14318                    curt = (ResolveInfo)receivers.get(it);
14319                }
14320                if (curr == null) {
14321                    curr = registeredReceivers.get(ir);
14322                }
14323                if (curr.getPriority() >= curt.priority) {
14324                    // Insert this broadcast record into the final list.
14325                    receivers.add(it, curr);
14326                    ir++;
14327                    curr = null;
14328                    it++;
14329                    NT++;
14330                } else {
14331                    // Skip to the next ResolveInfo in the final list.
14332                    it++;
14333                    curt = null;
14334                }
14335            }
14336        }
14337        while (ir < NR) {
14338            if (receivers == null) {
14339                receivers = new ArrayList();
14340            }
14341            receivers.add(registeredReceivers.get(ir));
14342            ir++;
14343        }
14344
14345        if ((receivers != null && receivers.size() > 0)
14346                || resultTo != null) {
14347            BroadcastQueue queue = broadcastQueueForIntent(intent);
14348            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14349                    callerPackage, callingPid, callingUid, resolvedType,
14350                    requiredPermission, appOp, receivers, resultTo, resultCode,
14351                    resultData, map, ordered, sticky, false, userId);
14352            if (DEBUG_BROADCAST) Slog.v(
14353                    TAG, "Enqueueing ordered broadcast " + r
14354                    + ": prev had " + queue.mOrderedBroadcasts.size());
14355            if (DEBUG_BROADCAST) {
14356                int seq = r.intent.getIntExtra("seq", -1);
14357                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14358            }
14359            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14360            if (!replaced) {
14361                queue.enqueueOrderedBroadcastLocked(r);
14362                queue.scheduleBroadcastsLocked();
14363            }
14364        }
14365
14366        return ActivityManager.BROADCAST_SUCCESS;
14367    }
14368
14369    final Intent verifyBroadcastLocked(Intent intent) {
14370        // Refuse possible leaked file descriptors
14371        if (intent != null && intent.hasFileDescriptors() == true) {
14372            throw new IllegalArgumentException("File descriptors passed in Intent");
14373        }
14374
14375        int flags = intent.getFlags();
14376
14377        if (!mProcessesReady) {
14378            // if the caller really truly claims to know what they're doing, go
14379            // ahead and allow the broadcast without launching any receivers
14380            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14381                intent = new Intent(intent);
14382                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14383            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14384                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14385                        + " before boot completion");
14386                throw new IllegalStateException("Cannot broadcast before boot completed");
14387            }
14388        }
14389
14390        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14391            throw new IllegalArgumentException(
14392                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14393        }
14394
14395        return intent;
14396    }
14397
14398    public final int broadcastIntent(IApplicationThread caller,
14399            Intent intent, String resolvedType, IIntentReceiver resultTo,
14400            int resultCode, String resultData, Bundle map,
14401            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14402        enforceNotIsolatedCaller("broadcastIntent");
14403        synchronized(this) {
14404            intent = verifyBroadcastLocked(intent);
14405
14406            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14407            final int callingPid = Binder.getCallingPid();
14408            final int callingUid = Binder.getCallingUid();
14409            final long origId = Binder.clearCallingIdentity();
14410            int res = broadcastIntentLocked(callerApp,
14411                    callerApp != null ? callerApp.info.packageName : null,
14412                    intent, resolvedType, resultTo,
14413                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14414                    callingPid, callingUid, userId);
14415            Binder.restoreCallingIdentity(origId);
14416            return res;
14417        }
14418    }
14419
14420    int broadcastIntentInPackage(String packageName, int uid,
14421            Intent intent, String resolvedType, IIntentReceiver resultTo,
14422            int resultCode, String resultData, Bundle map,
14423            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14424        synchronized(this) {
14425            intent = verifyBroadcastLocked(intent);
14426
14427            final long origId = Binder.clearCallingIdentity();
14428            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14429                    resultTo, resultCode, resultData, map, requiredPermission,
14430                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14431            Binder.restoreCallingIdentity(origId);
14432            return res;
14433        }
14434    }
14435
14436    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14437        // Refuse possible leaked file descriptors
14438        if (intent != null && intent.hasFileDescriptors() == true) {
14439            throw new IllegalArgumentException("File descriptors passed in Intent");
14440        }
14441
14442        userId = handleIncomingUser(Binder.getCallingPid(),
14443                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14444
14445        synchronized(this) {
14446            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14447                    != PackageManager.PERMISSION_GRANTED) {
14448                String msg = "Permission Denial: unbroadcastIntent() from pid="
14449                        + Binder.getCallingPid()
14450                        + ", uid=" + Binder.getCallingUid()
14451                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14452                Slog.w(TAG, msg);
14453                throw new SecurityException(msg);
14454            }
14455            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14456            if (stickies != null) {
14457                ArrayList<Intent> list = stickies.get(intent.getAction());
14458                if (list != null) {
14459                    int N = list.size();
14460                    int i;
14461                    for (i=0; i<N; i++) {
14462                        if (intent.filterEquals(list.get(i))) {
14463                            list.remove(i);
14464                            break;
14465                        }
14466                    }
14467                    if (list.size() <= 0) {
14468                        stickies.remove(intent.getAction());
14469                    }
14470                }
14471                if (stickies.size() <= 0) {
14472                    mStickyBroadcasts.remove(userId);
14473                }
14474            }
14475        }
14476    }
14477
14478    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14479            String resultData, Bundle resultExtras, boolean resultAbort) {
14480        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14481        if (r == null) {
14482            Slog.w(TAG, "finishReceiver called but not found on queue");
14483            return false;
14484        }
14485
14486        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14487    }
14488
14489    void backgroundServicesFinishedLocked(int userId) {
14490        for (BroadcastQueue queue : mBroadcastQueues) {
14491            queue.backgroundServicesFinishedLocked(userId);
14492        }
14493    }
14494
14495    public void finishReceiver(IBinder who, int resultCode, String resultData,
14496            Bundle resultExtras, boolean resultAbort) {
14497        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14498
14499        // Refuse possible leaked file descriptors
14500        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14501            throw new IllegalArgumentException("File descriptors passed in Bundle");
14502        }
14503
14504        final long origId = Binder.clearCallingIdentity();
14505        try {
14506            boolean doNext = false;
14507            BroadcastRecord r;
14508
14509            synchronized(this) {
14510                r = broadcastRecordForReceiverLocked(who);
14511                if (r != null) {
14512                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14513                        resultData, resultExtras, resultAbort, true);
14514                }
14515            }
14516
14517            if (doNext) {
14518                r.queue.processNextBroadcast(false);
14519            }
14520            trimApplications();
14521        } finally {
14522            Binder.restoreCallingIdentity(origId);
14523        }
14524    }
14525
14526    // =========================================================
14527    // INSTRUMENTATION
14528    // =========================================================
14529
14530    public boolean startInstrumentation(ComponentName className,
14531            String profileFile, int flags, Bundle arguments,
14532            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14533            int userId, String abiOverride) {
14534        enforceNotIsolatedCaller("startInstrumentation");
14535        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14536                userId, false, true, "startInstrumentation", null);
14537        // Refuse possible leaked file descriptors
14538        if (arguments != null && arguments.hasFileDescriptors()) {
14539            throw new IllegalArgumentException("File descriptors passed in Bundle");
14540        }
14541
14542        synchronized(this) {
14543            InstrumentationInfo ii = null;
14544            ApplicationInfo ai = null;
14545            try {
14546                ii = mContext.getPackageManager().getInstrumentationInfo(
14547                    className, STOCK_PM_FLAGS);
14548                ai = AppGlobals.getPackageManager().getApplicationInfo(
14549                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14550            } catch (PackageManager.NameNotFoundException e) {
14551            } catch (RemoteException e) {
14552            }
14553            if (ii == null) {
14554                reportStartInstrumentationFailure(watcher, className,
14555                        "Unable to find instrumentation info for: " + className);
14556                return false;
14557            }
14558            if (ai == null) {
14559                reportStartInstrumentationFailure(watcher, className,
14560                        "Unable to find instrumentation target package: " + ii.targetPackage);
14561                return false;
14562            }
14563
14564            int match = mContext.getPackageManager().checkSignatures(
14565                    ii.targetPackage, ii.packageName);
14566            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14567                String msg = "Permission Denial: starting instrumentation "
14568                        + className + " from pid="
14569                        + Binder.getCallingPid()
14570                        + ", uid=" + Binder.getCallingPid()
14571                        + " not allowed because package " + ii.packageName
14572                        + " does not have a signature matching the target "
14573                        + ii.targetPackage;
14574                reportStartInstrumentationFailure(watcher, className, msg);
14575                throw new SecurityException(msg);
14576            }
14577
14578            final long origId = Binder.clearCallingIdentity();
14579            // Instrumentation can kill and relaunch even persistent processes
14580            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14581                    "start instr");
14582            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14583            app.instrumentationClass = className;
14584            app.instrumentationInfo = ai;
14585            app.instrumentationProfileFile = profileFile;
14586            app.instrumentationArguments = arguments;
14587            app.instrumentationWatcher = watcher;
14588            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14589            app.instrumentationResultClass = className;
14590            Binder.restoreCallingIdentity(origId);
14591        }
14592
14593        return true;
14594    }
14595
14596    /**
14597     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14598     * error to the logs, but if somebody is watching, send the report there too.  This enables
14599     * the "am" command to report errors with more information.
14600     *
14601     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14602     * @param cn The component name of the instrumentation.
14603     * @param report The error report.
14604     */
14605    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14606            ComponentName cn, String report) {
14607        Slog.w(TAG, report);
14608        try {
14609            if (watcher != null) {
14610                Bundle results = new Bundle();
14611                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14612                results.putString("Error", report);
14613                watcher.instrumentationStatus(cn, -1, results);
14614            }
14615        } catch (RemoteException e) {
14616            Slog.w(TAG, e);
14617        }
14618    }
14619
14620    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14621        if (app.instrumentationWatcher != null) {
14622            try {
14623                // NOTE:  IInstrumentationWatcher *must* be oneway here
14624                app.instrumentationWatcher.instrumentationFinished(
14625                    app.instrumentationClass,
14626                    resultCode,
14627                    results);
14628            } catch (RemoteException e) {
14629            }
14630        }
14631        if (app.instrumentationUiAutomationConnection != null) {
14632            try {
14633                app.instrumentationUiAutomationConnection.shutdown();
14634            } catch (RemoteException re) {
14635                /* ignore */
14636            }
14637            // Only a UiAutomation can set this flag and now that
14638            // it is finished we make sure it is reset to its default.
14639            mUserIsMonkey = false;
14640        }
14641        app.instrumentationWatcher = null;
14642        app.instrumentationUiAutomationConnection = null;
14643        app.instrumentationClass = null;
14644        app.instrumentationInfo = null;
14645        app.instrumentationProfileFile = null;
14646        app.instrumentationArguments = null;
14647
14648        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14649                "finished inst");
14650    }
14651
14652    public void finishInstrumentation(IApplicationThread target,
14653            int resultCode, Bundle results) {
14654        int userId = UserHandle.getCallingUserId();
14655        // Refuse possible leaked file descriptors
14656        if (results != null && results.hasFileDescriptors()) {
14657            throw new IllegalArgumentException("File descriptors passed in Intent");
14658        }
14659
14660        synchronized(this) {
14661            ProcessRecord app = getRecordForAppLocked(target);
14662            if (app == null) {
14663                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14664                return;
14665            }
14666            final long origId = Binder.clearCallingIdentity();
14667            finishInstrumentationLocked(app, resultCode, results);
14668            Binder.restoreCallingIdentity(origId);
14669        }
14670    }
14671
14672    // =========================================================
14673    // CONFIGURATION
14674    // =========================================================
14675
14676    public ConfigurationInfo getDeviceConfigurationInfo() {
14677        ConfigurationInfo config = new ConfigurationInfo();
14678        synchronized (this) {
14679            config.reqTouchScreen = mConfiguration.touchscreen;
14680            config.reqKeyboardType = mConfiguration.keyboard;
14681            config.reqNavigation = mConfiguration.navigation;
14682            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14683                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14684                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14685            }
14686            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14687                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14688                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14689            }
14690            config.reqGlEsVersion = GL_ES_VERSION;
14691        }
14692        return config;
14693    }
14694
14695    ActivityStack getFocusedStack() {
14696        return mStackSupervisor.getFocusedStack();
14697    }
14698
14699    public Configuration getConfiguration() {
14700        Configuration ci;
14701        synchronized(this) {
14702            ci = new Configuration(mConfiguration);
14703        }
14704        return ci;
14705    }
14706
14707    public void updatePersistentConfiguration(Configuration values) {
14708        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14709                "updateConfiguration()");
14710        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14711                "updateConfiguration()");
14712        if (values == null) {
14713            throw new NullPointerException("Configuration must not be null");
14714        }
14715
14716        synchronized(this) {
14717            final long origId = Binder.clearCallingIdentity();
14718            updateConfigurationLocked(values, null, true, false);
14719            Binder.restoreCallingIdentity(origId);
14720        }
14721    }
14722
14723    public void updateConfiguration(Configuration values) {
14724        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14725                "updateConfiguration()");
14726
14727        synchronized(this) {
14728            if (values == null && mWindowManager != null) {
14729                // sentinel: fetch the current configuration from the window manager
14730                values = mWindowManager.computeNewConfiguration();
14731            }
14732
14733            if (mWindowManager != null) {
14734                mProcessList.applyDisplaySize(mWindowManager);
14735            }
14736
14737            final long origId = Binder.clearCallingIdentity();
14738            if (values != null) {
14739                Settings.System.clearConfiguration(values);
14740            }
14741            updateConfigurationLocked(values, null, false, false);
14742            Binder.restoreCallingIdentity(origId);
14743        }
14744    }
14745
14746    /**
14747     * Do either or both things: (1) change the current configuration, and (2)
14748     * make sure the given activity is running with the (now) current
14749     * configuration.  Returns true if the activity has been left running, or
14750     * false if <var>starting</var> is being destroyed to match the new
14751     * configuration.
14752     * @param persistent TODO
14753     */
14754    boolean updateConfigurationLocked(Configuration values,
14755            ActivityRecord starting, boolean persistent, boolean initLocale) {
14756        int changes = 0;
14757
14758        if (values != null) {
14759            Configuration newConfig = new Configuration(mConfiguration);
14760            changes = newConfig.updateFrom(values);
14761            if (changes != 0) {
14762                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14763                    Slog.i(TAG, "Updating configuration to: " + values);
14764                }
14765
14766                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14767
14768                if (values.locale != null && !initLocale) {
14769                    saveLocaleLocked(values.locale,
14770                                     !values.locale.equals(mConfiguration.locale),
14771                                     values.userSetLocale);
14772                }
14773
14774                mConfigurationSeq++;
14775                if (mConfigurationSeq <= 0) {
14776                    mConfigurationSeq = 1;
14777                }
14778                newConfig.seq = mConfigurationSeq;
14779                mConfiguration = newConfig;
14780                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14781                mUsageStatsService.noteStartConfig(newConfig);
14782
14783                final Configuration configCopy = new Configuration(mConfiguration);
14784
14785                // TODO: If our config changes, should we auto dismiss any currently
14786                // showing dialogs?
14787                mShowDialogs = shouldShowDialogs(newConfig);
14788
14789                AttributeCache ac = AttributeCache.instance();
14790                if (ac != null) {
14791                    ac.updateConfiguration(configCopy);
14792                }
14793
14794                // Make sure all resources in our process are updated
14795                // right now, so that anyone who is going to retrieve
14796                // resource values after we return will be sure to get
14797                // the new ones.  This is especially important during
14798                // boot, where the first config change needs to guarantee
14799                // all resources have that config before following boot
14800                // code is executed.
14801                mSystemThread.applyConfigurationToResources(configCopy);
14802
14803                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14804                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14805                    msg.obj = new Configuration(configCopy);
14806                    mHandler.sendMessage(msg);
14807                }
14808
14809                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14810                    ProcessRecord app = mLruProcesses.get(i);
14811                    try {
14812                        if (app.thread != null) {
14813                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14814                                    + app.processName + " new config " + mConfiguration);
14815                            app.thread.scheduleConfigurationChanged(configCopy);
14816                        }
14817                    } catch (Exception e) {
14818                    }
14819                }
14820                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14821                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14822                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14823                        | Intent.FLAG_RECEIVER_FOREGROUND);
14824                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14825                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14826                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14827                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14828                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14829                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14830                    broadcastIntentLocked(null, null, intent,
14831                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14832                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14833                }
14834            }
14835        }
14836
14837        boolean kept = true;
14838        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14839        // mainStack is null during startup.
14840        if (mainStack != null) {
14841            if (changes != 0 && starting == null) {
14842                // If the configuration changed, and the caller is not already
14843                // in the process of starting an activity, then find the top
14844                // activity to check if its configuration needs to change.
14845                starting = mainStack.topRunningActivityLocked(null);
14846            }
14847
14848            if (starting != null) {
14849                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14850                // And we need to make sure at this point that all other activities
14851                // are made visible with the correct configuration.
14852                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14853            }
14854        }
14855
14856        if (values != null && mWindowManager != null) {
14857            mWindowManager.setNewConfiguration(mConfiguration);
14858        }
14859
14860        return kept;
14861    }
14862
14863    /**
14864     * Decide based on the configuration whether we should shouw the ANR,
14865     * crash, etc dialogs.  The idea is that if there is no affordnace to
14866     * press the on-screen buttons, we shouldn't show the dialog.
14867     *
14868     * A thought: SystemUI might also want to get told about this, the Power
14869     * dialog / global actions also might want different behaviors.
14870     */
14871    private static final boolean shouldShowDialogs(Configuration config) {
14872        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14873                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14874    }
14875
14876    /**
14877     * Save the locale.  You must be inside a synchronized (this) block.
14878     */
14879    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14880        if(isDiff) {
14881            SystemProperties.set("user.language", l.getLanguage());
14882            SystemProperties.set("user.region", l.getCountry());
14883        }
14884
14885        if(isPersist) {
14886            SystemProperties.set("persist.sys.language", l.getLanguage());
14887            SystemProperties.set("persist.sys.country", l.getCountry());
14888            SystemProperties.set("persist.sys.localevar", l.getVariant());
14889        }
14890    }
14891
14892    @Override
14893    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14894        ActivityRecord srec = ActivityRecord.forToken(token);
14895        return srec != null && srec.task.affinity != null &&
14896                srec.task.affinity.equals(destAffinity);
14897    }
14898
14899    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14900            Intent resultData) {
14901
14902        synchronized (this) {
14903            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14904            if (stack != null) {
14905                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14906            }
14907            return false;
14908        }
14909    }
14910
14911    public int getLaunchedFromUid(IBinder activityToken) {
14912        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14913        if (srec == null) {
14914            return -1;
14915        }
14916        return srec.launchedFromUid;
14917    }
14918
14919    public String getLaunchedFromPackage(IBinder activityToken) {
14920        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14921        if (srec == null) {
14922            return null;
14923        }
14924        return srec.launchedFromPackage;
14925    }
14926
14927    // =========================================================
14928    // LIFETIME MANAGEMENT
14929    // =========================================================
14930
14931    // Returns which broadcast queue the app is the current [or imminent] receiver
14932    // on, or 'null' if the app is not an active broadcast recipient.
14933    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14934        BroadcastRecord r = app.curReceiver;
14935        if (r != null) {
14936            return r.queue;
14937        }
14938
14939        // It's not the current receiver, but it might be starting up to become one
14940        synchronized (this) {
14941            for (BroadcastQueue queue : mBroadcastQueues) {
14942                r = queue.mPendingBroadcast;
14943                if (r != null && r.curApp == app) {
14944                    // found it; report which queue it's in
14945                    return queue;
14946                }
14947            }
14948        }
14949
14950        return null;
14951    }
14952
14953    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14954            boolean doingAll, long now) {
14955        if (mAdjSeq == app.adjSeq) {
14956            // This adjustment has already been computed.
14957            return app.curRawAdj;
14958        }
14959
14960        if (app.thread == null) {
14961            app.adjSeq = mAdjSeq;
14962            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14963            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14964            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14965        }
14966
14967        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14968        app.adjSource = null;
14969        app.adjTarget = null;
14970        app.empty = false;
14971        app.cached = false;
14972
14973        final int activitiesSize = app.activities.size();
14974
14975        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14976            // The max adjustment doesn't allow this app to be anything
14977            // below foreground, so it is not worth doing work for it.
14978            app.adjType = "fixed";
14979            app.adjSeq = mAdjSeq;
14980            app.curRawAdj = app.maxAdj;
14981            app.foregroundActivities = false;
14982            app.keeping = true;
14983            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14984            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14985            // System processes can do UI, and when they do we want to have
14986            // them trim their memory after the user leaves the UI.  To
14987            // facilitate this, here we need to determine whether or not it
14988            // is currently showing UI.
14989            app.systemNoUi = true;
14990            if (app == TOP_APP) {
14991                app.systemNoUi = false;
14992            } else if (activitiesSize > 0) {
14993                for (int j = 0; j < activitiesSize; j++) {
14994                    final ActivityRecord r = app.activities.get(j);
14995                    if (r.visible) {
14996                        app.systemNoUi = false;
14997                    }
14998                }
14999            }
15000            if (!app.systemNoUi) {
15001                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15002            }
15003            return (app.curAdj=app.maxAdj);
15004        }
15005
15006        app.keeping = false;
15007        app.systemNoUi = false;
15008
15009        // Determine the importance of the process, starting with most
15010        // important to least, and assign an appropriate OOM adjustment.
15011        int adj;
15012        int schedGroup;
15013        int procState;
15014        boolean foregroundActivities = false;
15015        BroadcastQueue queue;
15016        if (app == TOP_APP) {
15017            // The last app on the list is the foreground app.
15018            adj = ProcessList.FOREGROUND_APP_ADJ;
15019            schedGroup = Process.THREAD_GROUP_DEFAULT;
15020            app.adjType = "top-activity";
15021            foregroundActivities = true;
15022            procState = ActivityManager.PROCESS_STATE_TOP;
15023        } else if (app.instrumentationClass != null) {
15024            // Don't want to kill running instrumentation.
15025            adj = ProcessList.FOREGROUND_APP_ADJ;
15026            schedGroup = Process.THREAD_GROUP_DEFAULT;
15027            app.adjType = "instrumentation";
15028            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15029        } else if ((queue = isReceivingBroadcast(app)) != null) {
15030            // An app that is currently receiving a broadcast also
15031            // counts as being in the foreground for OOM killer purposes.
15032            // It's placed in a sched group based on the nature of the
15033            // broadcast as reflected by which queue it's active in.
15034            adj = ProcessList.FOREGROUND_APP_ADJ;
15035            schedGroup = (queue == mFgBroadcastQueue)
15036                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15037            app.adjType = "broadcast";
15038            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15039        } else if (app.executingServices.size() > 0) {
15040            // An app that is currently executing a service callback also
15041            // counts as being in the foreground.
15042            adj = ProcessList.FOREGROUND_APP_ADJ;
15043            schedGroup = app.execServicesFg ?
15044                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15045            app.adjType = "exec-service";
15046            procState = ActivityManager.PROCESS_STATE_SERVICE;
15047            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15048        } else {
15049            // As far as we know the process is empty.  We may change our mind later.
15050            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15051            // At this point we don't actually know the adjustment.  Use the cached adj
15052            // value that the caller wants us to.
15053            adj = cachedAdj;
15054            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15055            app.cached = true;
15056            app.empty = true;
15057            app.adjType = "cch-empty";
15058        }
15059
15060        // Examine all activities if not already foreground.
15061        if (!foregroundActivities && activitiesSize > 0) {
15062            for (int j = 0; j < activitiesSize; j++) {
15063                final ActivityRecord r = app.activities.get(j);
15064                if (r.app != app) {
15065                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15066                            + app + "?!?");
15067                    continue;
15068                }
15069                if (r.visible) {
15070                    // App has a visible activity; only upgrade adjustment.
15071                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15072                        adj = ProcessList.VISIBLE_APP_ADJ;
15073                        app.adjType = "visible";
15074                    }
15075                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15076                        procState = ActivityManager.PROCESS_STATE_TOP;
15077                    }
15078                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15079                    app.cached = false;
15080                    app.empty = false;
15081                    foregroundActivities = true;
15082                    break;
15083                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15084                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15085                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15086                        app.adjType = "pausing";
15087                    }
15088                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15089                        procState = ActivityManager.PROCESS_STATE_TOP;
15090                    }
15091                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15092                    app.cached = false;
15093                    app.empty = false;
15094                    foregroundActivities = true;
15095                } else if (r.state == ActivityState.STOPPING) {
15096                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15097                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15098                        app.adjType = "stopping";
15099                    }
15100                    // For the process state, we will at this point consider the
15101                    // process to be cached.  It will be cached either as an activity
15102                    // or empty depending on whether the activity is finishing.  We do
15103                    // this so that we can treat the process as cached for purposes of
15104                    // memory trimming (determing current memory level, trim command to
15105                    // send to process) since there can be an arbitrary number of stopping
15106                    // processes and they should soon all go into the cached state.
15107                    if (!r.finishing) {
15108                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15109                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15110                        }
15111                    }
15112                    app.cached = false;
15113                    app.empty = false;
15114                    foregroundActivities = true;
15115                } else {
15116                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15117                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15118                        app.adjType = "cch-act";
15119                    }
15120                }
15121            }
15122        }
15123
15124        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15125            if (app.foregroundServices) {
15126                // The user is aware of this app, so make it visible.
15127                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15128                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15129                app.cached = false;
15130                app.adjType = "fg-service";
15131                schedGroup = Process.THREAD_GROUP_DEFAULT;
15132            } else if (app.forcingToForeground != null) {
15133                // The user is aware of this app, so make it visible.
15134                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15135                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15136                app.cached = false;
15137                app.adjType = "force-fg";
15138                app.adjSource = app.forcingToForeground;
15139                schedGroup = Process.THREAD_GROUP_DEFAULT;
15140            }
15141        }
15142
15143        if (app == mHeavyWeightProcess) {
15144            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15145                // We don't want to kill the current heavy-weight process.
15146                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15147                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15148                app.cached = false;
15149                app.adjType = "heavy";
15150            }
15151            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15152                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15153            }
15154        }
15155
15156        if (app == mHomeProcess) {
15157            if (adj > ProcessList.HOME_APP_ADJ) {
15158                // This process is hosting what we currently consider to be the
15159                // home app, so we don't want to let it go into the background.
15160                adj = ProcessList.HOME_APP_ADJ;
15161                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15162                app.cached = false;
15163                app.adjType = "home";
15164            }
15165            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15166                procState = ActivityManager.PROCESS_STATE_HOME;
15167            }
15168        }
15169
15170        if (app == mPreviousProcess && app.activities.size() > 0) {
15171            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15172                // This was the previous process that showed UI to the user.
15173                // We want to try to keep it around more aggressively, to give
15174                // a good experience around switching between two apps.
15175                adj = ProcessList.PREVIOUS_APP_ADJ;
15176                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15177                app.cached = false;
15178                app.adjType = "previous";
15179            }
15180            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15181                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15182            }
15183        }
15184
15185        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15186                + " reason=" + app.adjType);
15187
15188        // By default, we use the computed adjustment.  It may be changed if
15189        // there are applications dependent on our services or providers, but
15190        // this gives us a baseline and makes sure we don't get into an
15191        // infinite recursion.
15192        app.adjSeq = mAdjSeq;
15193        app.curRawAdj = adj;
15194        app.hasStartedServices = false;
15195
15196        if (mBackupTarget != null && app == mBackupTarget.app) {
15197            // If possible we want to avoid killing apps while they're being backed up
15198            if (adj > ProcessList.BACKUP_APP_ADJ) {
15199                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15200                adj = ProcessList.BACKUP_APP_ADJ;
15201                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15202                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15203                }
15204                app.adjType = "backup";
15205                app.cached = false;
15206            }
15207            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15208                procState = ActivityManager.PROCESS_STATE_BACKUP;
15209            }
15210        }
15211
15212        boolean mayBeTop = false;
15213
15214        for (int is = app.services.size()-1;
15215                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15216                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15217                        || procState > ActivityManager.PROCESS_STATE_TOP);
15218                is--) {
15219            ServiceRecord s = app.services.valueAt(is);
15220            if (s.startRequested) {
15221                app.hasStartedServices = true;
15222                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15223                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15224                }
15225                if (app.hasShownUi && app != mHomeProcess) {
15226                    // If this process has shown some UI, let it immediately
15227                    // go to the LRU list because it may be pretty heavy with
15228                    // UI stuff.  We'll tag it with a label just to help
15229                    // debug and understand what is going on.
15230                    if (adj > ProcessList.SERVICE_ADJ) {
15231                        app.adjType = "cch-started-ui-services";
15232                    }
15233                } else {
15234                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15235                        // This service has seen some activity within
15236                        // recent memory, so we will keep its process ahead
15237                        // of the background processes.
15238                        if (adj > ProcessList.SERVICE_ADJ) {
15239                            adj = ProcessList.SERVICE_ADJ;
15240                            app.adjType = "started-services";
15241                            app.cached = false;
15242                        }
15243                    }
15244                    // If we have let the service slide into the background
15245                    // state, still have some text describing what it is doing
15246                    // even though the service no longer has an impact.
15247                    if (adj > ProcessList.SERVICE_ADJ) {
15248                        app.adjType = "cch-started-services";
15249                    }
15250                }
15251                // Don't kill this process because it is doing work; it
15252                // has said it is doing work.
15253                app.keeping = true;
15254            }
15255            for (int conni = s.connections.size()-1;
15256                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15257                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15258                            || procState > ActivityManager.PROCESS_STATE_TOP);
15259                    conni--) {
15260                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15261                for (int i = 0;
15262                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15263                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15264                                || procState > ActivityManager.PROCESS_STATE_TOP);
15265                        i++) {
15266                    // XXX should compute this based on the max of
15267                    // all connected clients.
15268                    ConnectionRecord cr = clist.get(i);
15269                    if (cr.binding.client == app) {
15270                        // Binding to ourself is not interesting.
15271                        continue;
15272                    }
15273                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15274                        ProcessRecord client = cr.binding.client;
15275                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15276                                TOP_APP, doingAll, now);
15277                        int clientProcState = client.curProcState;
15278                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15279                            // If the other app is cached for any reason, for purposes here
15280                            // we are going to consider it empty.  The specific cached state
15281                            // doesn't propagate except under certain conditions.
15282                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15283                        }
15284                        String adjType = null;
15285                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15286                            // Not doing bind OOM management, so treat
15287                            // this guy more like a started service.
15288                            if (app.hasShownUi && app != mHomeProcess) {
15289                                // If this process has shown some UI, let it immediately
15290                                // go to the LRU list because it may be pretty heavy with
15291                                // UI stuff.  We'll tag it with a label just to help
15292                                // debug and understand what is going on.
15293                                if (adj > clientAdj) {
15294                                    adjType = "cch-bound-ui-services";
15295                                }
15296                                app.cached = false;
15297                                clientAdj = adj;
15298                                clientProcState = procState;
15299                            } else {
15300                                if (now >= (s.lastActivity
15301                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15302                                    // This service has not seen activity within
15303                                    // recent memory, so allow it to drop to the
15304                                    // LRU list if there is no other reason to keep
15305                                    // it around.  We'll also tag it with a label just
15306                                    // to help debug and undertand what is going on.
15307                                    if (adj > clientAdj) {
15308                                        adjType = "cch-bound-services";
15309                                    }
15310                                    clientAdj = adj;
15311                                }
15312                            }
15313                        }
15314                        if (adj > clientAdj) {
15315                            // If this process has recently shown UI, and
15316                            // the process that is binding to it is less
15317                            // important than being visible, then we don't
15318                            // care about the binding as much as we care
15319                            // about letting this process get into the LRU
15320                            // list to be killed and restarted if needed for
15321                            // memory.
15322                            if (app.hasShownUi && app != mHomeProcess
15323                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15324                                adjType = "cch-bound-ui-services";
15325                            } else {
15326                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15327                                        |Context.BIND_IMPORTANT)) != 0) {
15328                                    adj = clientAdj;
15329                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15330                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15331                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15332                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15333                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15334                                    adj = clientAdj;
15335                                } else {
15336                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15337                                        adj = ProcessList.VISIBLE_APP_ADJ;
15338                                    }
15339                                }
15340                                if (!client.cached) {
15341                                    app.cached = false;
15342                                }
15343                                if (client.keeping) {
15344                                    app.keeping = true;
15345                                }
15346                                adjType = "service";
15347                            }
15348                        }
15349                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15350                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15351                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15352                            }
15353                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15354                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15355                                    // Special handling of clients who are in the top state.
15356                                    // We *may* want to consider this process to be in the
15357                                    // top state as well, but only if there is not another
15358                                    // reason for it to be running.  Being on the top is a
15359                                    // special state, meaning you are specifically running
15360                                    // for the current top app.  If the process is already
15361                                    // running in the background for some other reason, it
15362                                    // is more important to continue considering it to be
15363                                    // in the background state.
15364                                    mayBeTop = true;
15365                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15366                                } else {
15367                                    // Special handling for above-top states (persistent
15368                                    // processes).  These should not bring the current process
15369                                    // into the top state, since they are not on top.  Instead
15370                                    // give them the best state after that.
15371                                    clientProcState =
15372                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15373                                }
15374                            }
15375                        } else {
15376                            if (clientProcState <
15377                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15378                                clientProcState =
15379                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15380                            }
15381                        }
15382                        if (procState > clientProcState) {
15383                            procState = clientProcState;
15384                        }
15385                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15386                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15387                            app.pendingUiClean = true;
15388                        }
15389                        if (adjType != null) {
15390                            app.adjType = adjType;
15391                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15392                                    .REASON_SERVICE_IN_USE;
15393                            app.adjSource = cr.binding.client;
15394                            app.adjSourceOom = clientAdj;
15395                            app.adjTarget = s.name;
15396                        }
15397                    }
15398                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15399                        app.treatLikeActivity = true;
15400                    }
15401                    final ActivityRecord a = cr.activity;
15402                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15403                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15404                                (a.visible || a.state == ActivityState.RESUMED
15405                                 || a.state == ActivityState.PAUSING)) {
15406                            adj = ProcessList.FOREGROUND_APP_ADJ;
15407                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15408                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15409                            }
15410                            app.cached = false;
15411                            app.adjType = "service";
15412                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15413                                    .REASON_SERVICE_IN_USE;
15414                            app.adjSource = a;
15415                            app.adjSourceOom = adj;
15416                            app.adjTarget = s.name;
15417                        }
15418                    }
15419                }
15420            }
15421        }
15422
15423        for (int provi = app.pubProviders.size()-1;
15424                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15425                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15426                        || procState > ActivityManager.PROCESS_STATE_TOP);
15427                provi--) {
15428            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15429            for (int i = cpr.connections.size()-1;
15430                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15431                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15432                            || procState > ActivityManager.PROCESS_STATE_TOP);
15433                    i--) {
15434                ContentProviderConnection conn = cpr.connections.get(i);
15435                ProcessRecord client = conn.client;
15436                if (client == app) {
15437                    // Being our own client is not interesting.
15438                    continue;
15439                }
15440                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15441                int clientProcState = client.curProcState;
15442                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15443                    // If the other app is cached for any reason, for purposes here
15444                    // we are going to consider it empty.
15445                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15446                }
15447                if (adj > clientAdj) {
15448                    if (app.hasShownUi && app != mHomeProcess
15449                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15450                        app.adjType = "cch-ui-provider";
15451                    } else {
15452                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15453                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15454                        app.adjType = "provider";
15455                    }
15456                    app.cached &= client.cached;
15457                    app.keeping |= client.keeping;
15458                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15459                            .REASON_PROVIDER_IN_USE;
15460                    app.adjSource = client;
15461                    app.adjSourceOom = clientAdj;
15462                    app.adjTarget = cpr.name;
15463                }
15464                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15465                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15466                        // Special handling of clients who are in the top state.
15467                        // We *may* want to consider this process to be in the
15468                        // top state as well, but only if there is not another
15469                        // reason for it to be running.  Being on the top is a
15470                        // special state, meaning you are specifically running
15471                        // for the current top app.  If the process is already
15472                        // running in the background for some other reason, it
15473                        // is more important to continue considering it to be
15474                        // in the background state.
15475                        mayBeTop = true;
15476                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15477                    } else {
15478                        // Special handling for above-top states (persistent
15479                        // processes).  These should not bring the current process
15480                        // into the top state, since they are not on top.  Instead
15481                        // give them the best state after that.
15482                        clientProcState =
15483                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15484                    }
15485                }
15486                if (procState > clientProcState) {
15487                    procState = clientProcState;
15488                }
15489                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15490                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15491                }
15492            }
15493            // If the provider has external (non-framework) process
15494            // dependencies, ensure that its adjustment is at least
15495            // FOREGROUND_APP_ADJ.
15496            if (cpr.hasExternalProcessHandles()) {
15497                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15498                    adj = ProcessList.FOREGROUND_APP_ADJ;
15499                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15500                    app.cached = false;
15501                    app.keeping = true;
15502                    app.adjType = "provider";
15503                    app.adjTarget = cpr.name;
15504                }
15505                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15506                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15507                }
15508            }
15509        }
15510
15511        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15512            // A client of one of our services or providers is in the top state.  We
15513            // *may* want to be in the top state, but not if we are already running in
15514            // the background for some other reason.  For the decision here, we are going
15515            // to pick out a few specific states that we want to remain in when a client
15516            // is top (states that tend to be longer-term) and otherwise allow it to go
15517            // to the top state.
15518            switch (procState) {
15519                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15520                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15521                case ActivityManager.PROCESS_STATE_SERVICE:
15522                    // These all are longer-term states, so pull them up to the top
15523                    // of the background states, but not all the way to the top state.
15524                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15525                    break;
15526                default:
15527                    // Otherwise, top is a better choice, so take it.
15528                    procState = ActivityManager.PROCESS_STATE_TOP;
15529                    break;
15530            }
15531        }
15532
15533        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15534            if (app.hasClientActivities) {
15535                // This is a cached process, but with client activities.  Mark it so.
15536                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15537                app.adjType = "cch-client-act";
15538            } else if (app.treatLikeActivity) {
15539                // This is a cached process, but somebody wants us to treat it like it has
15540                // an activity, okay!
15541                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15542                app.adjType = "cch-as-act";
15543            }
15544        }
15545
15546        if (adj == ProcessList.SERVICE_ADJ) {
15547            if (doingAll) {
15548                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15549                mNewNumServiceProcs++;
15550                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15551                if (!app.serviceb) {
15552                    // This service isn't far enough down on the LRU list to
15553                    // normally be a B service, but if we are low on RAM and it
15554                    // is large we want to force it down since we would prefer to
15555                    // keep launcher over it.
15556                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15557                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15558                        app.serviceHighRam = true;
15559                        app.serviceb = true;
15560                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15561                    } else {
15562                        mNewNumAServiceProcs++;
15563                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15564                    }
15565                } else {
15566                    app.serviceHighRam = false;
15567                }
15568            }
15569            if (app.serviceb) {
15570                adj = ProcessList.SERVICE_B_ADJ;
15571            }
15572        }
15573
15574        app.curRawAdj = adj;
15575
15576        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15577        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15578        if (adj > app.maxAdj) {
15579            adj = app.maxAdj;
15580            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15581                schedGroup = Process.THREAD_GROUP_DEFAULT;
15582            }
15583        }
15584        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15585            app.keeping = true;
15586        }
15587
15588        // Do final modification to adj.  Everything we do between here and applying
15589        // the final setAdj must be done in this function, because we will also use
15590        // it when computing the final cached adj later.  Note that we don't need to
15591        // worry about this for max adj above, since max adj will always be used to
15592        // keep it out of the cached vaues.
15593        app.curAdj = app.modifyRawOomAdj(adj);
15594        app.curSchedGroup = schedGroup;
15595        app.curProcState = procState;
15596        app.foregroundActivities = foregroundActivities;
15597
15598        return app.curRawAdj;
15599    }
15600
15601    /**
15602     * Schedule PSS collection of a process.
15603     */
15604    void requestPssLocked(ProcessRecord proc, int procState) {
15605        if (mPendingPssProcesses.contains(proc)) {
15606            return;
15607        }
15608        if (mPendingPssProcesses.size() == 0) {
15609            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15610        }
15611        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15612        proc.pssProcState = procState;
15613        mPendingPssProcesses.add(proc);
15614    }
15615
15616    /**
15617     * Schedule PSS collection of all processes.
15618     */
15619    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15620        if (!always) {
15621            if (now < (mLastFullPssTime +
15622                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15623                return;
15624            }
15625        }
15626        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15627        mLastFullPssTime = now;
15628        mFullPssPending = true;
15629        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15630        mPendingPssProcesses.clear();
15631        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15632            ProcessRecord app = mLruProcesses.get(i);
15633            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15634                app.pssProcState = app.setProcState;
15635                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15636                        isSleeping(), now);
15637                mPendingPssProcesses.add(app);
15638            }
15639        }
15640        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15641    }
15642
15643    /**
15644     * Ask a given process to GC right now.
15645     */
15646    final void performAppGcLocked(ProcessRecord app) {
15647        try {
15648            app.lastRequestedGc = SystemClock.uptimeMillis();
15649            if (app.thread != null) {
15650                if (app.reportLowMemory) {
15651                    app.reportLowMemory = false;
15652                    app.thread.scheduleLowMemory();
15653                } else {
15654                    app.thread.processInBackground();
15655                }
15656            }
15657        } catch (Exception e) {
15658            // whatever.
15659        }
15660    }
15661
15662    /**
15663     * Returns true if things are idle enough to perform GCs.
15664     */
15665    private final boolean canGcNowLocked() {
15666        boolean processingBroadcasts = false;
15667        for (BroadcastQueue q : mBroadcastQueues) {
15668            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15669                processingBroadcasts = true;
15670            }
15671        }
15672        return !processingBroadcasts
15673                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15674    }
15675
15676    /**
15677     * Perform GCs on all processes that are waiting for it, but only
15678     * if things are idle.
15679     */
15680    final void performAppGcsLocked() {
15681        final int N = mProcessesToGc.size();
15682        if (N <= 0) {
15683            return;
15684        }
15685        if (canGcNowLocked()) {
15686            while (mProcessesToGc.size() > 0) {
15687                ProcessRecord proc = mProcessesToGc.remove(0);
15688                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15689                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15690                            <= SystemClock.uptimeMillis()) {
15691                        // To avoid spamming the system, we will GC processes one
15692                        // at a time, waiting a few seconds between each.
15693                        performAppGcLocked(proc);
15694                        scheduleAppGcsLocked();
15695                        return;
15696                    } else {
15697                        // It hasn't been long enough since we last GCed this
15698                        // process...  put it in the list to wait for its time.
15699                        addProcessToGcListLocked(proc);
15700                        break;
15701                    }
15702                }
15703            }
15704
15705            scheduleAppGcsLocked();
15706        }
15707    }
15708
15709    /**
15710     * If all looks good, perform GCs on all processes waiting for them.
15711     */
15712    final void performAppGcsIfAppropriateLocked() {
15713        if (canGcNowLocked()) {
15714            performAppGcsLocked();
15715            return;
15716        }
15717        // Still not idle, wait some more.
15718        scheduleAppGcsLocked();
15719    }
15720
15721    /**
15722     * Schedule the execution of all pending app GCs.
15723     */
15724    final void scheduleAppGcsLocked() {
15725        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15726
15727        if (mProcessesToGc.size() > 0) {
15728            // Schedule a GC for the time to the next process.
15729            ProcessRecord proc = mProcessesToGc.get(0);
15730            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15731
15732            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15733            long now = SystemClock.uptimeMillis();
15734            if (when < (now+GC_TIMEOUT)) {
15735                when = now + GC_TIMEOUT;
15736            }
15737            mHandler.sendMessageAtTime(msg, when);
15738        }
15739    }
15740
15741    /**
15742     * Add a process to the array of processes waiting to be GCed.  Keeps the
15743     * list in sorted order by the last GC time.  The process can't already be
15744     * on the list.
15745     */
15746    final void addProcessToGcListLocked(ProcessRecord proc) {
15747        boolean added = false;
15748        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15749            if (mProcessesToGc.get(i).lastRequestedGc <
15750                    proc.lastRequestedGc) {
15751                added = true;
15752                mProcessesToGc.add(i+1, proc);
15753                break;
15754            }
15755        }
15756        if (!added) {
15757            mProcessesToGc.add(0, proc);
15758        }
15759    }
15760
15761    /**
15762     * Set up to ask a process to GC itself.  This will either do it
15763     * immediately, or put it on the list of processes to gc the next
15764     * time things are idle.
15765     */
15766    final void scheduleAppGcLocked(ProcessRecord app) {
15767        long now = SystemClock.uptimeMillis();
15768        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15769            return;
15770        }
15771        if (!mProcessesToGc.contains(app)) {
15772            addProcessToGcListLocked(app);
15773            scheduleAppGcsLocked();
15774        }
15775    }
15776
15777    final void checkExcessivePowerUsageLocked(boolean doKills) {
15778        updateCpuStatsNow();
15779
15780        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15781        boolean doWakeKills = doKills;
15782        boolean doCpuKills = doKills;
15783        if (mLastPowerCheckRealtime == 0) {
15784            doWakeKills = false;
15785        }
15786        if (mLastPowerCheckUptime == 0) {
15787            doCpuKills = false;
15788        }
15789        if (stats.isScreenOn()) {
15790            doWakeKills = false;
15791        }
15792        final long curRealtime = SystemClock.elapsedRealtime();
15793        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15794        final long curUptime = SystemClock.uptimeMillis();
15795        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15796        mLastPowerCheckRealtime = curRealtime;
15797        mLastPowerCheckUptime = curUptime;
15798        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15799            doWakeKills = false;
15800        }
15801        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15802            doCpuKills = false;
15803        }
15804        int i = mLruProcesses.size();
15805        while (i > 0) {
15806            i--;
15807            ProcessRecord app = mLruProcesses.get(i);
15808            if (!app.keeping) {
15809                long wtime;
15810                synchronized (stats) {
15811                    wtime = stats.getProcessWakeTime(app.info.uid,
15812                            app.pid, curRealtime);
15813                }
15814                long wtimeUsed = wtime - app.lastWakeTime;
15815                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15816                if (DEBUG_POWER) {
15817                    StringBuilder sb = new StringBuilder(128);
15818                    sb.append("Wake for ");
15819                    app.toShortString(sb);
15820                    sb.append(": over ");
15821                    TimeUtils.formatDuration(realtimeSince, sb);
15822                    sb.append(" used ");
15823                    TimeUtils.formatDuration(wtimeUsed, sb);
15824                    sb.append(" (");
15825                    sb.append((wtimeUsed*100)/realtimeSince);
15826                    sb.append("%)");
15827                    Slog.i(TAG, sb.toString());
15828                    sb.setLength(0);
15829                    sb.append("CPU for ");
15830                    app.toShortString(sb);
15831                    sb.append(": over ");
15832                    TimeUtils.formatDuration(uptimeSince, sb);
15833                    sb.append(" used ");
15834                    TimeUtils.formatDuration(cputimeUsed, sb);
15835                    sb.append(" (");
15836                    sb.append((cputimeUsed*100)/uptimeSince);
15837                    sb.append("%)");
15838                    Slog.i(TAG, sb.toString());
15839                }
15840                // If a process has held a wake lock for more
15841                // than 50% of the time during this period,
15842                // that sounds bad.  Kill!
15843                if (doWakeKills && realtimeSince > 0
15844                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15845                    synchronized (stats) {
15846                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15847                                realtimeSince, wtimeUsed);
15848                    }
15849                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15850                            + " during " + realtimeSince);
15851                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15852                } else if (doCpuKills && uptimeSince > 0
15853                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15854                    synchronized (stats) {
15855                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15856                                uptimeSince, cputimeUsed);
15857                    }
15858                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15859                            + " during " + uptimeSince);
15860                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15861                } else {
15862                    app.lastWakeTime = wtime;
15863                    app.lastCpuTime = app.curCpuTime;
15864                }
15865            }
15866        }
15867    }
15868
15869    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15870            ProcessRecord TOP_APP, boolean doingAll, long now) {
15871        boolean success = true;
15872
15873        if (app.curRawAdj != app.setRawAdj) {
15874            if (wasKeeping && !app.keeping) {
15875                // This app is no longer something we want to keep.  Note
15876                // its current wake lock time to later know to kill it if
15877                // it is not behaving well.
15878                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15879                synchronized (stats) {
15880                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15881                            app.pid, SystemClock.elapsedRealtime());
15882                }
15883                app.lastCpuTime = app.curCpuTime;
15884            }
15885
15886            app.setRawAdj = app.curRawAdj;
15887        }
15888
15889        int changes = 0;
15890
15891        if (app.curAdj != app.setAdj) {
15892            ProcessList.setOomAdj(app.pid, app.curAdj);
15893            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15894                TAG, "Set " + app.pid + " " + app.processName +
15895                " adj " + app.curAdj + ": " + app.adjType);
15896            app.setAdj = app.curAdj;
15897        }
15898
15899        if (app.setSchedGroup != app.curSchedGroup) {
15900            app.setSchedGroup = app.curSchedGroup;
15901            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15902                    "Setting process group of " + app.processName
15903                    + " to " + app.curSchedGroup);
15904            if (app.waitingToKill != null &&
15905                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15906                killUnneededProcessLocked(app, app.waitingToKill);
15907                success = false;
15908            } else {
15909                if (true) {
15910                    long oldId = Binder.clearCallingIdentity();
15911                    try {
15912                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15913                    } catch (Exception e) {
15914                        Slog.w(TAG, "Failed setting process group of " + app.pid
15915                                + " to " + app.curSchedGroup);
15916                        e.printStackTrace();
15917                    } finally {
15918                        Binder.restoreCallingIdentity(oldId);
15919                    }
15920                } else {
15921                    if (app.thread != null) {
15922                        try {
15923                            app.thread.setSchedulingGroup(app.curSchedGroup);
15924                        } catch (RemoteException e) {
15925                        }
15926                    }
15927                }
15928                Process.setSwappiness(app.pid,
15929                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15930            }
15931        }
15932        if (app.repForegroundActivities != app.foregroundActivities) {
15933            app.repForegroundActivities = app.foregroundActivities;
15934            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15935        }
15936        if (app.repProcState != app.curProcState) {
15937            app.repProcState = app.curProcState;
15938            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15939            if (app.thread != null) {
15940                try {
15941                    if (false) {
15942                        //RuntimeException h = new RuntimeException("here");
15943                        Slog.i(TAG, "Sending new process state " + app.repProcState
15944                                + " to " + app /*, h*/);
15945                    }
15946                    app.thread.setProcessState(app.repProcState);
15947                } catch (RemoteException e) {
15948                }
15949            }
15950        }
15951        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15952                app.setProcState)) {
15953            app.lastStateTime = now;
15954            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15955                    isSleeping(), now);
15956            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15957                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15958                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15959                    + (app.nextPssTime-now) + ": " + app);
15960        } else {
15961            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15962                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15963                requestPssLocked(app, app.setProcState);
15964                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15965                        isSleeping(), now);
15966            } else if (false && DEBUG_PSS) {
15967                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15968            }
15969        }
15970        if (app.setProcState != app.curProcState) {
15971            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15972                    "Proc state change of " + app.processName
15973                    + " to " + app.curProcState);
15974            app.setProcState = app.curProcState;
15975            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15976                app.notCachedSinceIdle = false;
15977            }
15978            if (!doingAll) {
15979                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15980            } else {
15981                app.procStateChanged = true;
15982            }
15983        }
15984
15985        if (changes != 0) {
15986            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15987            int i = mPendingProcessChanges.size()-1;
15988            ProcessChangeItem item = null;
15989            while (i >= 0) {
15990                item = mPendingProcessChanges.get(i);
15991                if (item.pid == app.pid) {
15992                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15993                    break;
15994                }
15995                i--;
15996            }
15997            if (i < 0) {
15998                // No existing item in pending changes; need a new one.
15999                final int NA = mAvailProcessChanges.size();
16000                if (NA > 0) {
16001                    item = mAvailProcessChanges.remove(NA-1);
16002                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16003                } else {
16004                    item = new ProcessChangeItem();
16005                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16006                }
16007                item.changes = 0;
16008                item.pid = app.pid;
16009                item.uid = app.info.uid;
16010                if (mPendingProcessChanges.size() == 0) {
16011                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16012                            "*** Enqueueing dispatch processes changed!");
16013                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16014                }
16015                mPendingProcessChanges.add(item);
16016            }
16017            item.changes |= changes;
16018            item.processState = app.repProcState;
16019            item.foregroundActivities = app.repForegroundActivities;
16020            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16021                    + Integer.toHexString(System.identityHashCode(item))
16022                    + " " + app.toShortString() + ": changes=" + item.changes
16023                    + " procState=" + item.processState
16024                    + " foreground=" + item.foregroundActivities
16025                    + " type=" + app.adjType + " source=" + app.adjSource
16026                    + " target=" + app.adjTarget);
16027        }
16028
16029        return success;
16030    }
16031
16032    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
16033        if (proc.thread != null && proc.baseProcessTracker != null) {
16034            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16035        }
16036    }
16037
16038    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16039            ProcessRecord TOP_APP, boolean doingAll, long now) {
16040        if (app.thread == null) {
16041            return false;
16042        }
16043
16044        final boolean wasKeeping = app.keeping;
16045
16046        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16047
16048        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
16049    }
16050
16051    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16052            boolean oomAdj) {
16053        if (isForeground != proc.foregroundServices) {
16054            proc.foregroundServices = isForeground;
16055            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16056                    proc.info.uid);
16057            if (isForeground) {
16058                if (curProcs == null) {
16059                    curProcs = new ArrayList<ProcessRecord>();
16060                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16061                }
16062                if (!curProcs.contains(proc)) {
16063                    curProcs.add(proc);
16064                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16065                            proc.info.packageName, proc.info.uid);
16066                }
16067            } else {
16068                if (curProcs != null) {
16069                    if (curProcs.remove(proc)) {
16070                        mBatteryStatsService.noteEvent(
16071                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16072                                proc.info.packageName, proc.info.uid);
16073                        if (curProcs.size() <= 0) {
16074                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16075                        }
16076                    }
16077                }
16078            }
16079            if (oomAdj) {
16080                updateOomAdjLocked();
16081            }
16082        }
16083    }
16084
16085    private final ActivityRecord resumedAppLocked() {
16086        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16087        String pkg;
16088        int uid;
16089        if (act != null && !act.sleeping) {
16090            pkg = act.packageName;
16091            uid = act.info.applicationInfo.uid;
16092        } else {
16093            pkg = null;
16094            uid = -1;
16095        }
16096        // Has the UID or resumed package name changed?
16097        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16098                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16099            if (mCurResumedPackage != null) {
16100                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16101                        mCurResumedPackage, mCurResumedUid);
16102            }
16103            mCurResumedPackage = pkg;
16104            mCurResumedUid = uid;
16105            if (mCurResumedPackage != null) {
16106                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16107                        mCurResumedPackage, mCurResumedUid);
16108            }
16109        }
16110        return act;
16111    }
16112
16113    final boolean updateOomAdjLocked(ProcessRecord app) {
16114        final ActivityRecord TOP_ACT = resumedAppLocked();
16115        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16116        final boolean wasCached = app.cached;
16117
16118        mAdjSeq++;
16119
16120        // This is the desired cached adjusment we want to tell it to use.
16121        // If our app is currently cached, we know it, and that is it.  Otherwise,
16122        // we don't know it yet, and it needs to now be cached we will then
16123        // need to do a complete oom adj.
16124        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16125                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16126        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16127                SystemClock.uptimeMillis());
16128        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16129            // Changed to/from cached state, so apps after it in the LRU
16130            // list may also be changed.
16131            updateOomAdjLocked();
16132        }
16133        return success;
16134    }
16135
16136    final void updateOomAdjLocked() {
16137        final ActivityRecord TOP_ACT = resumedAppLocked();
16138        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16139        final long now = SystemClock.uptimeMillis();
16140        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16141        final int N = mLruProcesses.size();
16142
16143        if (false) {
16144            RuntimeException e = new RuntimeException();
16145            e.fillInStackTrace();
16146            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16147        }
16148
16149        mAdjSeq++;
16150        mNewNumServiceProcs = 0;
16151        mNewNumAServiceProcs = 0;
16152
16153        final int emptyProcessLimit;
16154        final int cachedProcessLimit;
16155        if (mProcessLimit <= 0) {
16156            emptyProcessLimit = cachedProcessLimit = 0;
16157        } else if (mProcessLimit == 1) {
16158            emptyProcessLimit = 1;
16159            cachedProcessLimit = 0;
16160        } else {
16161            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16162            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16163        }
16164
16165        // Let's determine how many processes we have running vs.
16166        // how many slots we have for background processes; we may want
16167        // to put multiple processes in a slot of there are enough of
16168        // them.
16169        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16170                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16171        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16172        if (numEmptyProcs > cachedProcessLimit) {
16173            // If there are more empty processes than our limit on cached
16174            // processes, then use the cached process limit for the factor.
16175            // This ensures that the really old empty processes get pushed
16176            // down to the bottom, so if we are running low on memory we will
16177            // have a better chance at keeping around more cached processes
16178            // instead of a gazillion empty processes.
16179            numEmptyProcs = cachedProcessLimit;
16180        }
16181        int emptyFactor = numEmptyProcs/numSlots;
16182        if (emptyFactor < 1) emptyFactor = 1;
16183        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16184        if (cachedFactor < 1) cachedFactor = 1;
16185        int stepCached = 0;
16186        int stepEmpty = 0;
16187        int numCached = 0;
16188        int numEmpty = 0;
16189        int numTrimming = 0;
16190
16191        mNumNonCachedProcs = 0;
16192        mNumCachedHiddenProcs = 0;
16193
16194        // First update the OOM adjustment for each of the
16195        // application processes based on their current state.
16196        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16197        int nextCachedAdj = curCachedAdj+1;
16198        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16199        int nextEmptyAdj = curEmptyAdj+2;
16200        for (int i=N-1; i>=0; i--) {
16201            ProcessRecord app = mLruProcesses.get(i);
16202            if (!app.killedByAm && app.thread != null) {
16203                app.procStateChanged = false;
16204                final boolean wasKeeping = app.keeping;
16205                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16206
16207                // If we haven't yet assigned the final cached adj
16208                // to the process, do that now.
16209                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16210                    switch (app.curProcState) {
16211                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16212                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16213                            // This process is a cached process holding activities...
16214                            // assign it the next cached value for that type, and then
16215                            // step that cached level.
16216                            app.curRawAdj = curCachedAdj;
16217                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16218                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16219                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16220                                    + ")");
16221                            if (curCachedAdj != nextCachedAdj) {
16222                                stepCached++;
16223                                if (stepCached >= cachedFactor) {
16224                                    stepCached = 0;
16225                                    curCachedAdj = nextCachedAdj;
16226                                    nextCachedAdj += 2;
16227                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16228                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16229                                    }
16230                                }
16231                            }
16232                            break;
16233                        default:
16234                            // For everything else, assign next empty cached process
16235                            // level and bump that up.  Note that this means that
16236                            // long-running services that have dropped down to the
16237                            // cached level will be treated as empty (since their process
16238                            // state is still as a service), which is what we want.
16239                            app.curRawAdj = curEmptyAdj;
16240                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16241                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16242                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16243                                    + ")");
16244                            if (curEmptyAdj != nextEmptyAdj) {
16245                                stepEmpty++;
16246                                if (stepEmpty >= emptyFactor) {
16247                                    stepEmpty = 0;
16248                                    curEmptyAdj = nextEmptyAdj;
16249                                    nextEmptyAdj += 2;
16250                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16251                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16252                                    }
16253                                }
16254                            }
16255                            break;
16256                    }
16257                }
16258
16259                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16260
16261                // Count the number of process types.
16262                switch (app.curProcState) {
16263                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16264                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16265                        mNumCachedHiddenProcs++;
16266                        numCached++;
16267                        if (numCached > cachedProcessLimit) {
16268                            killUnneededProcessLocked(app, "cached #" + numCached);
16269                        }
16270                        break;
16271                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16272                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16273                                && app.lastActivityTime < oldTime) {
16274                            killUnneededProcessLocked(app, "empty for "
16275                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16276                                    / 1000) + "s");
16277                        } else {
16278                            numEmpty++;
16279                            if (numEmpty > emptyProcessLimit) {
16280                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16281                            }
16282                        }
16283                        break;
16284                    default:
16285                        mNumNonCachedProcs++;
16286                        break;
16287                }
16288
16289                if (app.isolated && app.services.size() <= 0) {
16290                    // If this is an isolated process, and there are no
16291                    // services running in it, then the process is no longer
16292                    // needed.  We agressively kill these because we can by
16293                    // definition not re-use the same process again, and it is
16294                    // good to avoid having whatever code was running in them
16295                    // left sitting around after no longer needed.
16296                    killUnneededProcessLocked(app, "isolated not needed");
16297                }
16298
16299                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16300                        && !app.killedByAm) {
16301                    numTrimming++;
16302                }
16303            }
16304        }
16305
16306        mNumServiceProcs = mNewNumServiceProcs;
16307
16308        // Now determine the memory trimming level of background processes.
16309        // Unfortunately we need to start at the back of the list to do this
16310        // properly.  We only do this if the number of background apps we
16311        // are managing to keep around is less than half the maximum we desire;
16312        // if we are keeping a good number around, we'll let them use whatever
16313        // memory they want.
16314        final int numCachedAndEmpty = numCached + numEmpty;
16315        int memFactor;
16316        if (numCached <= ProcessList.TRIM_CACHED_APPS
16317                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16318            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16319                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16320            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16321                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16322            } else {
16323                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16324            }
16325        } else {
16326            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16327        }
16328        // We always allow the memory level to go up (better).  We only allow it to go
16329        // down if we are in a state where that is allowed, *and* the total number of processes
16330        // has gone down since last time.
16331        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16332                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16333                + " last=" + mLastNumProcesses);
16334        if (memFactor > mLastMemoryLevel) {
16335            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16336                memFactor = mLastMemoryLevel;
16337                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16338            }
16339        }
16340        mLastMemoryLevel = memFactor;
16341        mLastNumProcesses = mLruProcesses.size();
16342        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16343        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16344        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16345            if (mLowRamStartTime == 0) {
16346                mLowRamStartTime = now;
16347            }
16348            int step = 0;
16349            int fgTrimLevel;
16350            switch (memFactor) {
16351                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16352                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16353                    break;
16354                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16355                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16356                    break;
16357                default:
16358                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16359                    break;
16360            }
16361            int factor = numTrimming/3;
16362            int minFactor = 2;
16363            if (mHomeProcess != null) minFactor++;
16364            if (mPreviousProcess != null) minFactor++;
16365            if (factor < minFactor) factor = minFactor;
16366            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16367            for (int i=N-1; i>=0; i--) {
16368                ProcessRecord app = mLruProcesses.get(i);
16369                if (allChanged || app.procStateChanged) {
16370                    setProcessTrackerState(app, trackerMemFactor, now);
16371                    app.procStateChanged = false;
16372                }
16373                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16374                        && !app.killedByAm) {
16375                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16376                        try {
16377                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16378                                    "Trimming memory of " + app.processName
16379                                    + " to " + curLevel);
16380                            app.thread.scheduleTrimMemory(curLevel);
16381                        } catch (RemoteException e) {
16382                        }
16383                        if (false) {
16384                            // For now we won't do this; our memory trimming seems
16385                            // to be good enough at this point that destroying
16386                            // activities causes more harm than good.
16387                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16388                                    && app != mHomeProcess && app != mPreviousProcess) {
16389                                // Need to do this on its own message because the stack may not
16390                                // be in a consistent state at this point.
16391                                // For these apps we will also finish their activities
16392                                // to help them free memory.
16393                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16394                            }
16395                        }
16396                    }
16397                    app.trimMemoryLevel = curLevel;
16398                    step++;
16399                    if (step >= factor) {
16400                        step = 0;
16401                        switch (curLevel) {
16402                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16403                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16404                                break;
16405                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16406                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16407                                break;
16408                        }
16409                    }
16410                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16411                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16412                            && app.thread != null) {
16413                        try {
16414                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16415                                    "Trimming memory of heavy-weight " + app.processName
16416                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16417                            app.thread.scheduleTrimMemory(
16418                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16419                        } catch (RemoteException e) {
16420                        }
16421                    }
16422                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16423                } else {
16424                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16425                            || app.systemNoUi) && app.pendingUiClean) {
16426                        // If this application is now in the background and it
16427                        // had done UI, then give it the special trim level to
16428                        // have it free UI resources.
16429                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16430                        if (app.trimMemoryLevel < level && app.thread != null) {
16431                            try {
16432                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16433                                        "Trimming memory of bg-ui " + app.processName
16434                                        + " to " + level);
16435                                app.thread.scheduleTrimMemory(level);
16436                            } catch (RemoteException e) {
16437                            }
16438                        }
16439                        app.pendingUiClean = false;
16440                    }
16441                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16442                        try {
16443                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16444                                    "Trimming memory of fg " + app.processName
16445                                    + " to " + fgTrimLevel);
16446                            app.thread.scheduleTrimMemory(fgTrimLevel);
16447                        } catch (RemoteException e) {
16448                        }
16449                    }
16450                    app.trimMemoryLevel = fgTrimLevel;
16451                }
16452            }
16453        } else {
16454            if (mLowRamStartTime != 0) {
16455                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16456                mLowRamStartTime = 0;
16457            }
16458            for (int i=N-1; i>=0; i--) {
16459                ProcessRecord app = mLruProcesses.get(i);
16460                if (allChanged || app.procStateChanged) {
16461                    setProcessTrackerState(app, trackerMemFactor, now);
16462                    app.procStateChanged = false;
16463                }
16464                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16465                        || app.systemNoUi) && app.pendingUiClean) {
16466                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16467                            && app.thread != null) {
16468                        try {
16469                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16470                                    "Trimming memory of ui hidden " + app.processName
16471                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16472                            app.thread.scheduleTrimMemory(
16473                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16474                        } catch (RemoteException e) {
16475                        }
16476                    }
16477                    app.pendingUiClean = false;
16478                }
16479                app.trimMemoryLevel = 0;
16480            }
16481        }
16482
16483        if (mAlwaysFinishActivities) {
16484            // Need to do this on its own message because the stack may not
16485            // be in a consistent state at this point.
16486            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16487        }
16488
16489        if (allChanged) {
16490            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16491        }
16492
16493        if (mProcessStats.shouldWriteNowLocked(now)) {
16494            mHandler.post(new Runnable() {
16495                @Override public void run() {
16496                    synchronized (ActivityManagerService.this) {
16497                        mProcessStats.writeStateAsyncLocked();
16498                    }
16499                }
16500            });
16501        }
16502
16503        if (DEBUG_OOM_ADJ) {
16504            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16505        }
16506    }
16507
16508    final void trimApplications() {
16509        synchronized (this) {
16510            int i;
16511
16512            // First remove any unused application processes whose package
16513            // has been removed.
16514            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16515                final ProcessRecord app = mRemovedProcesses.get(i);
16516                if (app.activities.size() == 0
16517                        && app.curReceiver == null && app.services.size() == 0) {
16518                    Slog.i(
16519                        TAG, "Exiting empty application process "
16520                        + app.processName + " ("
16521                        + (app.thread != null ? app.thread.asBinder() : null)
16522                        + ")\n");
16523                    if (app.pid > 0 && app.pid != MY_PID) {
16524                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16525                                app.processName, app.setAdj, "empty");
16526                        app.killedByAm = true;
16527                        Process.killProcessQuiet(app.pid);
16528                    } else {
16529                        try {
16530                            app.thread.scheduleExit();
16531                        } catch (Exception e) {
16532                            // Ignore exceptions.
16533                        }
16534                    }
16535                    cleanUpApplicationRecordLocked(app, false, true, -1);
16536                    mRemovedProcesses.remove(i);
16537
16538                    if (app.persistent) {
16539                        if (app.persistent) {
16540                            addAppLocked(app.info, false, null /* ABI override */);
16541                        }
16542                    }
16543                }
16544            }
16545
16546            // Now update the oom adj for all processes.
16547            updateOomAdjLocked();
16548        }
16549    }
16550
16551    /** This method sends the specified signal to each of the persistent apps */
16552    public void signalPersistentProcesses(int sig) throws RemoteException {
16553        if (sig != Process.SIGNAL_USR1) {
16554            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16555        }
16556
16557        synchronized (this) {
16558            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16559                    != PackageManager.PERMISSION_GRANTED) {
16560                throw new SecurityException("Requires permission "
16561                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16562            }
16563
16564            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16565                ProcessRecord r = mLruProcesses.get(i);
16566                if (r.thread != null && r.persistent) {
16567                    Process.sendSignal(r.pid, sig);
16568                }
16569            }
16570        }
16571    }
16572
16573    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16574        if (proc == null || proc == mProfileProc) {
16575            proc = mProfileProc;
16576            path = mProfileFile;
16577            profileType = mProfileType;
16578            clearProfilerLocked();
16579        }
16580        if (proc == null) {
16581            return;
16582        }
16583        try {
16584            proc.thread.profilerControl(false, path, null, profileType);
16585        } catch (RemoteException e) {
16586            throw new IllegalStateException("Process disappeared");
16587        }
16588    }
16589
16590    private void clearProfilerLocked() {
16591        if (mProfileFd != null) {
16592            try {
16593                mProfileFd.close();
16594            } catch (IOException e) {
16595            }
16596        }
16597        mProfileApp = null;
16598        mProfileProc = null;
16599        mProfileFile = null;
16600        mProfileType = 0;
16601        mAutoStopProfiler = false;
16602    }
16603
16604    public boolean profileControl(String process, int userId, boolean start,
16605            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16606
16607        try {
16608            synchronized (this) {
16609                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16610                // its own permission.
16611                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16612                        != PackageManager.PERMISSION_GRANTED) {
16613                    throw new SecurityException("Requires permission "
16614                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16615                }
16616
16617                if (start && fd == null) {
16618                    throw new IllegalArgumentException("null fd");
16619                }
16620
16621                ProcessRecord proc = null;
16622                if (process != null) {
16623                    proc = findProcessLocked(process, userId, "profileControl");
16624                }
16625
16626                if (start && (proc == null || proc.thread == null)) {
16627                    throw new IllegalArgumentException("Unknown process: " + process);
16628                }
16629
16630                if (start) {
16631                    stopProfilerLocked(null, null, 0);
16632                    setProfileApp(proc.info, proc.processName, path, fd, false);
16633                    mProfileProc = proc;
16634                    mProfileType = profileType;
16635                    try {
16636                        fd = fd.dup();
16637                    } catch (IOException e) {
16638                        fd = null;
16639                    }
16640                    proc.thread.profilerControl(start, path, fd, profileType);
16641                    fd = null;
16642                    mProfileFd = null;
16643                } else {
16644                    stopProfilerLocked(proc, path, profileType);
16645                    if (fd != null) {
16646                        try {
16647                            fd.close();
16648                        } catch (IOException e) {
16649                        }
16650                    }
16651                }
16652
16653                return true;
16654            }
16655        } catch (RemoteException e) {
16656            throw new IllegalStateException("Process disappeared");
16657        } finally {
16658            if (fd != null) {
16659                try {
16660                    fd.close();
16661                } catch (IOException e) {
16662                }
16663            }
16664        }
16665    }
16666
16667    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16668        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16669                userId, true, true, callName, null);
16670        ProcessRecord proc = null;
16671        try {
16672            int pid = Integer.parseInt(process);
16673            synchronized (mPidsSelfLocked) {
16674                proc = mPidsSelfLocked.get(pid);
16675            }
16676        } catch (NumberFormatException e) {
16677        }
16678
16679        if (proc == null) {
16680            ArrayMap<String, SparseArray<ProcessRecord>> all
16681                    = mProcessNames.getMap();
16682            SparseArray<ProcessRecord> procs = all.get(process);
16683            if (procs != null && procs.size() > 0) {
16684                proc = procs.valueAt(0);
16685                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16686                    for (int i=1; i<procs.size(); i++) {
16687                        ProcessRecord thisProc = procs.valueAt(i);
16688                        if (thisProc.userId == userId) {
16689                            proc = thisProc;
16690                            break;
16691                        }
16692                    }
16693                }
16694            }
16695        }
16696
16697        return proc;
16698    }
16699
16700    public boolean dumpHeap(String process, int userId, boolean managed,
16701            String path, ParcelFileDescriptor fd) throws RemoteException {
16702
16703        try {
16704            synchronized (this) {
16705                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16706                // its own permission (same as profileControl).
16707                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16708                        != PackageManager.PERMISSION_GRANTED) {
16709                    throw new SecurityException("Requires permission "
16710                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16711                }
16712
16713                if (fd == null) {
16714                    throw new IllegalArgumentException("null fd");
16715                }
16716
16717                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16718                if (proc == null || proc.thread == null) {
16719                    throw new IllegalArgumentException("Unknown process: " + process);
16720                }
16721
16722                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16723                if (!isDebuggable) {
16724                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16725                        throw new SecurityException("Process not debuggable: " + proc);
16726                    }
16727                }
16728
16729                proc.thread.dumpHeap(managed, path, fd);
16730                fd = null;
16731                return true;
16732            }
16733        } catch (RemoteException e) {
16734            throw new IllegalStateException("Process disappeared");
16735        } finally {
16736            if (fd != null) {
16737                try {
16738                    fd.close();
16739                } catch (IOException e) {
16740                }
16741            }
16742        }
16743    }
16744
16745    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16746    public void monitor() {
16747        synchronized (this) { }
16748    }
16749
16750    void onCoreSettingsChange(Bundle settings) {
16751        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16752            ProcessRecord processRecord = mLruProcesses.get(i);
16753            try {
16754                if (processRecord.thread != null) {
16755                    processRecord.thread.setCoreSettings(settings);
16756                }
16757            } catch (RemoteException re) {
16758                /* ignore */
16759            }
16760        }
16761    }
16762
16763    // Multi-user methods
16764
16765    /**
16766     * Start user, if its not already running, but don't bring it to foreground.
16767     */
16768    @Override
16769    public boolean startUserInBackground(final int userId) {
16770        return startUser(userId, /* foreground */ false);
16771    }
16772
16773    /**
16774     * Refreshes the list of users related to the current user when either a
16775     * user switch happens or when a new related user is started in the
16776     * background.
16777     */
16778    private void updateCurrentProfileIdsLocked() {
16779        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16780                mCurrentUserId, false /* enabledOnly */);
16781        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16782        for (int i = 0; i < currentProfileIds.length; i++) {
16783            currentProfileIds[i] = profiles.get(i).id;
16784        }
16785        mCurrentProfileIds = currentProfileIds;
16786    }
16787
16788    private Set getProfileIdsLocked(int userId) {
16789        Set userIds = new HashSet<Integer>();
16790        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16791                userId, false /* enabledOnly */);
16792        for (UserInfo user : profiles) {
16793            userIds.add(Integer.valueOf(user.id));
16794        }
16795        return userIds;
16796    }
16797
16798    @Override
16799    public boolean switchUser(final int userId) {
16800        return startUser(userId, /* foregound */ true);
16801    }
16802
16803    private boolean startUser(final int userId, boolean foreground) {
16804        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16805                != PackageManager.PERMISSION_GRANTED) {
16806            String msg = "Permission Denial: switchUser() from pid="
16807                    + Binder.getCallingPid()
16808                    + ", uid=" + Binder.getCallingUid()
16809                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16810            Slog.w(TAG, msg);
16811            throw new SecurityException(msg);
16812        }
16813
16814        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16815
16816        final long ident = Binder.clearCallingIdentity();
16817        try {
16818            synchronized (this) {
16819                final int oldUserId = mCurrentUserId;
16820                if (oldUserId == userId) {
16821                    return true;
16822                }
16823
16824                mStackSupervisor.setLockTaskModeLocked(null, false);
16825
16826                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16827                if (userInfo == null) {
16828                    Slog.w(TAG, "No user info for user #" + userId);
16829                    return false;
16830                }
16831
16832                if (foreground) {
16833                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16834                            R.anim.screen_user_enter);
16835                }
16836
16837                boolean needStart = false;
16838
16839                // If the user we are switching to is not currently started, then
16840                // we need to start it now.
16841                if (mStartedUsers.get(userId) == null) {
16842                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16843                    updateStartedUserArrayLocked();
16844                    needStart = true;
16845                }
16846
16847                final Integer userIdInt = Integer.valueOf(userId);
16848                mUserLru.remove(userIdInt);
16849                mUserLru.add(userIdInt);
16850
16851                if (foreground) {
16852                    mCurrentUserId = userId;
16853                    updateCurrentProfileIdsLocked();
16854                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16855                    // Once the internal notion of the active user has switched, we lock the device
16856                    // with the option to show the user switcher on the keyguard.
16857                    mWindowManager.lockNow(null);
16858                } else {
16859                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16860                    updateCurrentProfileIdsLocked();
16861                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16862                    mUserLru.remove(currentUserIdInt);
16863                    mUserLru.add(currentUserIdInt);
16864                }
16865
16866                final UserStartedState uss = mStartedUsers.get(userId);
16867
16868                // Make sure user is in the started state.  If it is currently
16869                // stopping, we need to knock that off.
16870                if (uss.mState == UserStartedState.STATE_STOPPING) {
16871                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16872                    // so we can just fairly silently bring the user back from
16873                    // the almost-dead.
16874                    uss.mState = UserStartedState.STATE_RUNNING;
16875                    updateStartedUserArrayLocked();
16876                    needStart = true;
16877                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16878                    // This means ACTION_SHUTDOWN has been sent, so we will
16879                    // need to treat this as a new boot of the user.
16880                    uss.mState = UserStartedState.STATE_BOOTING;
16881                    updateStartedUserArrayLocked();
16882                    needStart = true;
16883                }
16884
16885                if (uss.mState == UserStartedState.STATE_BOOTING) {
16886                    // Booting up a new user, need to tell system services about it.
16887                    // Note that this is on the same handler as scheduling of broadcasts,
16888                    // which is important because it needs to go first.
16889                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16890                }
16891
16892                if (foreground) {
16893                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16894                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16895                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16896                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16897                            oldUserId, userId, uss));
16898                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16899                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16900                }
16901
16902                if (needStart) {
16903                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16904                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16905                            | Intent.FLAG_RECEIVER_FOREGROUND);
16906                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16907                    broadcastIntentLocked(null, null, intent,
16908                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16909                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16910                }
16911
16912                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16913                    if (userId != UserHandle.USER_OWNER) {
16914                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16915                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16916                        broadcastIntentLocked(null, null, intent, null,
16917                                new IIntentReceiver.Stub() {
16918                                    public void performReceive(Intent intent, int resultCode,
16919                                            String data, Bundle extras, boolean ordered,
16920                                            boolean sticky, int sendingUser) {
16921                                        userInitialized(uss, userId);
16922                                    }
16923                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16924                                true, false, MY_PID, Process.SYSTEM_UID,
16925                                userId);
16926                        uss.initializing = true;
16927                    } else {
16928                        getUserManagerLocked().makeInitialized(userInfo.id);
16929                    }
16930                }
16931
16932                if (foreground) {
16933                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16934                    if (homeInFront) {
16935                        startHomeActivityLocked(userId);
16936                    } else {
16937                        mStackSupervisor.resumeTopActivitiesLocked();
16938                    }
16939                    EventLogTags.writeAmSwitchUser(userId);
16940                    getUserManagerLocked().userForeground(userId);
16941                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16942                } else {
16943                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16944                }
16945
16946                if (needStart) {
16947                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16948                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16949                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16950                    broadcastIntentLocked(null, null, intent,
16951                            null, new IIntentReceiver.Stub() {
16952                                @Override
16953                                public void performReceive(Intent intent, int resultCode, String data,
16954                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16955                                        throws RemoteException {
16956                                }
16957                            }, 0, null, null,
16958                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16959                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16960                }
16961            }
16962        } finally {
16963            Binder.restoreCallingIdentity(ident);
16964        }
16965
16966        return true;
16967    }
16968
16969    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16970        long ident = Binder.clearCallingIdentity();
16971        try {
16972            Intent intent;
16973            if (oldUserId >= 0) {
16974                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16975                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16976                        | Intent.FLAG_RECEIVER_FOREGROUND);
16977                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16978                broadcastIntentLocked(null, null, intent,
16979                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16980                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16981            }
16982            if (newUserId >= 0) {
16983                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16984                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16985                        | Intent.FLAG_RECEIVER_FOREGROUND);
16986                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16987                broadcastIntentLocked(null, null, intent,
16988                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16989                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16990                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16991                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16992                        | Intent.FLAG_RECEIVER_FOREGROUND);
16993                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16994                broadcastIntentLocked(null, null, intent,
16995                        null, null, 0, null, null,
16996                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16997                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16998            }
16999        } finally {
17000            Binder.restoreCallingIdentity(ident);
17001        }
17002    }
17003
17004    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17005            final int newUserId) {
17006        final int N = mUserSwitchObservers.beginBroadcast();
17007        if (N > 0) {
17008            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17009                int mCount = 0;
17010                @Override
17011                public void sendResult(Bundle data) throws RemoteException {
17012                    synchronized (ActivityManagerService.this) {
17013                        if (mCurUserSwitchCallback == this) {
17014                            mCount++;
17015                            if (mCount == N) {
17016                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17017                            }
17018                        }
17019                    }
17020                }
17021            };
17022            synchronized (this) {
17023                uss.switching = true;
17024                mCurUserSwitchCallback = callback;
17025            }
17026            for (int i=0; i<N; i++) {
17027                try {
17028                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17029                            newUserId, callback);
17030                } catch (RemoteException e) {
17031                }
17032            }
17033        } else {
17034            synchronized (this) {
17035                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17036            }
17037        }
17038        mUserSwitchObservers.finishBroadcast();
17039    }
17040
17041    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17042        synchronized (this) {
17043            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17044            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17045        }
17046    }
17047
17048    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17049        mCurUserSwitchCallback = null;
17050        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17051        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17052                oldUserId, newUserId, uss));
17053    }
17054
17055    void userInitialized(UserStartedState uss, int newUserId) {
17056        completeSwitchAndInitalize(uss, newUserId, true, false);
17057    }
17058
17059    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17060        completeSwitchAndInitalize(uss, newUserId, false, true);
17061    }
17062
17063    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17064            boolean clearInitializing, boolean clearSwitching) {
17065        boolean unfrozen = false;
17066        synchronized (this) {
17067            if (clearInitializing) {
17068                uss.initializing = false;
17069                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17070            }
17071            if (clearSwitching) {
17072                uss.switching = false;
17073            }
17074            if (!uss.switching && !uss.initializing) {
17075                mWindowManager.stopFreezingScreen();
17076                unfrozen = true;
17077            }
17078        }
17079        if (unfrozen) {
17080            final int N = mUserSwitchObservers.beginBroadcast();
17081            for (int i=0; i<N; i++) {
17082                try {
17083                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17084                } catch (RemoteException e) {
17085                }
17086            }
17087            mUserSwitchObservers.finishBroadcast();
17088        }
17089    }
17090
17091    void scheduleStartProfilesLocked() {
17092        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17093            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17094                    DateUtils.SECOND_IN_MILLIS);
17095        }
17096    }
17097
17098    void startProfilesLocked() {
17099        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17100        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17101                mCurrentUserId, false /* enabledOnly */);
17102        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17103        for (UserInfo user : profiles) {
17104            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17105                    && user.id != mCurrentUserId) {
17106                toStart.add(user);
17107            }
17108        }
17109        final int n = toStart.size();
17110        int i = 0;
17111        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17112            startUserInBackground(toStart.get(i).id);
17113        }
17114        if (i < n) {
17115            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17116        }
17117    }
17118
17119    void finishUserBoot(UserStartedState uss) {
17120        synchronized (this) {
17121            if (uss.mState == UserStartedState.STATE_BOOTING
17122                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17123                uss.mState = UserStartedState.STATE_RUNNING;
17124                final int userId = uss.mHandle.getIdentifier();
17125                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17126                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17127                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17128                broadcastIntentLocked(null, null, intent,
17129                        null, null, 0, null, null,
17130                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17131                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17132            }
17133        }
17134    }
17135
17136    void finishUserSwitch(UserStartedState uss) {
17137        synchronized (this) {
17138            finishUserBoot(uss);
17139
17140            startProfilesLocked();
17141
17142            int num = mUserLru.size();
17143            int i = 0;
17144            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17145                Integer oldUserId = mUserLru.get(i);
17146                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17147                if (oldUss == null) {
17148                    // Shouldn't happen, but be sane if it does.
17149                    mUserLru.remove(i);
17150                    num--;
17151                    continue;
17152                }
17153                if (oldUss.mState == UserStartedState.STATE_STOPPING
17154                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17155                    // This user is already stopping, doesn't count.
17156                    num--;
17157                    i++;
17158                    continue;
17159                }
17160                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17161                    // Owner and current can't be stopped, but count as running.
17162                    i++;
17163                    continue;
17164                }
17165                // This is a user to be stopped.
17166                stopUserLocked(oldUserId, null);
17167                num--;
17168                i++;
17169            }
17170        }
17171    }
17172
17173    @Override
17174    public int stopUser(final int userId, final IStopUserCallback callback) {
17175        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17176                != PackageManager.PERMISSION_GRANTED) {
17177            String msg = "Permission Denial: switchUser() from pid="
17178                    + Binder.getCallingPid()
17179                    + ", uid=" + Binder.getCallingUid()
17180                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17181            Slog.w(TAG, msg);
17182            throw new SecurityException(msg);
17183        }
17184        if (userId <= 0) {
17185            throw new IllegalArgumentException("Can't stop primary user " + userId);
17186        }
17187        synchronized (this) {
17188            return stopUserLocked(userId, callback);
17189        }
17190    }
17191
17192    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17193        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17194        if (mCurrentUserId == userId) {
17195            return ActivityManager.USER_OP_IS_CURRENT;
17196        }
17197
17198        final UserStartedState uss = mStartedUsers.get(userId);
17199        if (uss == null) {
17200            // User is not started, nothing to do...  but we do need to
17201            // callback if requested.
17202            if (callback != null) {
17203                mHandler.post(new Runnable() {
17204                    @Override
17205                    public void run() {
17206                        try {
17207                            callback.userStopped(userId);
17208                        } catch (RemoteException e) {
17209                        }
17210                    }
17211                });
17212            }
17213            return ActivityManager.USER_OP_SUCCESS;
17214        }
17215
17216        if (callback != null) {
17217            uss.mStopCallbacks.add(callback);
17218        }
17219
17220        if (uss.mState != UserStartedState.STATE_STOPPING
17221                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17222            uss.mState = UserStartedState.STATE_STOPPING;
17223            updateStartedUserArrayLocked();
17224
17225            long ident = Binder.clearCallingIdentity();
17226            try {
17227                // We are going to broadcast ACTION_USER_STOPPING and then
17228                // once that is done send a final ACTION_SHUTDOWN and then
17229                // stop the user.
17230                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17231                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17232                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17233                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17234                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17235                // This is the result receiver for the final shutdown broadcast.
17236                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17237                    @Override
17238                    public void performReceive(Intent intent, int resultCode, String data,
17239                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17240                        finishUserStop(uss);
17241                    }
17242                };
17243                // This is the result receiver for the initial stopping broadcast.
17244                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17245                    @Override
17246                    public void performReceive(Intent intent, int resultCode, String data,
17247                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17248                        // On to the next.
17249                        synchronized (ActivityManagerService.this) {
17250                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17251                                // Whoops, we are being started back up.  Abort, abort!
17252                                return;
17253                            }
17254                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17255                        }
17256                        mSystemServiceManager.stopUser(userId);
17257                        broadcastIntentLocked(null, null, shutdownIntent,
17258                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17259                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17260                    }
17261                };
17262                // Kick things off.
17263                broadcastIntentLocked(null, null, stoppingIntent,
17264                        null, stoppingReceiver, 0, null, null,
17265                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17266                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17267            } finally {
17268                Binder.restoreCallingIdentity(ident);
17269            }
17270        }
17271
17272        return ActivityManager.USER_OP_SUCCESS;
17273    }
17274
17275    void finishUserStop(UserStartedState uss) {
17276        final int userId = uss.mHandle.getIdentifier();
17277        boolean stopped;
17278        ArrayList<IStopUserCallback> callbacks;
17279        synchronized (this) {
17280            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17281            if (mStartedUsers.get(userId) != uss) {
17282                stopped = false;
17283            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17284                stopped = false;
17285            } else {
17286                stopped = true;
17287                // User can no longer run.
17288                mStartedUsers.remove(userId);
17289                mUserLru.remove(Integer.valueOf(userId));
17290                updateStartedUserArrayLocked();
17291
17292                // Clean up all state and processes associated with the user.
17293                // Kill all the processes for the user.
17294                forceStopUserLocked(userId, "finish user");
17295            }
17296        }
17297
17298        for (int i=0; i<callbacks.size(); i++) {
17299            try {
17300                if (stopped) callbacks.get(i).userStopped(userId);
17301                else callbacks.get(i).userStopAborted(userId);
17302            } catch (RemoteException e) {
17303            }
17304        }
17305
17306        if (stopped) {
17307            mSystemServiceManager.cleanupUser(userId);
17308            synchronized (this) {
17309                mStackSupervisor.removeUserLocked(userId);
17310            }
17311        }
17312    }
17313
17314    @Override
17315    public UserInfo getCurrentUser() {
17316        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17317                != PackageManager.PERMISSION_GRANTED) && (
17318                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17319                != PackageManager.PERMISSION_GRANTED)) {
17320            String msg = "Permission Denial: getCurrentUser() from pid="
17321                    + Binder.getCallingPid()
17322                    + ", uid=" + Binder.getCallingUid()
17323                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17324            Slog.w(TAG, msg);
17325            throw new SecurityException(msg);
17326        }
17327        synchronized (this) {
17328            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17329        }
17330    }
17331
17332    int getCurrentUserIdLocked() {
17333        return mCurrentUserId;
17334    }
17335
17336    @Override
17337    public boolean isUserRunning(int userId, boolean orStopped) {
17338        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17339                != PackageManager.PERMISSION_GRANTED) {
17340            String msg = "Permission Denial: isUserRunning() from pid="
17341                    + Binder.getCallingPid()
17342                    + ", uid=" + Binder.getCallingUid()
17343                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17344            Slog.w(TAG, msg);
17345            throw new SecurityException(msg);
17346        }
17347        synchronized (this) {
17348            return isUserRunningLocked(userId, orStopped);
17349        }
17350    }
17351
17352    boolean isUserRunningLocked(int userId, boolean orStopped) {
17353        UserStartedState state = mStartedUsers.get(userId);
17354        if (state == null) {
17355            return false;
17356        }
17357        if (orStopped) {
17358            return true;
17359        }
17360        return state.mState != UserStartedState.STATE_STOPPING
17361                && state.mState != UserStartedState.STATE_SHUTDOWN;
17362    }
17363
17364    @Override
17365    public int[] getRunningUserIds() {
17366        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17367                != PackageManager.PERMISSION_GRANTED) {
17368            String msg = "Permission Denial: isUserRunning() from pid="
17369                    + Binder.getCallingPid()
17370                    + ", uid=" + Binder.getCallingUid()
17371                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17372            Slog.w(TAG, msg);
17373            throw new SecurityException(msg);
17374        }
17375        synchronized (this) {
17376            return mStartedUserArray;
17377        }
17378    }
17379
17380    private void updateStartedUserArrayLocked() {
17381        int num = 0;
17382        for (int i=0; i<mStartedUsers.size();  i++) {
17383            UserStartedState uss = mStartedUsers.valueAt(i);
17384            // This list does not include stopping users.
17385            if (uss.mState != UserStartedState.STATE_STOPPING
17386                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17387                num++;
17388            }
17389        }
17390        mStartedUserArray = new int[num];
17391        num = 0;
17392        for (int i=0; i<mStartedUsers.size();  i++) {
17393            UserStartedState uss = mStartedUsers.valueAt(i);
17394            if (uss.mState != UserStartedState.STATE_STOPPING
17395                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17396                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17397                num++;
17398            }
17399        }
17400    }
17401
17402    @Override
17403    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17404        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17405                != PackageManager.PERMISSION_GRANTED) {
17406            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17407                    + Binder.getCallingPid()
17408                    + ", uid=" + Binder.getCallingUid()
17409                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17410            Slog.w(TAG, msg);
17411            throw new SecurityException(msg);
17412        }
17413
17414        mUserSwitchObservers.register(observer);
17415    }
17416
17417    @Override
17418    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17419        mUserSwitchObservers.unregister(observer);
17420    }
17421
17422    private boolean userExists(int userId) {
17423        if (userId == 0) {
17424            return true;
17425        }
17426        UserManagerService ums = getUserManagerLocked();
17427        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17428    }
17429
17430    int[] getUsersLocked() {
17431        UserManagerService ums = getUserManagerLocked();
17432        return ums != null ? ums.getUserIds() : new int[] { 0 };
17433    }
17434
17435    UserManagerService getUserManagerLocked() {
17436        if (mUserManager == null) {
17437            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17438            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17439        }
17440        return mUserManager;
17441    }
17442
17443    private int applyUserId(int uid, int userId) {
17444        return UserHandle.getUid(userId, uid);
17445    }
17446
17447    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17448        if (info == null) return null;
17449        ApplicationInfo newInfo = new ApplicationInfo(info);
17450        newInfo.uid = applyUserId(info.uid, userId);
17451        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17452                + info.packageName;
17453        return newInfo;
17454    }
17455
17456    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17457        if (aInfo == null
17458                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17459            return aInfo;
17460        }
17461
17462        ActivityInfo info = new ActivityInfo(aInfo);
17463        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17464        return info;
17465    }
17466
17467    private final class LocalService extends ActivityManagerInternal {
17468        @Override
17469        public void goingToSleep() {
17470            ActivityManagerService.this.goingToSleep();
17471        }
17472
17473        @Override
17474        public void wakingUp() {
17475            ActivityManagerService.this.wakingUp();
17476        }
17477    }
17478
17479    /**
17480     * An implementation of IAppTask, that allows an app to manage its own tasks via
17481     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17482     * only the process that calls getAppTasks() can call the AppTask methods.
17483     */
17484    class AppTaskImpl extends IAppTask.Stub {
17485        private int mTaskId;
17486        private int mCallingUid;
17487
17488        public AppTaskImpl(int taskId, int callingUid) {
17489            mTaskId = taskId;
17490            mCallingUid = callingUid;
17491        }
17492
17493        @Override
17494        public void finishAndRemoveTask() {
17495            // Ensure that we are called from the same process that created this AppTask
17496            if (mCallingUid != Binder.getCallingUid()) {
17497                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17498                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17499                return;
17500            }
17501
17502            synchronized (ActivityManagerService.this) {
17503                long origId = Binder.clearCallingIdentity();
17504                try {
17505                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17506                    if (tr != null) {
17507                        // Only kill the process if we are not a new document
17508                        int flags = tr.getBaseIntent().getFlags();
17509                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17510                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17511                        removeTaskByIdLocked(mTaskId,
17512                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17513                    }
17514                } finally {
17515                    Binder.restoreCallingIdentity(origId);
17516                }
17517            }
17518        }
17519
17520        @Override
17521        public ActivityManager.RecentTaskInfo getTaskInfo() {
17522            // Ensure that we are called from the same process that created this AppTask
17523            if (mCallingUid != Binder.getCallingUid()) {
17524                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17525                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17526                return null;
17527            }
17528
17529            synchronized (ActivityManagerService.this) {
17530                long origId = Binder.clearCallingIdentity();
17531                try {
17532                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17533                    if (tr != null) {
17534                        return createRecentTaskInfoFromTaskRecord(tr);
17535                    }
17536                } finally {
17537                    Binder.restoreCallingIdentity(origId);
17538                }
17539                return null;
17540            }
17541        }
17542    }
17543}
17544