ActivityManagerService.java revision 99b9030a3ececd9b88e5011c98be0a5b9499c776
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;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
30import static com.android.server.am.ActivityManagerDebugConfig.*;
31import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
32import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
33import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
34import static org.xmlpull.v1.XmlPullParser.START_TAG;
35
36import android.Manifest;
37import android.app.AppOpsManager;
38import android.app.ApplicationThreadNative;
39import android.app.IActivityContainer;
40import android.app.IActivityContainerCallback;
41import android.app.IAppTask;
42import android.app.ITaskStackListener;
43import android.app.ProfilerInfo;
44import android.app.usage.UsageEvents;
45import android.app.usage.UsageStats;
46import android.app.usage.UsageStatsManagerInternal;
47import android.appwidget.AppWidgetManager;
48import android.content.res.Resources;
49import android.graphics.Bitmap;
50import android.graphics.Point;
51import android.graphics.Rect;
52import android.os.BatteryStats;
53import android.os.PersistableBundle;
54import android.os.PowerManager;
55import android.os.TransactionTooLargeException;
56import android.os.WorkSource;
57import android.os.storage.IMountService;
58import android.os.storage.StorageManager;
59import android.service.voice.IVoiceInteractionSession;
60import android.util.ArrayMap;
61import android.util.ArraySet;
62import android.util.DebugUtils;
63import android.util.SparseIntArray;
64import android.view.Display;
65
66import com.android.internal.R;
67import com.android.internal.annotations.GuardedBy;
68import com.android.internal.app.DumpHeapActivity;
69import com.android.internal.app.IAppOpsService;
70import com.android.internal.app.IVoiceInteractor;
71import com.android.internal.app.ProcessMap;
72import com.android.internal.app.ProcessStats;
73import com.android.internal.os.BackgroundThread;
74import com.android.internal.os.BatteryStatsImpl;
75import com.android.internal.os.IResultReceiver;
76import com.android.internal.os.ProcessCpuTracker;
77import com.android.internal.os.TransferPipe;
78import com.android.internal.os.Zygote;
79import com.android.internal.util.ArrayUtils;
80import com.android.internal.util.FastPrintWriter;
81import com.android.internal.util.FastXmlSerializer;
82import com.android.internal.util.MemInfoReader;
83import com.android.internal.util.Preconditions;
84import com.android.server.AppOpsService;
85import com.android.server.AttributeCache;
86import com.android.server.IntentResolver;
87import com.android.server.LocalServices;
88import com.android.server.ServiceThread;
89import com.android.server.SystemService;
90import com.android.server.SystemServiceManager;
91import com.android.server.Watchdog;
92import com.android.server.am.ActivityStack.ActivityState;
93import com.android.server.firewall.IntentFirewall;
94import com.android.server.pm.Installer;
95import com.android.server.pm.UserManagerService;
96import com.android.server.statusbar.StatusBarManagerInternal;
97import com.android.server.wm.AppTransition;
98import com.android.server.wm.WindowManagerService;
99import com.google.android.collect.Lists;
100import com.google.android.collect.Maps;
101
102import libcore.io.IoUtils;
103
104import org.xmlpull.v1.XmlPullParser;
105import org.xmlpull.v1.XmlPullParserException;
106import org.xmlpull.v1.XmlSerializer;
107
108import android.app.Activity;
109import android.app.ActivityManager;
110import android.app.ActivityManager.RunningTaskInfo;
111import android.app.ActivityManager.StackInfo;
112import android.app.ActivityManagerInternal;
113import android.app.ActivityManagerNative;
114import android.app.ActivityOptions;
115import android.app.ActivityThread;
116import android.app.AlertDialog;
117import android.app.AppGlobals;
118import android.app.ApplicationErrorReport;
119import android.app.Dialog;
120import android.app.IActivityController;
121import android.app.IApplicationThread;
122import android.app.IInstrumentationWatcher;
123import android.app.INotificationManager;
124import android.app.IProcessObserver;
125import android.app.IServiceConnection;
126import android.app.IStopUserCallback;
127import android.app.IUiAutomationConnection;
128import android.app.IUserSwitchObserver;
129import android.app.Instrumentation;
130import android.app.Notification;
131import android.app.NotificationManager;
132import android.app.PendingIntent;
133import android.app.backup.IBackupManager;
134import android.content.ActivityNotFoundException;
135import android.content.BroadcastReceiver;
136import android.content.ClipData;
137import android.content.ComponentCallbacks2;
138import android.content.ComponentName;
139import android.content.ContentProvider;
140import android.content.ContentResolver;
141import android.content.Context;
142import android.content.DialogInterface;
143import android.content.IContentProvider;
144import android.content.IIntentReceiver;
145import android.content.IIntentSender;
146import android.content.Intent;
147import android.content.IntentFilter;
148import android.content.IntentSender;
149import android.content.pm.ActivityInfo;
150import android.content.pm.ApplicationInfo;
151import android.content.pm.ConfigurationInfo;
152import android.content.pm.IPackageDataObserver;
153import android.content.pm.IPackageManager;
154import android.content.pm.InstrumentationInfo;
155import android.content.pm.PackageInfo;
156import android.content.pm.PackageManager;
157import android.content.pm.ParceledListSlice;
158import android.content.pm.UserInfo;
159import android.content.pm.PackageManager.NameNotFoundException;
160import android.content.pm.PathPermission;
161import android.content.pm.ProviderInfo;
162import android.content.pm.ResolveInfo;
163import android.content.pm.ServiceInfo;
164import android.content.res.CompatibilityInfo;
165import android.content.res.Configuration;
166import android.net.Proxy;
167import android.net.ProxyInfo;
168import android.net.Uri;
169import android.os.Binder;
170import android.os.Build;
171import android.os.Bundle;
172import android.os.Debug;
173import android.os.DropBoxManager;
174import android.os.Environment;
175import android.os.FactoryTest;
176import android.os.FileObserver;
177import android.os.FileUtils;
178import android.os.Handler;
179import android.os.IBinder;
180import android.os.IPermissionController;
181import android.os.IProcessInfoService;
182import android.os.IRemoteCallback;
183import android.os.IUserManager;
184import android.os.Looper;
185import android.os.Message;
186import android.os.Parcel;
187import android.os.ParcelFileDescriptor;
188import android.os.PowerManagerInternal;
189import android.os.Process;
190import android.os.RemoteCallbackList;
191import android.os.RemoteException;
192import android.os.SELinux;
193import android.os.ServiceManager;
194import android.os.StrictMode;
195import android.os.SystemClock;
196import android.os.SystemProperties;
197import android.os.UpdateLock;
198import android.os.UserHandle;
199import android.os.UserManager;
200import android.provider.Settings;
201import android.text.format.DateUtils;
202import android.text.format.Time;
203import android.util.AtomicFile;
204import android.util.EventLog;
205import android.util.Log;
206import android.util.Pair;
207import android.util.PrintWriterPrinter;
208import android.util.Slog;
209import android.util.SparseArray;
210import android.util.TimeUtils;
211import android.util.Xml;
212import android.view.Gravity;
213import android.view.LayoutInflater;
214import android.view.View;
215import android.view.WindowManager;
216
217import dalvik.system.VMRuntime;
218
219import java.io.BufferedInputStream;
220import java.io.BufferedOutputStream;
221import java.io.DataInputStream;
222import java.io.DataOutputStream;
223import java.io.File;
224import java.io.FileDescriptor;
225import java.io.FileInputStream;
226import java.io.FileNotFoundException;
227import java.io.FileOutputStream;
228import java.io.IOException;
229import java.io.InputStreamReader;
230import java.io.PrintWriter;
231import java.io.StringWriter;
232import java.lang.ref.WeakReference;
233import java.util.ArrayList;
234import java.util.Arrays;
235import java.util.Collections;
236import java.util.Comparator;
237import java.util.HashMap;
238import java.util.HashSet;
239import java.util.Iterator;
240import java.util.List;
241import java.util.Locale;
242import java.util.Map;
243import java.util.Set;
244import java.util.concurrent.atomic.AtomicBoolean;
245import java.util.concurrent.atomic.AtomicLong;
246
247public final class ActivityManagerService extends ActivityManagerNative
248        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
249
250    private static final String USER_DATA_DIR = "/data/user/";
251    // File that stores last updated system version and called preboot receivers
252    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
253
254    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
255    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
256    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
257    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
258    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
259    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
260    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
261    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
262    private static final String TAG_LRU = TAG + POSTFIX_LRU;
263    private static final String TAG_MU = TAG + POSTFIX_MU;
264    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
265    private static final String TAG_POWER = TAG + POSTFIX_POWER;
266    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
267    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
268    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
269    private static final String TAG_PSS = TAG + POSTFIX_PSS;
270    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
271    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
272    private static final String TAG_STACK = TAG + POSTFIX_STACK;
273    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
274    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
275    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
276
277    /** Control over CPU and battery monitoring */
278    // write battery stats every 30 minutes.
279    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
280    static final boolean MONITOR_CPU_USAGE = true;
281    // don't sample cpu less than every 5 seconds.
282    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
283    // wait possibly forever for next cpu sample.
284    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
285    static final boolean MONITOR_THREAD_CPU_USAGE = false;
286
287    // The flags that are set for all calls we make to the package manager.
288    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
289
290    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
291
292    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
293
294    // Amount of time after a call to stopAppSwitches() during which we will
295    // prevent further untrusted switches from happening.
296    static final long APP_SWITCH_DELAY_TIME = 5*1000;
297
298    // How long we wait for a launched process to attach to the activity manager
299    // before we decide it's never going to come up for real.
300    static final int PROC_START_TIMEOUT = 10*1000;
301
302    // How long we wait for a launched process to attach to the activity manager
303    // before we decide it's never going to come up for real, when the process was
304    // started with a wrapper for instrumentation (such as Valgrind) because it
305    // could take much longer than usual.
306    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
307
308    // How long to wait after going idle before forcing apps to GC.
309    static final int GC_TIMEOUT = 5*1000;
310
311    // The minimum amount of time between successive GC requests for a process.
312    static final int GC_MIN_INTERVAL = 60*1000;
313
314    // The minimum amount of time between successive PSS requests for a process.
315    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
316
317    // The minimum amount of time between successive PSS requests for a process
318    // when the request is due to the memory state being lowered.
319    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
320
321    // The rate at which we check for apps using excessive power -- 15 mins.
322    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
323
324    // The minimum sample duration we will allow before deciding we have
325    // enough data on wake locks to start killing things.
326    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
327
328    // The minimum sample duration we will allow before deciding we have
329    // enough data on CPU usage to start killing things.
330    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
331
332    // How long we allow a receiver to run before giving up on it.
333    static final int BROADCAST_FG_TIMEOUT = 10*1000;
334    static final int BROADCAST_BG_TIMEOUT = 60*1000;
335
336    // How long we wait until we timeout on key dispatching.
337    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
338
339    // How long we wait until we timeout on key dispatching during instrumentation.
340    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
341
342    // Amount of time we wait for observers to handle a user switch before
343    // giving up on them and unfreezing the screen.
344    static final int USER_SWITCH_TIMEOUT = 2*1000;
345
346    // Maximum number of users we allow to be running at a time.
347    static final int MAX_RUNNING_USERS = 3;
348
349    // How long to wait in getAssistContextExtras for the activity and foreground services
350    // to respond with the result.
351    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
352
353    // Maximum number of persisted Uri grants a package is allowed
354    static final int MAX_PERSISTED_URI_GRANTS = 128;
355
356    static final int MY_PID = Process.myPid();
357
358    static final String[] EMPTY_STRING_ARRAY = new String[0];
359
360    // How many bytes to write into the dropbox log before truncating
361    static final int DROPBOX_MAX_SIZE = 256 * 1024;
362
363    // Access modes for handleIncomingUser.
364    static final int ALLOW_NON_FULL = 0;
365    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
366    static final int ALLOW_FULL_ONLY = 2;
367
368    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
369
370    // Delay in notifying task stack change listeners (in millis)
371    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
372
373    /** All system services */
374    SystemServiceManager mSystemServiceManager;
375
376    private Installer mInstaller;
377
378    /** Run all ActivityStacks through this */
379    ActivityStackSupervisor mStackSupervisor;
380
381    /** Task stack change listeners. */
382    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
383            new RemoteCallbackList<ITaskStackListener>();
384
385    public IntentFirewall mIntentFirewall;
386
387    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
388    // default actuion automatically.  Important for devices without direct input
389    // devices.
390    private boolean mShowDialogs = true;
391
392    BroadcastQueue mFgBroadcastQueue;
393    BroadcastQueue mBgBroadcastQueue;
394    // Convenient for easy iteration over the queues. Foreground is first
395    // so that dispatch of foreground broadcasts gets precedence.
396    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
397
398    BroadcastQueue broadcastQueueForIntent(Intent intent) {
399        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
400        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
401                "Broadcast intent " + intent + " on "
402                + (isFg ? "foreground" : "background") + " queue");
403        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
404    }
405
406    /**
407     * Activity we have told the window manager to have key focus.
408     */
409    ActivityRecord mFocusedActivity = null;
410
411    /**
412     * List of intents that were used to start the most recent tasks.
413     */
414    private final RecentTasks mRecentTasks;
415
416    /**
417     * For addAppTask: cached of the last activity component that was added.
418     */
419    ComponentName mLastAddedTaskComponent;
420
421    /**
422     * For addAppTask: cached of the last activity uid that was added.
423     */
424    int mLastAddedTaskUid;
425
426    /**
427     * For addAppTask: cached of the last ActivityInfo that was added.
428     */
429    ActivityInfo mLastAddedTaskActivity;
430
431    /**
432     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
433     */
434    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
435
436    public class PendingAssistExtras extends Binder implements Runnable {
437        public final ActivityRecord activity;
438        public final Bundle extras;
439        public final Intent intent;
440        public final String hint;
441        public final IResultReceiver receiver;
442        public final int userHandle;
443        public boolean haveResult = false;
444        public Bundle result = null;
445        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
446                String _hint, IResultReceiver _receiver, int _userHandle) {
447            activity = _activity;
448            extras = _extras;
449            intent = _intent;
450            hint = _hint;
451            receiver = _receiver;
452            userHandle = _userHandle;
453        }
454        @Override
455        public void run() {
456            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
457            synchronized (ActivityManagerService.this) {
458                synchronized (this) {
459                    haveResult = true;
460                    notifyAll();
461                }
462                pendingAssistExtrasTimedOutLocked(this);
463            }
464        }
465    }
466
467    final ArrayList<PendingAssistExtras> mPendingAssistExtras
468            = new ArrayList<PendingAssistExtras>();
469
470    /**
471     * Process management.
472     */
473    final ProcessList mProcessList = new ProcessList();
474
475    /**
476     * All of the applications we currently have running organized by name.
477     * The keys are strings of the application package name (as
478     * returned by the package manager), and the keys are ApplicationRecord
479     * objects.
480     */
481    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
482
483    /**
484     * Tracking long-term execution of processes to look for abuse and other
485     * bad app behavior.
486     */
487    final ProcessStatsService mProcessStats;
488
489    /**
490     * The currently running isolated processes.
491     */
492    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
493
494    /**
495     * Counter for assigning isolated process uids, to avoid frequently reusing the
496     * same ones.
497     */
498    int mNextIsolatedProcessUid = 0;
499
500    /**
501     * The currently running heavy-weight process, if any.
502     */
503    ProcessRecord mHeavyWeightProcess = null;
504
505    /**
506     * The last time that various processes have crashed.
507     */
508    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
509
510    /**
511     * Information about a process that is currently marked as bad.
512     */
513    static final class BadProcessInfo {
514        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
515            this.time = time;
516            this.shortMsg = shortMsg;
517            this.longMsg = longMsg;
518            this.stack = stack;
519        }
520
521        final long time;
522        final String shortMsg;
523        final String longMsg;
524        final String stack;
525    }
526
527    /**
528     * Set of applications that we consider to be bad, and will reject
529     * incoming broadcasts from (which the user has no control over).
530     * Processes are added to this set when they have crashed twice within
531     * a minimum amount of time; they are removed from it when they are
532     * later restarted (hopefully due to some user action).  The value is the
533     * time it was added to the list.
534     */
535    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
536
537    /**
538     * All of the processes we currently have running organized by pid.
539     * The keys are the pid running the application.
540     *
541     * <p>NOTE: This object is protected by its own lock, NOT the global
542     * activity manager lock!
543     */
544    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
545
546    /**
547     * All of the processes that have been forced to be foreground.  The key
548     * is the pid of the caller who requested it (we hold a death
549     * link on it).
550     */
551    abstract class ForegroundToken implements IBinder.DeathRecipient {
552        int pid;
553        IBinder token;
554    }
555    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
556
557    /**
558     * List of records for processes that someone had tried to start before the
559     * system was ready.  We don't start them at that point, but ensure they
560     * are started by the time booting is complete.
561     */
562    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
563
564    /**
565     * List of persistent applications that are in the process
566     * of being started.
567     */
568    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
569
570    /**
571     * Processes that are being forcibly torn down.
572     */
573    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
574
575    /**
576     * List of running applications, sorted by recent usage.
577     * The first entry in the list is the least recently used.
578     */
579    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
580
581    /**
582     * Where in mLruProcesses that the processes hosting activities start.
583     */
584    int mLruProcessActivityStart = 0;
585
586    /**
587     * Where in mLruProcesses that the processes hosting services start.
588     * This is after (lower index) than mLruProcessesActivityStart.
589     */
590    int mLruProcessServiceStart = 0;
591
592    /**
593     * List of processes that should gc as soon as things are idle.
594     */
595    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
596
597    /**
598     * Processes we want to collect PSS data from.
599     */
600    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
601
602    /**
603     * Last time we requested PSS data of all processes.
604     */
605    long mLastFullPssTime = SystemClock.uptimeMillis();
606
607    /**
608     * If set, the next time we collect PSS data we should do a full collection
609     * with data from native processes and the kernel.
610     */
611    boolean mFullPssPending = false;
612
613    /**
614     * This is the process holding what we currently consider to be
615     * the "home" activity.
616     */
617    ProcessRecord mHomeProcess;
618
619    /**
620     * This is the process holding the activity the user last visited that
621     * is in a different process from the one they are currently in.
622     */
623    ProcessRecord mPreviousProcess;
624
625    /**
626     * The time at which the previous process was last visible.
627     */
628    long mPreviousProcessVisibleTime;
629
630    /**
631     * Which uses have been started, so are allowed to run code.
632     */
633    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
634
635    /**
636     * LRU list of history of current users.  Most recently current is at the end.
637     */
638    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
639
640    /**
641     * Constant array of the users that are currently started.
642     */
643    int[] mStartedUserArray = new int[] { 0 };
644
645    /**
646     * Registered observers of the user switching mechanics.
647     */
648    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
649            = new RemoteCallbackList<IUserSwitchObserver>();
650
651    /**
652     * Currently active user switch.
653     */
654    Object mCurUserSwitchCallback;
655
656    /**
657     * Packages that the user has asked to have run in screen size
658     * compatibility mode instead of filling the screen.
659     */
660    final CompatModePackages mCompatModePackages;
661
662    /**
663     * Set of IntentSenderRecord objects that are currently active.
664     */
665    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
666            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
667
668    /**
669     * Fingerprints (hashCode()) of stack traces that we've
670     * already logged DropBox entries for.  Guarded by itself.  If
671     * something (rogue user app) forces this over
672     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
673     */
674    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
675    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
676
677    /**
678     * Strict Mode background batched logging state.
679     *
680     * The string buffer is guarded by itself, and its lock is also
681     * used to determine if another batched write is already
682     * in-flight.
683     */
684    private final StringBuilder mStrictModeBuffer = new StringBuilder();
685
686    /**
687     * Keeps track of all IIntentReceivers that have been registered for
688     * broadcasts.  Hash keys are the receiver IBinder, hash value is
689     * a ReceiverList.
690     */
691    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
692            new HashMap<IBinder, ReceiverList>();
693
694    /**
695     * Resolver for broadcast intents to registered receivers.
696     * Holds BroadcastFilter (subclass of IntentFilter).
697     */
698    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
699            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
700        @Override
701        protected boolean allowFilterResult(
702                BroadcastFilter filter, List<BroadcastFilter> dest) {
703            IBinder target = filter.receiverList.receiver.asBinder();
704            for (int i=dest.size()-1; i>=0; i--) {
705                if (dest.get(i).receiverList.receiver.asBinder() == target) {
706                    return false;
707                }
708            }
709            return true;
710        }
711
712        @Override
713        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
714            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
715                    || userId == filter.owningUserId) {
716                return super.newResult(filter, match, userId);
717            }
718            return null;
719        }
720
721        @Override
722        protected BroadcastFilter[] newArray(int size) {
723            return new BroadcastFilter[size];
724        }
725
726        @Override
727        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
728            return packageName.equals(filter.packageName);
729        }
730    };
731
732    /**
733     * State of all active sticky broadcasts per user.  Keys are the action of the
734     * sticky Intent, values are an ArrayList of all broadcasted intents with
735     * that action (which should usually be one).  The SparseArray is keyed
736     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
737     * for stickies that are sent to all users.
738     */
739    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
740            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
741
742    final ActiveServices mServices;
743
744    final static class Association {
745        final int mSourceUid;
746        final String mSourceProcess;
747        final int mTargetUid;
748        final ComponentName mTargetComponent;
749        final String mTargetProcess;
750
751        int mCount;
752        long mTime;
753
754        int mNesting;
755        long mStartTime;
756
757        Association(int sourceUid, String sourceProcess, int targetUid,
758                ComponentName targetComponent, String targetProcess) {
759            mSourceUid = sourceUid;
760            mSourceProcess = sourceProcess;
761            mTargetUid = targetUid;
762            mTargetComponent = targetComponent;
763            mTargetProcess = targetProcess;
764        }
765    }
766
767    /**
768     * When service association tracking is enabled, this is all of the associations we
769     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
770     * -> association data.
771     */
772    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
773            mAssociations = new SparseArray<>();
774    boolean mTrackingAssociations;
775
776    /**
777     * Backup/restore process management
778     */
779    String mBackupAppName = null;
780    BackupRecord mBackupTarget = null;
781
782    final ProviderMap mProviderMap;
783
784    /**
785     * List of content providers who have clients waiting for them.  The
786     * application is currently being launched and the provider will be
787     * removed from this list once it is published.
788     */
789    final ArrayList<ContentProviderRecord> mLaunchingProviders
790            = new ArrayList<ContentProviderRecord>();
791
792    /**
793     * File storing persisted {@link #mGrantedUriPermissions}.
794     */
795    private final AtomicFile mGrantFile;
796
797    /** XML constants used in {@link #mGrantFile} */
798    private static final String TAG_URI_GRANTS = "uri-grants";
799    private static final String TAG_URI_GRANT = "uri-grant";
800    private static final String ATTR_USER_HANDLE = "userHandle";
801    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
802    private static final String ATTR_TARGET_USER_ID = "targetUserId";
803    private static final String ATTR_SOURCE_PKG = "sourcePkg";
804    private static final String ATTR_TARGET_PKG = "targetPkg";
805    private static final String ATTR_URI = "uri";
806    private static final String ATTR_MODE_FLAGS = "modeFlags";
807    private static final String ATTR_CREATED_TIME = "createdTime";
808    private static final String ATTR_PREFIX = "prefix";
809
810    /**
811     * Global set of specific {@link Uri} permissions that have been granted.
812     * This optimized lookup structure maps from {@link UriPermission#targetUid}
813     * to {@link UriPermission#uri} to {@link UriPermission}.
814     */
815    @GuardedBy("this")
816    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
817            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
818
819    public static class GrantUri {
820        public final int sourceUserId;
821        public final Uri uri;
822        public boolean prefix;
823
824        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
825            this.sourceUserId = sourceUserId;
826            this.uri = uri;
827            this.prefix = prefix;
828        }
829
830        @Override
831        public int hashCode() {
832            int hashCode = 1;
833            hashCode = 31 * hashCode + sourceUserId;
834            hashCode = 31 * hashCode + uri.hashCode();
835            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
836            return hashCode;
837        }
838
839        @Override
840        public boolean equals(Object o) {
841            if (o instanceof GrantUri) {
842                GrantUri other = (GrantUri) o;
843                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
844                        && prefix == other.prefix;
845            }
846            return false;
847        }
848
849        @Override
850        public String toString() {
851            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
852            if (prefix) result += " [prefix]";
853            return result;
854        }
855
856        public String toSafeString() {
857            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
858            if (prefix) result += " [prefix]";
859            return result;
860        }
861
862        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
863            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
864                    ContentProvider.getUriWithoutUserId(uri), false);
865        }
866    }
867
868    CoreSettingsObserver mCoreSettingsObserver;
869
870    /**
871     * Thread-local storage used to carry caller permissions over through
872     * indirect content-provider access.
873     */
874    private class Identity {
875        public final IBinder token;
876        public final int pid;
877        public final int uid;
878
879        Identity(IBinder _token, int _pid, int _uid) {
880            token = _token;
881            pid = _pid;
882            uid = _uid;
883        }
884    }
885
886    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
887
888    /**
889     * All information we have collected about the runtime performance of
890     * any user id that can impact battery performance.
891     */
892    final BatteryStatsService mBatteryStatsService;
893
894    /**
895     * Information about component usage
896     */
897    UsageStatsManagerInternal mUsageStatsService;
898
899    /**
900     * Information about and control over application operations
901     */
902    final AppOpsService mAppOpsService;
903
904    /**
905     * Save recent tasks information across reboots.
906     */
907    final TaskPersister mTaskPersister;
908
909    /**
910     * Current configuration information.  HistoryRecord objects are given
911     * a reference to this object to indicate which configuration they are
912     * currently running in, so this object must be kept immutable.
913     */
914    Configuration mConfiguration = new Configuration();
915
916    /**
917     * Current sequencing integer of the configuration, for skipping old
918     * configurations.
919     */
920    int mConfigurationSeq = 0;
921
922    /**
923     * Hardware-reported OpenGLES version.
924     */
925    final int GL_ES_VERSION;
926
927    /**
928     * List of initialization arguments to pass to all processes when binding applications to them.
929     * For example, references to the commonly used services.
930     */
931    HashMap<String, IBinder> mAppBindArgs;
932
933    /**
934     * Temporary to avoid allocations.  Protected by main lock.
935     */
936    final StringBuilder mStringBuilder = new StringBuilder(256);
937
938    /**
939     * Used to control how we initialize the service.
940     */
941    ComponentName mTopComponent;
942    String mTopAction = Intent.ACTION_MAIN;
943    String mTopData;
944    boolean mProcessesReady = false;
945    boolean mSystemReady = false;
946    boolean mBooting = false;
947    boolean mCallFinishBooting = false;
948    boolean mBootAnimationComplete = false;
949    boolean mWaitingUpdate = false;
950    boolean mDidUpdate = false;
951    boolean mOnBattery = false;
952    boolean mLaunchWarningShown = false;
953
954    Context mContext;
955
956    int mFactoryTest;
957
958    boolean mCheckedForSetup;
959
960    /**
961     * The time at which we will allow normal application switches again,
962     * after a call to {@link #stopAppSwitches()}.
963     */
964    long mAppSwitchesAllowedTime;
965
966    /**
967     * This is set to true after the first switch after mAppSwitchesAllowedTime
968     * is set; any switches after that will clear the time.
969     */
970    boolean mDidAppSwitch;
971
972    /**
973     * Last time (in realtime) at which we checked for power usage.
974     */
975    long mLastPowerCheckRealtime;
976
977    /**
978     * Last time (in uptime) at which we checked for power usage.
979     */
980    long mLastPowerCheckUptime;
981
982    /**
983     * Set while we are wanting to sleep, to prevent any
984     * activities from being started/resumed.
985     */
986    private boolean mSleeping = false;
987
988    /**
989     * Set while we are running a voice interaction.  This overrides
990     * sleeping while it is active.
991     */
992    private IVoiceInteractionSession mRunningVoice;
993
994    /**
995     * We want to hold a wake lock while running a voice interaction session, since
996     * this may happen with the screen off and we need to keep the CPU running to
997     * be able to continue to interact with the user.
998     */
999    PowerManager.WakeLock mVoiceWakeLock;
1000
1001    /**
1002     * State of external calls telling us if the device is awake or asleep.
1003     */
1004    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1005
1006    static final int LOCK_SCREEN_HIDDEN = 0;
1007    static final int LOCK_SCREEN_LEAVING = 1;
1008    static final int LOCK_SCREEN_SHOWN = 2;
1009    /**
1010     * State of external call telling us if the lock screen is shown.
1011     */
1012    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1013
1014    /**
1015     * Set if we are shutting down the system, similar to sleeping.
1016     */
1017    boolean mShuttingDown = false;
1018
1019    /**
1020     * Current sequence id for oom_adj computation traversal.
1021     */
1022    int mAdjSeq = 0;
1023
1024    /**
1025     * Current sequence id for process LRU updating.
1026     */
1027    int mLruSeq = 0;
1028
1029    /**
1030     * Keep track of the non-cached/empty process we last found, to help
1031     * determine how to distribute cached/empty processes next time.
1032     */
1033    int mNumNonCachedProcs = 0;
1034
1035    /**
1036     * Keep track of the number of cached hidden procs, to balance oom adj
1037     * distribution between those and empty procs.
1038     */
1039    int mNumCachedHiddenProcs = 0;
1040
1041    /**
1042     * Keep track of the number of service processes we last found, to
1043     * determine on the next iteration which should be B services.
1044     */
1045    int mNumServiceProcs = 0;
1046    int mNewNumAServiceProcs = 0;
1047    int mNewNumServiceProcs = 0;
1048
1049    /**
1050     * Allow the current computed overall memory level of the system to go down?
1051     * This is set to false when we are killing processes for reasons other than
1052     * memory management, so that the now smaller process list will not be taken as
1053     * an indication that memory is tighter.
1054     */
1055    boolean mAllowLowerMemLevel = false;
1056
1057    /**
1058     * The last computed memory level, for holding when we are in a state that
1059     * processes are going away for other reasons.
1060     */
1061    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1062
1063    /**
1064     * The last total number of process we have, to determine if changes actually look
1065     * like a shrinking number of process due to lower RAM.
1066     */
1067    int mLastNumProcesses;
1068
1069    /**
1070     * The uptime of the last time we performed idle maintenance.
1071     */
1072    long mLastIdleTime = SystemClock.uptimeMillis();
1073
1074    /**
1075     * Total time spent with RAM that has been added in the past since the last idle time.
1076     */
1077    long mLowRamTimeSinceLastIdle = 0;
1078
1079    /**
1080     * If RAM is currently low, when that horrible situation started.
1081     */
1082    long mLowRamStartTime = 0;
1083
1084    /**
1085     * For reporting to battery stats the current top application.
1086     */
1087    private String mCurResumedPackage = null;
1088    private int mCurResumedUid = -1;
1089
1090    /**
1091     * For reporting to battery stats the apps currently running foreground
1092     * service.  The ProcessMap is package/uid tuples; each of these contain
1093     * an array of the currently foreground processes.
1094     */
1095    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1096            = new ProcessMap<ArrayList<ProcessRecord>>();
1097
1098    /**
1099     * This is set if we had to do a delayed dexopt of an app before launching
1100     * it, to increase the ANR timeouts in that case.
1101     */
1102    boolean mDidDexOpt;
1103
1104    /**
1105     * Set if the systemServer made a call to enterSafeMode.
1106     */
1107    boolean mSafeMode;
1108
1109    /**
1110     * If true, we are running under a test environment so will sample PSS from processes
1111     * much more rapidly to try to collect better data when the tests are rapidly
1112     * running through apps.
1113     */
1114    boolean mTestPssMode = false;
1115
1116    String mDebugApp = null;
1117    boolean mWaitForDebugger = false;
1118    boolean mDebugTransient = false;
1119    String mOrigDebugApp = null;
1120    boolean mOrigWaitForDebugger = false;
1121    boolean mAlwaysFinishActivities = false;
1122    IActivityController mController = null;
1123    String mProfileApp = null;
1124    ProcessRecord mProfileProc = null;
1125    String mProfileFile;
1126    ParcelFileDescriptor mProfileFd;
1127    int mSamplingInterval = 0;
1128    boolean mAutoStopProfiler = false;
1129    int mProfileType = 0;
1130    String mOpenGlTraceApp = null;
1131    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1132    String mMemWatchDumpProcName;
1133    String mMemWatchDumpFile;
1134    int mMemWatchDumpPid;
1135    int mMemWatchDumpUid;
1136
1137    final long[] mTmpLong = new long[1];
1138
1139    static class ProcessChangeItem {
1140        static final int CHANGE_ACTIVITIES = 1<<0;
1141        static final int CHANGE_PROCESS_STATE = 1<<1;
1142        int changes;
1143        int uid;
1144        int pid;
1145        int processState;
1146        boolean foregroundActivities;
1147    }
1148
1149    final RemoteCallbackList<IProcessObserver> mProcessObservers
1150            = new RemoteCallbackList<IProcessObserver>();
1151    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1152
1153    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1154            = new ArrayList<ProcessChangeItem>();
1155    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1156            = new ArrayList<ProcessChangeItem>();
1157
1158    /**
1159     * Runtime CPU use collection thread.  This object's lock is used to
1160     * perform synchronization with the thread (notifying it to run).
1161     */
1162    final Thread mProcessCpuThread;
1163
1164    /**
1165     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1166     * Must acquire this object's lock when accessing it.
1167     * NOTE: this lock will be held while doing long operations (trawling
1168     * through all processes in /proc), so it should never be acquired by
1169     * any critical paths such as when holding the main activity manager lock.
1170     */
1171    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1172            MONITOR_THREAD_CPU_USAGE);
1173    final AtomicLong mLastCpuTime = new AtomicLong(0);
1174    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1175
1176    long mLastWriteTime = 0;
1177
1178    /**
1179     * Used to retain an update lock when the foreground activity is in
1180     * immersive mode.
1181     */
1182    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1183
1184    /**
1185     * Set to true after the system has finished booting.
1186     */
1187    boolean mBooted = false;
1188
1189    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1190    int mProcessLimitOverride = -1;
1191
1192    WindowManagerService mWindowManager;
1193
1194    final ActivityThread mSystemThread;
1195
1196    // Holds the current foreground user's id
1197    int mCurrentUserId = 0;
1198    // Holds the target user's id during a user switch
1199    int mTargetUserId = UserHandle.USER_NULL;
1200    // If there are multiple profiles for the current user, their ids are here
1201    // Currently only the primary user can have managed profiles
1202    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1203
1204    /**
1205     * Mapping from each known user ID to the profile group ID it is associated with.
1206     */
1207    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1208
1209    private UserManagerService mUserManager;
1210
1211    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1212        final ProcessRecord mApp;
1213        final int mPid;
1214        final IApplicationThread mAppThread;
1215
1216        AppDeathRecipient(ProcessRecord app, int pid,
1217                IApplicationThread thread) {
1218            if (DEBUG_ALL) Slog.v(
1219                TAG, "New death recipient " + this
1220                + " for thread " + thread.asBinder());
1221            mApp = app;
1222            mPid = pid;
1223            mAppThread = thread;
1224        }
1225
1226        @Override
1227        public void binderDied() {
1228            if (DEBUG_ALL) Slog.v(
1229                TAG, "Death received in " + this
1230                + " for thread " + mAppThread.asBinder());
1231            synchronized(ActivityManagerService.this) {
1232                appDiedLocked(mApp, mPid, mAppThread, true);
1233            }
1234        }
1235    }
1236
1237    static final int SHOW_ERROR_MSG = 1;
1238    static final int SHOW_NOT_RESPONDING_MSG = 2;
1239    static final int SHOW_FACTORY_ERROR_MSG = 3;
1240    static final int UPDATE_CONFIGURATION_MSG = 4;
1241    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1242    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1243    static final int SERVICE_TIMEOUT_MSG = 12;
1244    static final int UPDATE_TIME_ZONE = 13;
1245    static final int SHOW_UID_ERROR_MSG = 14;
1246    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1247    static final int PROC_START_TIMEOUT_MSG = 20;
1248    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1249    static final int KILL_APPLICATION_MSG = 22;
1250    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1251    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1252    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1253    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1254    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1255    static final int CLEAR_DNS_CACHE_MSG = 28;
1256    static final int UPDATE_HTTP_PROXY_MSG = 29;
1257    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1258    static final int DISPATCH_PROCESSES_CHANGED = 31;
1259    static final int DISPATCH_PROCESS_DIED = 32;
1260    static final int REPORT_MEM_USAGE_MSG = 33;
1261    static final int REPORT_USER_SWITCH_MSG = 34;
1262    static final int CONTINUE_USER_SWITCH_MSG = 35;
1263    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1264    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1265    static final int PERSIST_URI_GRANTS_MSG = 38;
1266    static final int REQUEST_ALL_PSS_MSG = 39;
1267    static final int START_PROFILES_MSG = 40;
1268    static final int UPDATE_TIME = 41;
1269    static final int SYSTEM_USER_START_MSG = 42;
1270    static final int SYSTEM_USER_CURRENT_MSG = 43;
1271    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1272    static final int FINISH_BOOTING_MSG = 45;
1273    static final int START_USER_SWITCH_MSG = 46;
1274    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1275    static final int DISMISS_DIALOG_MSG = 48;
1276    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1277    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1278    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1279    static final int DELETE_DUMPHEAP_MSG = 52;
1280    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1281
1282    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1283    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1284    static final int FIRST_COMPAT_MODE_MSG = 300;
1285    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1286
1287    CompatModeDialog mCompatModeDialog;
1288    long mLastMemUsageReportTime = 0;
1289
1290    /**
1291     * Flag whether the current user is a "monkey", i.e. whether
1292     * the UI is driven by a UI automation tool.
1293     */
1294    private boolean mUserIsMonkey;
1295
1296    /** Flag whether the device has a Recents UI */
1297    boolean mHasRecents;
1298
1299    /** The dimensions of the thumbnails in the Recents UI. */
1300    int mThumbnailWidth;
1301    int mThumbnailHeight;
1302
1303    final ServiceThread mHandlerThread;
1304    final MainHandler mHandler;
1305
1306    final class MainHandler extends Handler {
1307        public MainHandler(Looper looper) {
1308            super(looper, null, true);
1309        }
1310
1311        @Override
1312        public void handleMessage(Message msg) {
1313            switch (msg.what) {
1314            case SHOW_ERROR_MSG: {
1315                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1316                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1317                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1318                synchronized (ActivityManagerService.this) {
1319                    ProcessRecord proc = (ProcessRecord)data.get("app");
1320                    AppErrorResult res = (AppErrorResult) data.get("result");
1321                    if (proc != null && proc.crashDialog != null) {
1322                        Slog.e(TAG, "App already has crash dialog: " + proc);
1323                        if (res != null) {
1324                            res.set(0);
1325                        }
1326                        return;
1327                    }
1328                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1329                            >= Process.FIRST_APPLICATION_UID
1330                            && proc.pid != MY_PID);
1331                    for (int userId : mCurrentProfileIds) {
1332                        isBackground &= (proc.userId != userId);
1333                    }
1334                    if (isBackground && !showBackground) {
1335                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1336                        if (res != null) {
1337                            res.set(0);
1338                        }
1339                        return;
1340                    }
1341                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1342                        Dialog d = new AppErrorDialog(mContext,
1343                                ActivityManagerService.this, res, proc);
1344                        d.show();
1345                        proc.crashDialog = d;
1346                    } else {
1347                        // The device is asleep, so just pretend that the user
1348                        // saw a crash dialog and hit "force quit".
1349                        if (res != null) {
1350                            res.set(0);
1351                        }
1352                    }
1353                }
1354
1355                ensureBootCompleted();
1356            } break;
1357            case SHOW_NOT_RESPONDING_MSG: {
1358                synchronized (ActivityManagerService.this) {
1359                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1360                    ProcessRecord proc = (ProcessRecord)data.get("app");
1361                    if (proc != null && proc.anrDialog != null) {
1362                        Slog.e(TAG, "App already has anr dialog: " + proc);
1363                        return;
1364                    }
1365
1366                    Intent intent = new Intent("android.intent.action.ANR");
1367                    if (!mProcessesReady) {
1368                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1369                                | Intent.FLAG_RECEIVER_FOREGROUND);
1370                    }
1371                    broadcastIntentLocked(null, null, intent,
1372                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1373                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1374
1375                    if (mShowDialogs) {
1376                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1377                                mContext, proc, (ActivityRecord)data.get("activity"),
1378                                msg.arg1 != 0);
1379                        d.show();
1380                        proc.anrDialog = d;
1381                    } else {
1382                        // Just kill the app if there is no dialog to be shown.
1383                        killAppAtUsersRequest(proc, null);
1384                    }
1385                }
1386
1387                ensureBootCompleted();
1388            } break;
1389            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1390                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1391                synchronized (ActivityManagerService.this) {
1392                    ProcessRecord proc = (ProcessRecord) data.get("app");
1393                    if (proc == null) {
1394                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1395                        break;
1396                    }
1397                    if (proc.crashDialog != null) {
1398                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1399                        return;
1400                    }
1401                    AppErrorResult res = (AppErrorResult) data.get("result");
1402                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1403                        Dialog d = new StrictModeViolationDialog(mContext,
1404                                ActivityManagerService.this, res, proc);
1405                        d.show();
1406                        proc.crashDialog = d;
1407                    } else {
1408                        // The device is asleep, so just pretend that the user
1409                        // saw a crash dialog and hit "force quit".
1410                        res.set(0);
1411                    }
1412                }
1413                ensureBootCompleted();
1414            } break;
1415            case SHOW_FACTORY_ERROR_MSG: {
1416                Dialog d = new FactoryErrorDialog(
1417                    mContext, msg.getData().getCharSequence("msg"));
1418                d.show();
1419                ensureBootCompleted();
1420            } break;
1421            case UPDATE_CONFIGURATION_MSG: {
1422                final ContentResolver resolver = mContext.getContentResolver();
1423                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1424            } break;
1425            case GC_BACKGROUND_PROCESSES_MSG: {
1426                synchronized (ActivityManagerService.this) {
1427                    performAppGcsIfAppropriateLocked();
1428                }
1429            } break;
1430            case WAIT_FOR_DEBUGGER_MSG: {
1431                synchronized (ActivityManagerService.this) {
1432                    ProcessRecord app = (ProcessRecord)msg.obj;
1433                    if (msg.arg1 != 0) {
1434                        if (!app.waitedForDebugger) {
1435                            Dialog d = new AppWaitingForDebuggerDialog(
1436                                    ActivityManagerService.this,
1437                                    mContext, app);
1438                            app.waitDialog = d;
1439                            app.waitedForDebugger = true;
1440                            d.show();
1441                        }
1442                    } else {
1443                        if (app.waitDialog != null) {
1444                            app.waitDialog.dismiss();
1445                            app.waitDialog = null;
1446                        }
1447                    }
1448                }
1449            } break;
1450            case SERVICE_TIMEOUT_MSG: {
1451                if (mDidDexOpt) {
1452                    mDidDexOpt = false;
1453                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1454                    nmsg.obj = msg.obj;
1455                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1456                    return;
1457                }
1458                mServices.serviceTimeout((ProcessRecord)msg.obj);
1459            } break;
1460            case UPDATE_TIME_ZONE: {
1461                synchronized (ActivityManagerService.this) {
1462                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1463                        ProcessRecord r = mLruProcesses.get(i);
1464                        if (r.thread != null) {
1465                            try {
1466                                r.thread.updateTimeZone();
1467                            } catch (RemoteException ex) {
1468                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1469                            }
1470                        }
1471                    }
1472                }
1473            } break;
1474            case CLEAR_DNS_CACHE_MSG: {
1475                synchronized (ActivityManagerService.this) {
1476                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1477                        ProcessRecord r = mLruProcesses.get(i);
1478                        if (r.thread != null) {
1479                            try {
1480                                r.thread.clearDnsCache();
1481                            } catch (RemoteException ex) {
1482                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1483                            }
1484                        }
1485                    }
1486                }
1487            } break;
1488            case UPDATE_HTTP_PROXY_MSG: {
1489                ProxyInfo proxy = (ProxyInfo)msg.obj;
1490                String host = "";
1491                String port = "";
1492                String exclList = "";
1493                Uri pacFileUrl = Uri.EMPTY;
1494                if (proxy != null) {
1495                    host = proxy.getHost();
1496                    port = Integer.toString(proxy.getPort());
1497                    exclList = proxy.getExclusionListAsString();
1498                    pacFileUrl = proxy.getPacFileUrl();
1499                }
1500                synchronized (ActivityManagerService.this) {
1501                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1502                        ProcessRecord r = mLruProcesses.get(i);
1503                        if (r.thread != null) {
1504                            try {
1505                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1506                            } catch (RemoteException ex) {
1507                                Slog.w(TAG, "Failed to update http proxy for: " +
1508                                        r.info.processName);
1509                            }
1510                        }
1511                    }
1512                }
1513            } break;
1514            case SHOW_UID_ERROR_MSG: {
1515                if (mShowDialogs) {
1516                    AlertDialog d = new BaseErrorDialog(mContext);
1517                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1518                    d.setCancelable(false);
1519                    d.setTitle(mContext.getText(R.string.android_system_label));
1520                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1521                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1522                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1523                    d.show();
1524                }
1525            } break;
1526            case SHOW_FINGERPRINT_ERROR_MSG: {
1527                if (mShowDialogs) {
1528                    AlertDialog d = new BaseErrorDialog(mContext);
1529                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1530                    d.setCancelable(false);
1531                    d.setTitle(mContext.getText(R.string.android_system_label));
1532                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1533                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1534                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1535                    d.show();
1536                }
1537            } break;
1538            case PROC_START_TIMEOUT_MSG: {
1539                if (mDidDexOpt) {
1540                    mDidDexOpt = false;
1541                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1542                    nmsg.obj = msg.obj;
1543                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1544                    return;
1545                }
1546                ProcessRecord app = (ProcessRecord)msg.obj;
1547                synchronized (ActivityManagerService.this) {
1548                    processStartTimedOutLocked(app);
1549                }
1550            } break;
1551            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1552                synchronized (ActivityManagerService.this) {
1553                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1554                }
1555            } break;
1556            case KILL_APPLICATION_MSG: {
1557                synchronized (ActivityManagerService.this) {
1558                    int appid = msg.arg1;
1559                    boolean restart = (msg.arg2 == 1);
1560                    Bundle bundle = (Bundle)msg.obj;
1561                    String pkg = bundle.getString("pkg");
1562                    String reason = bundle.getString("reason");
1563                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1564                            false, UserHandle.USER_ALL, reason);
1565                }
1566            } break;
1567            case FINALIZE_PENDING_INTENT_MSG: {
1568                ((PendingIntentRecord)msg.obj).completeFinalize();
1569            } break;
1570            case POST_HEAVY_NOTIFICATION_MSG: {
1571                INotificationManager inm = NotificationManager.getService();
1572                if (inm == null) {
1573                    return;
1574                }
1575
1576                ActivityRecord root = (ActivityRecord)msg.obj;
1577                ProcessRecord process = root.app;
1578                if (process == null) {
1579                    return;
1580                }
1581
1582                try {
1583                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1584                    String text = mContext.getString(R.string.heavy_weight_notification,
1585                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1586                    Notification notification = new Notification();
1587                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1588                    notification.when = 0;
1589                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1590                    notification.tickerText = text;
1591                    notification.defaults = 0; // please be quiet
1592                    notification.sound = null;
1593                    notification.vibrate = null;
1594                    notification.color = mContext.getColor(
1595                            com.android.internal.R.color.system_notification_accent_color);
1596                    notification.setLatestEventInfo(context, text,
1597                            mContext.getText(R.string.heavy_weight_notification_detail),
1598                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1599                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1600                                    new UserHandle(root.userId)));
1601
1602                    try {
1603                        int[] outId = new int[1];
1604                        inm.enqueueNotificationWithTag("android", "android", null,
1605                                R.string.heavy_weight_notification,
1606                                notification, outId, root.userId);
1607                    } catch (RuntimeException e) {
1608                        Slog.w(ActivityManagerService.TAG,
1609                                "Error showing notification for heavy-weight app", e);
1610                    } catch (RemoteException e) {
1611                    }
1612                } catch (NameNotFoundException e) {
1613                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1614                }
1615            } break;
1616            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1617                INotificationManager inm = NotificationManager.getService();
1618                if (inm == null) {
1619                    return;
1620                }
1621                try {
1622                    inm.cancelNotificationWithTag("android", null,
1623                            R.string.heavy_weight_notification,  msg.arg1);
1624                } catch (RuntimeException e) {
1625                    Slog.w(ActivityManagerService.TAG,
1626                            "Error canceling notification for service", e);
1627                } catch (RemoteException e) {
1628                }
1629            } break;
1630            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1631                synchronized (ActivityManagerService.this) {
1632                    checkExcessivePowerUsageLocked(true);
1633                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1634                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1635                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1636                }
1637            } break;
1638            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1639                synchronized (ActivityManagerService.this) {
1640                    ActivityRecord ar = (ActivityRecord)msg.obj;
1641                    if (mCompatModeDialog != null) {
1642                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1643                                ar.info.applicationInfo.packageName)) {
1644                            return;
1645                        }
1646                        mCompatModeDialog.dismiss();
1647                        mCompatModeDialog = null;
1648                    }
1649                    if (ar != null && false) {
1650                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1651                                ar.packageName)) {
1652                            int mode = mCompatModePackages.computeCompatModeLocked(
1653                                    ar.info.applicationInfo);
1654                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1655                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1656                                mCompatModeDialog = new CompatModeDialog(
1657                                        ActivityManagerService.this, mContext,
1658                                        ar.info.applicationInfo);
1659                                mCompatModeDialog.show();
1660                            }
1661                        }
1662                    }
1663                }
1664                break;
1665            }
1666            case DISPATCH_PROCESSES_CHANGED: {
1667                dispatchProcessesChanged();
1668                break;
1669            }
1670            case DISPATCH_PROCESS_DIED: {
1671                final int pid = msg.arg1;
1672                final int uid = msg.arg2;
1673                dispatchProcessDied(pid, uid);
1674                break;
1675            }
1676            case REPORT_MEM_USAGE_MSG: {
1677                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1678                Thread thread = new Thread() {
1679                    @Override public void run() {
1680                        reportMemUsage(memInfos);
1681                    }
1682                };
1683                thread.start();
1684                break;
1685            }
1686            case START_USER_SWITCH_MSG: {
1687                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1688                break;
1689            }
1690            case REPORT_USER_SWITCH_MSG: {
1691                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1692                break;
1693            }
1694            case CONTINUE_USER_SWITCH_MSG: {
1695                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1696                break;
1697            }
1698            case USER_SWITCH_TIMEOUT_MSG: {
1699                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1700                break;
1701            }
1702            case IMMERSIVE_MODE_LOCK_MSG: {
1703                final boolean nextState = (msg.arg1 != 0);
1704                if (mUpdateLock.isHeld() != nextState) {
1705                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1706                            "Applying new update lock state '" + nextState
1707                            + "' for " + (ActivityRecord)msg.obj);
1708                    if (nextState) {
1709                        mUpdateLock.acquire();
1710                    } else {
1711                        mUpdateLock.release();
1712                    }
1713                }
1714                break;
1715            }
1716            case PERSIST_URI_GRANTS_MSG: {
1717                writeGrantedUriPermissions();
1718                break;
1719            }
1720            case REQUEST_ALL_PSS_MSG: {
1721                synchronized (ActivityManagerService.this) {
1722                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1723                }
1724                break;
1725            }
1726            case START_PROFILES_MSG: {
1727                synchronized (ActivityManagerService.this) {
1728                    startProfilesLocked();
1729                }
1730                break;
1731            }
1732            case UPDATE_TIME: {
1733                synchronized (ActivityManagerService.this) {
1734                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1735                        ProcessRecord r = mLruProcesses.get(i);
1736                        if (r.thread != null) {
1737                            try {
1738                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1739                            } catch (RemoteException ex) {
1740                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1741                            }
1742                        }
1743                    }
1744                }
1745                break;
1746            }
1747            case SYSTEM_USER_START_MSG: {
1748                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1749                        Integer.toString(msg.arg1), msg.arg1);
1750                mSystemServiceManager.startUser(msg.arg1);
1751                break;
1752            }
1753            case SYSTEM_USER_CURRENT_MSG: {
1754                mBatteryStatsService.noteEvent(
1755                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1756                        Integer.toString(msg.arg2), msg.arg2);
1757                mBatteryStatsService.noteEvent(
1758                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1759                        Integer.toString(msg.arg1), msg.arg1);
1760                mSystemServiceManager.switchUser(msg.arg1);
1761                break;
1762            }
1763            case ENTER_ANIMATION_COMPLETE_MSG: {
1764                synchronized (ActivityManagerService.this) {
1765                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1766                    if (r != null && r.app != null && r.app.thread != null) {
1767                        try {
1768                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1769                        } catch (RemoteException e) {
1770                        }
1771                    }
1772                }
1773                break;
1774            }
1775            case FINISH_BOOTING_MSG: {
1776                if (msg.arg1 != 0) {
1777                    finishBooting();
1778                }
1779                if (msg.arg2 != 0) {
1780                    enableScreenAfterBoot();
1781                }
1782                break;
1783            }
1784            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1785                try {
1786                    Locale l = (Locale) msg.obj;
1787                    IBinder service = ServiceManager.getService("mount");
1788                    IMountService mountService = IMountService.Stub.asInterface(service);
1789                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1790                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1791                } catch (RemoteException e) {
1792                    Log.e(TAG, "Error storing locale for decryption UI", e);
1793                }
1794                break;
1795            }
1796            case DISMISS_DIALOG_MSG: {
1797                final Dialog d = (Dialog) msg.obj;
1798                d.dismiss();
1799                break;
1800            }
1801            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1802                synchronized (ActivityManagerService.this) {
1803                    int i = mTaskStackListeners.beginBroadcast();
1804                    while (i > 0) {
1805                        i--;
1806                        try {
1807                            // Make a one-way callback to the listener
1808                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1809                        } catch (RemoteException e){
1810                            // Handled by the RemoteCallbackList
1811                        }
1812                    }
1813                    mTaskStackListeners.finishBroadcast();
1814                }
1815                break;
1816            }
1817            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1818                final int uid = msg.arg1;
1819                final byte[] firstPacket = (byte[]) msg.obj;
1820
1821                synchronized (mPidsSelfLocked) {
1822                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1823                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1824                        if (p.uid == uid) {
1825                            try {
1826                                p.thread.notifyCleartextNetwork(firstPacket);
1827                            } catch (RemoteException ignored) {
1828                            }
1829                        }
1830                    }
1831                }
1832                break;
1833            }
1834            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1835                final String procName;
1836                final int uid;
1837                final long memLimit;
1838                final String reportPackage;
1839                synchronized (ActivityManagerService.this) {
1840                    procName = mMemWatchDumpProcName;
1841                    uid = mMemWatchDumpUid;
1842                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1843                    if (val == null) {
1844                        val = mMemWatchProcesses.get(procName, 0);
1845                    }
1846                    if (val != null) {
1847                        memLimit = val.first;
1848                        reportPackage = val.second;
1849                    } else {
1850                        memLimit = 0;
1851                        reportPackage = null;
1852                    }
1853                }
1854                if (procName == null) {
1855                    return;
1856                }
1857
1858                if (DEBUG_PSS) Slog.d(TAG_PSS,
1859                        "Showing dump heap notification from " + procName + "/" + uid);
1860
1861                INotificationManager inm = NotificationManager.getService();
1862                if (inm == null) {
1863                    return;
1864                }
1865
1866                String text = mContext.getString(R.string.dump_heap_notification, procName);
1867                Notification notification = new Notification();
1868                notification.icon = com.android.internal.R.drawable.stat_sys_adb;
1869                notification.when = 0;
1870                notification.flags = Notification.FLAG_ONGOING_EVENT|Notification.FLAG_AUTO_CANCEL;
1871                notification.tickerText = text;
1872                notification.defaults = 0; // please be quiet
1873                notification.sound = null;
1874                notification.vibrate = null;
1875                notification.color = mContext.getColor(
1876                        com.android.internal.R.color.system_notification_accent_color);
1877                Intent deleteIntent = new Intent();
1878                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1879                notification.deleteIntent = PendingIntent.getBroadcastAsUser(mContext, 0,
1880                        deleteIntent, 0, UserHandle.OWNER);
1881                Intent intent = new Intent();
1882                intent.setClassName("android", DumpHeapActivity.class.getName());
1883                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1884                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1885                if (reportPackage != null) {
1886                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1887                }
1888                int userId = UserHandle.getUserId(uid);
1889                notification.setLatestEventInfo(mContext, text,
1890                        mContext.getText(R.string.dump_heap_notification_detail),
1891                        PendingIntent.getActivityAsUser(mContext, 0, intent,
1892                                PendingIntent.FLAG_CANCEL_CURRENT, null,
1893                                new UserHandle(userId)));
1894
1895                try {
1896                    int[] outId = new int[1];
1897                    inm.enqueueNotificationWithTag("android", "android", null,
1898                            R.string.dump_heap_notification,
1899                            notification, outId, userId);
1900                } catch (RuntimeException e) {
1901                    Slog.w(ActivityManagerService.TAG,
1902                            "Error showing notification for dump heap", e);
1903                } catch (RemoteException e) {
1904                }
1905            } break;
1906            case DELETE_DUMPHEAP_MSG: {
1907                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
1908                        DumpHeapActivity.JAVA_URI,
1909                        Intent.FLAG_GRANT_READ_URI_PERMISSION
1910                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
1911                        UserHandle.myUserId());
1912                synchronized (ActivityManagerService.this) {
1913                    mMemWatchDumpFile = null;
1914                    mMemWatchDumpProcName = null;
1915                    mMemWatchDumpPid = -1;
1916                    mMemWatchDumpUid = -1;
1917                }
1918            } break;
1919            case FOREGROUND_PROFILE_CHANGED_MSG: {
1920                dispatchForegroundProfileChanged(msg.arg1);
1921            } break;
1922            }
1923        }
1924    };
1925
1926    static final int COLLECT_PSS_BG_MSG = 1;
1927
1928    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1929        @Override
1930        public void handleMessage(Message msg) {
1931            switch (msg.what) {
1932            case COLLECT_PSS_BG_MSG: {
1933                long start = SystemClock.uptimeMillis();
1934                MemInfoReader memInfo = null;
1935                synchronized (ActivityManagerService.this) {
1936                    if (mFullPssPending) {
1937                        mFullPssPending = false;
1938                        memInfo = new MemInfoReader();
1939                    }
1940                }
1941                if (memInfo != null) {
1942                    updateCpuStatsNow();
1943                    long nativeTotalPss = 0;
1944                    synchronized (mProcessCpuTracker) {
1945                        final int N = mProcessCpuTracker.countStats();
1946                        for (int j=0; j<N; j++) {
1947                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1948                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1949                                // This is definitely an application process; skip it.
1950                                continue;
1951                            }
1952                            synchronized (mPidsSelfLocked) {
1953                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1954                                    // This is one of our own processes; skip it.
1955                                    continue;
1956                                }
1957                            }
1958                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1959                        }
1960                    }
1961                    memInfo.readMemInfo();
1962                    synchronized (ActivityManagerService.this) {
1963                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
1964                                + (SystemClock.uptimeMillis()-start) + "ms");
1965                        final long cachedKb = memInfo.getCachedSizeKb();
1966                        final long freeKb = memInfo.getFreeSizeKb();
1967                        final long zramKb = memInfo.getZramTotalSizeKb();
1968                        final long kernelKb = memInfo.getKernelUsedSizeKb();
1969                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
1970                                kernelKb*1024, nativeTotalPss*1024);
1971                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
1972                                nativeTotalPss);
1973                    }
1974                }
1975
1976                int num = 0;
1977                long[] tmp = new long[1];
1978                do {
1979                    ProcessRecord proc;
1980                    int procState;
1981                    int pid;
1982                    long lastPssTime;
1983                    synchronized (ActivityManagerService.this) {
1984                        if (mPendingPssProcesses.size() <= 0) {
1985                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
1986                                    "Collected PSS of " + num + " processes in "
1987                                    + (SystemClock.uptimeMillis() - start) + "ms");
1988                            mPendingPssProcesses.clear();
1989                            return;
1990                        }
1991                        proc = mPendingPssProcesses.remove(0);
1992                        procState = proc.pssProcState;
1993                        lastPssTime = proc.lastPssTime;
1994                        if (proc.thread != null && procState == proc.setProcState
1995                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1996                                        < SystemClock.uptimeMillis()) {
1997                            pid = proc.pid;
1998                        } else {
1999                            proc = null;
2000                            pid = 0;
2001                        }
2002                    }
2003                    if (proc != null) {
2004                        long pss = Debug.getPss(pid, tmp, null);
2005                        synchronized (ActivityManagerService.this) {
2006                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2007                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2008                                num++;
2009                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2010                                        SystemClock.uptimeMillis());
2011                            }
2012                        }
2013                    }
2014                } while (true);
2015            }
2016            }
2017        }
2018    };
2019
2020    public void setSystemProcess() {
2021        try {
2022            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2023            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2024            ServiceManager.addService("meminfo", new MemBinder(this));
2025            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2026            ServiceManager.addService("dbinfo", new DbBinder(this));
2027            if (MONITOR_CPU_USAGE) {
2028                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2029            }
2030            ServiceManager.addService("permission", new PermissionController(this));
2031            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2032
2033            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2034                    "android", STOCK_PM_FLAGS);
2035            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2036
2037            synchronized (this) {
2038                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2039                app.persistent = true;
2040                app.pid = MY_PID;
2041                app.maxAdj = ProcessList.SYSTEM_ADJ;
2042                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2043                mProcessNames.put(app.processName, app.uid, app);
2044                synchronized (mPidsSelfLocked) {
2045                    mPidsSelfLocked.put(app.pid, app);
2046                }
2047                updateLruProcessLocked(app, false, null);
2048                updateOomAdjLocked();
2049            }
2050        } catch (PackageManager.NameNotFoundException e) {
2051            throw new RuntimeException(
2052                    "Unable to find android system package", e);
2053        }
2054    }
2055
2056    public void setWindowManager(WindowManagerService wm) {
2057        mWindowManager = wm;
2058        mStackSupervisor.setWindowManager(wm);
2059    }
2060
2061    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2062        mUsageStatsService = usageStatsManager;
2063    }
2064
2065    public void startObservingNativeCrashes() {
2066        final NativeCrashListener ncl = new NativeCrashListener(this);
2067        ncl.start();
2068    }
2069
2070    public IAppOpsService getAppOpsService() {
2071        return mAppOpsService;
2072    }
2073
2074    static class MemBinder extends Binder {
2075        ActivityManagerService mActivityManagerService;
2076        MemBinder(ActivityManagerService activityManagerService) {
2077            mActivityManagerService = activityManagerService;
2078        }
2079
2080        @Override
2081        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2082            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2083                    != PackageManager.PERMISSION_GRANTED) {
2084                pw.println("Permission Denial: can't dump meminfo from from pid="
2085                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2086                        + " without permission " + android.Manifest.permission.DUMP);
2087                return;
2088            }
2089
2090            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2091        }
2092    }
2093
2094    static class GraphicsBinder extends Binder {
2095        ActivityManagerService mActivityManagerService;
2096        GraphicsBinder(ActivityManagerService activityManagerService) {
2097            mActivityManagerService = activityManagerService;
2098        }
2099
2100        @Override
2101        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2102            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2103                    != PackageManager.PERMISSION_GRANTED) {
2104                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2105                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2106                        + " without permission " + android.Manifest.permission.DUMP);
2107                return;
2108            }
2109
2110            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2111        }
2112    }
2113
2114    static class DbBinder extends Binder {
2115        ActivityManagerService mActivityManagerService;
2116        DbBinder(ActivityManagerService activityManagerService) {
2117            mActivityManagerService = activityManagerService;
2118        }
2119
2120        @Override
2121        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2122            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2123                    != PackageManager.PERMISSION_GRANTED) {
2124                pw.println("Permission Denial: can't dump dbinfo from from pid="
2125                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2126                        + " without permission " + android.Manifest.permission.DUMP);
2127                return;
2128            }
2129
2130            mActivityManagerService.dumpDbInfo(fd, pw, args);
2131        }
2132    }
2133
2134    static class CpuBinder extends Binder {
2135        ActivityManagerService mActivityManagerService;
2136        CpuBinder(ActivityManagerService activityManagerService) {
2137            mActivityManagerService = activityManagerService;
2138        }
2139
2140        @Override
2141        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2142            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2143                    != PackageManager.PERMISSION_GRANTED) {
2144                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2145                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2146                        + " without permission " + android.Manifest.permission.DUMP);
2147                return;
2148            }
2149
2150            synchronized (mActivityManagerService.mProcessCpuTracker) {
2151                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2152                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2153                        SystemClock.uptimeMillis()));
2154            }
2155        }
2156    }
2157
2158    public static final class Lifecycle extends SystemService {
2159        private final ActivityManagerService mService;
2160
2161        public Lifecycle(Context context) {
2162            super(context);
2163            mService = new ActivityManagerService(context);
2164        }
2165
2166        @Override
2167        public void onStart() {
2168            mService.start();
2169        }
2170
2171        public ActivityManagerService getService() {
2172            return mService;
2173        }
2174    }
2175
2176    // Note: This method is invoked on the main thread but may need to attach various
2177    // handlers to other threads.  So take care to be explicit about the looper.
2178    public ActivityManagerService(Context systemContext) {
2179        mContext = systemContext;
2180        mFactoryTest = FactoryTest.getMode();
2181        mSystemThread = ActivityThread.currentActivityThread();
2182
2183        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2184
2185        mHandlerThread = new ServiceThread(TAG,
2186                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2187        mHandlerThread.start();
2188        mHandler = new MainHandler(mHandlerThread.getLooper());
2189
2190        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2191                "foreground", BROADCAST_FG_TIMEOUT, false);
2192        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2193                "background", BROADCAST_BG_TIMEOUT, true);
2194        mBroadcastQueues[0] = mFgBroadcastQueue;
2195        mBroadcastQueues[1] = mBgBroadcastQueue;
2196
2197        mServices = new ActiveServices(this);
2198        mProviderMap = new ProviderMap(this);
2199
2200        // TODO: Move creation of battery stats service outside of activity manager service.
2201        File dataDir = Environment.getDataDirectory();
2202        File systemDir = new File(dataDir, "system");
2203        systemDir.mkdirs();
2204        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2205        mBatteryStatsService.getActiveStatistics().readLocked();
2206        mBatteryStatsService.scheduleWriteToDisk();
2207        mOnBattery = DEBUG_POWER ? true
2208                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2209        mBatteryStatsService.getActiveStatistics().setCallback(this);
2210
2211        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2212
2213        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2214
2215        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2216
2217        // User 0 is the first and only user that runs at boot.
2218        mStartedUsers.put(UserHandle.USER_OWNER, new UserStartedState(UserHandle.OWNER, true));
2219        mUserLru.add(UserHandle.USER_OWNER);
2220        updateStartedUserArrayLocked();
2221
2222        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2223            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2224
2225        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2226
2227        mConfiguration.setToDefaults();
2228        mConfiguration.setLocale(Locale.getDefault());
2229
2230        mConfigurationSeq = mConfiguration.seq = 1;
2231        mProcessCpuTracker.init();
2232
2233        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2234        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2235        mRecentTasks = new RecentTasks(this);
2236        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2237        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2238
2239        mProcessCpuThread = new Thread("CpuTracker") {
2240            @Override
2241            public void run() {
2242                while (true) {
2243                    try {
2244                        try {
2245                            synchronized(this) {
2246                                final long now = SystemClock.uptimeMillis();
2247                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2248                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2249                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2250                                //        + ", write delay=" + nextWriteDelay);
2251                                if (nextWriteDelay < nextCpuDelay) {
2252                                    nextCpuDelay = nextWriteDelay;
2253                                }
2254                                if (nextCpuDelay > 0) {
2255                                    mProcessCpuMutexFree.set(true);
2256                                    this.wait(nextCpuDelay);
2257                                }
2258                            }
2259                        } catch (InterruptedException e) {
2260                        }
2261                        updateCpuStatsNow();
2262                    } catch (Exception e) {
2263                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2264                    }
2265                }
2266            }
2267        };
2268
2269        Watchdog.getInstance().addMonitor(this);
2270        Watchdog.getInstance().addThread(mHandler);
2271    }
2272
2273    public void setSystemServiceManager(SystemServiceManager mgr) {
2274        mSystemServiceManager = mgr;
2275    }
2276
2277    public void setInstaller(Installer installer) {
2278        mInstaller = installer;
2279    }
2280
2281    private void start() {
2282        Process.removeAllProcessGroups();
2283        mProcessCpuThread.start();
2284
2285        mBatteryStatsService.publish(mContext);
2286        mAppOpsService.publish(mContext);
2287        Slog.d("AppOps", "AppOpsService published");
2288        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2289    }
2290
2291    public void initPowerManagement() {
2292        mStackSupervisor.initPowerManagement();
2293        mBatteryStatsService.initPowerManagement();
2294        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2295        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2296        mVoiceWakeLock.setReferenceCounted(false);
2297    }
2298
2299    @Override
2300    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2301            throws RemoteException {
2302        if (code == SYSPROPS_TRANSACTION) {
2303            // We need to tell all apps about the system property change.
2304            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2305            synchronized(this) {
2306                final int NP = mProcessNames.getMap().size();
2307                for (int ip=0; ip<NP; ip++) {
2308                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2309                    final int NA = apps.size();
2310                    for (int ia=0; ia<NA; ia++) {
2311                        ProcessRecord app = apps.valueAt(ia);
2312                        if (app.thread != null) {
2313                            procs.add(app.thread.asBinder());
2314                        }
2315                    }
2316                }
2317            }
2318
2319            int N = procs.size();
2320            for (int i=0; i<N; i++) {
2321                Parcel data2 = Parcel.obtain();
2322                try {
2323                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2324                } catch (RemoteException e) {
2325                }
2326                data2.recycle();
2327            }
2328        }
2329        try {
2330            return super.onTransact(code, data, reply, flags);
2331        } catch (RuntimeException e) {
2332            // The activity manager only throws security exceptions, so let's
2333            // log all others.
2334            if (!(e instanceof SecurityException)) {
2335                Slog.wtf(TAG, "Activity Manager Crash", e);
2336            }
2337            throw e;
2338        }
2339    }
2340
2341    void updateCpuStats() {
2342        final long now = SystemClock.uptimeMillis();
2343        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2344            return;
2345        }
2346        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2347            synchronized (mProcessCpuThread) {
2348                mProcessCpuThread.notify();
2349            }
2350        }
2351    }
2352
2353    void updateCpuStatsNow() {
2354        synchronized (mProcessCpuTracker) {
2355            mProcessCpuMutexFree.set(false);
2356            final long now = SystemClock.uptimeMillis();
2357            boolean haveNewCpuStats = false;
2358
2359            if (MONITOR_CPU_USAGE &&
2360                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2361                mLastCpuTime.set(now);
2362                mProcessCpuTracker.update();
2363                if (mProcessCpuTracker.hasGoodLastStats()) {
2364                    haveNewCpuStats = true;
2365                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2366                    //Slog.i(TAG, "Total CPU usage: "
2367                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2368
2369                    // Slog the cpu usage if the property is set.
2370                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2371                        int user = mProcessCpuTracker.getLastUserTime();
2372                        int system = mProcessCpuTracker.getLastSystemTime();
2373                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2374                        int irq = mProcessCpuTracker.getLastIrqTime();
2375                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2376                        int idle = mProcessCpuTracker.getLastIdleTime();
2377
2378                        int total = user + system + iowait + irq + softIrq + idle;
2379                        if (total == 0) total = 1;
2380
2381                        EventLog.writeEvent(EventLogTags.CPU,
2382                                ((user+system+iowait+irq+softIrq) * 100) / total,
2383                                (user * 100) / total,
2384                                (system * 100) / total,
2385                                (iowait * 100) / total,
2386                                (irq * 100) / total,
2387                                (softIrq * 100) / total);
2388                    }
2389                }
2390            }
2391
2392            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2393            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2394            synchronized(bstats) {
2395                synchronized(mPidsSelfLocked) {
2396                    if (haveNewCpuStats) {
2397                        final int perc = bstats.startAddingCpuLocked();
2398                        if (perc >= 0) {
2399                            int remainUTime = 0;
2400                            int remainSTime = 0;
2401                            int totalUTime = 0;
2402                            int totalSTime = 0;
2403                            final int N = mProcessCpuTracker.countStats();
2404                            for (int i=0; i<N; i++) {
2405                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2406                                if (!st.working) {
2407                                    continue;
2408                                }
2409                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2410                                int otherUTime = (st.rel_utime*perc)/100;
2411                                int otherSTime = (st.rel_stime*perc)/100;
2412                                remainUTime += otherUTime;
2413                                remainSTime += otherSTime;
2414                                totalUTime += st.rel_utime;
2415                                totalSTime += st.rel_stime;
2416                                if (pr != null) {
2417                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2418                                    if (ps == null || !ps.isActive()) {
2419                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2420                                                pr.info.uid, pr.processName);
2421                                    }
2422                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2423                                            st.rel_stime - otherSTime, cpuSpeedTimes);
2424                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2425                                } else {
2426                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2427                                    if (ps == null || !ps.isActive()) {
2428                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2429                                                bstats.mapUid(st.uid), st.name);
2430                                    }
2431                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2432                                            st.rel_stime - otherSTime, cpuSpeedTimes);
2433                                }
2434                            }
2435                            final int userTime = mProcessCpuTracker.getLastUserTime();
2436                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2437                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2438                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2439                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2440                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2441                            bstats.finishAddingCpuLocked(perc, remainUTime,
2442                                    remainSTime, totalUTime, totalSTime, userTime, systemTime,
2443                                    iowaitTime, irqTime, softIrqTime, idleTime, cpuSpeedTimes);
2444                        }
2445                    }
2446                }
2447
2448                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2449                    mLastWriteTime = now;
2450                    mBatteryStatsService.scheduleWriteToDisk();
2451                }
2452            }
2453        }
2454    }
2455
2456    @Override
2457    public void batteryNeedsCpuUpdate() {
2458        updateCpuStatsNow();
2459    }
2460
2461    @Override
2462    public void batteryPowerChanged(boolean onBattery) {
2463        // When plugging in, update the CPU stats first before changing
2464        // the plug state.
2465        updateCpuStatsNow();
2466        synchronized (this) {
2467            synchronized(mPidsSelfLocked) {
2468                mOnBattery = DEBUG_POWER ? true : onBattery;
2469            }
2470        }
2471    }
2472
2473    /**
2474     * Initialize the application bind args. These are passed to each
2475     * process when the bindApplication() IPC is sent to the process. They're
2476     * lazily setup to make sure the services are running when they're asked for.
2477     */
2478    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2479        if (mAppBindArgs == null) {
2480            mAppBindArgs = new HashMap<>();
2481
2482            // Isolated processes won't get this optimization, so that we don't
2483            // violate the rules about which services they have access to.
2484            if (!isolated) {
2485                // Setup the application init args
2486                mAppBindArgs.put("package", ServiceManager.getService("package"));
2487                mAppBindArgs.put("window", ServiceManager.getService("window"));
2488                mAppBindArgs.put(Context.ALARM_SERVICE,
2489                        ServiceManager.getService(Context.ALARM_SERVICE));
2490            }
2491        }
2492        return mAppBindArgs;
2493    }
2494
2495    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2496        if (r != null && mFocusedActivity != r) {
2497            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2498            ActivityRecord last = mFocusedActivity;
2499            mFocusedActivity = r;
2500            if (r.task != null && r.task.voiceInteractor != null) {
2501                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2502            } else {
2503                finishRunningVoiceLocked();
2504                if (last != null && last.task.voiceSession != null) {
2505                    // We had been in a voice interaction session, but now focused has
2506                    // move to something different.  Just finish the session, we can't
2507                    // return to it and retain the proper state and synchronization with
2508                    // the voice interaction service.
2509                    finishVoiceTask(last.task.voiceSession);
2510                }
2511            }
2512            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2513                mWindowManager.setFocusedApp(r.appToken, true);
2514            }
2515            applyUpdateLockStateLocked(r);
2516            if (last != null && last.userId != mFocusedActivity.userId) {
2517                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2518                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2519                                mFocusedActivity.userId, 0));
2520            }
2521        }
2522        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
2523                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2524    }
2525
2526    final void clearFocusedActivity(ActivityRecord r) {
2527        if (mFocusedActivity == r) {
2528            mFocusedActivity = null;
2529        }
2530    }
2531
2532    @Override
2533    public void setFocusedStack(int stackId) {
2534        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2535        synchronized (ActivityManagerService.this) {
2536            ActivityStack stack = mStackSupervisor.getStack(stackId);
2537            if (stack != null) {
2538                ActivityRecord r = stack.topRunningActivityLocked(null);
2539                if (r != null) {
2540                    setFocusedActivityLocked(r, "setFocusedStack");
2541                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2542                }
2543            }
2544        }
2545    }
2546
2547    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2548    @Override
2549    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2550        synchronized (ActivityManagerService.this) {
2551            if (listener != null) {
2552                mTaskStackListeners.register(listener);
2553            }
2554        }
2555    }
2556
2557    @Override
2558    public void notifyActivityDrawn(IBinder token) {
2559        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2560        synchronized (this) {
2561            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2562            if (r != null) {
2563                r.task.stack.notifyActivityDrawnLocked(r);
2564            }
2565        }
2566    }
2567
2568    final void applyUpdateLockStateLocked(ActivityRecord r) {
2569        // Modifications to the UpdateLock state are done on our handler, outside
2570        // the activity manager's locks.  The new state is determined based on the
2571        // state *now* of the relevant activity record.  The object is passed to
2572        // the handler solely for logging detail, not to be consulted/modified.
2573        final boolean nextState = r != null && r.immersive;
2574        mHandler.sendMessage(
2575                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2576    }
2577
2578    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2579        Message msg = Message.obtain();
2580        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2581        msg.obj = r.task.askedCompatMode ? null : r;
2582        mHandler.sendMessage(msg);
2583    }
2584
2585    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2586            String what, Object obj, ProcessRecord srcApp) {
2587        app.lastActivityTime = now;
2588
2589        if (app.activities.size() > 0) {
2590            // Don't want to touch dependent processes that are hosting activities.
2591            return index;
2592        }
2593
2594        int lrui = mLruProcesses.lastIndexOf(app);
2595        if (lrui < 0) {
2596            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2597                    + what + " " + obj + " from " + srcApp);
2598            return index;
2599        }
2600
2601        if (lrui >= index) {
2602            // Don't want to cause this to move dependent processes *back* in the
2603            // list as if they were less frequently used.
2604            return index;
2605        }
2606
2607        if (lrui >= mLruProcessActivityStart) {
2608            // Don't want to touch dependent processes that are hosting activities.
2609            return index;
2610        }
2611
2612        mLruProcesses.remove(lrui);
2613        if (index > 0) {
2614            index--;
2615        }
2616        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2617                + " in LRU list: " + app);
2618        mLruProcesses.add(index, app);
2619        return index;
2620    }
2621
2622    final void removeLruProcessLocked(ProcessRecord app) {
2623        int lrui = mLruProcesses.lastIndexOf(app);
2624        if (lrui >= 0) {
2625            if (!app.killed) {
2626                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2627                Process.killProcessQuiet(app.pid);
2628                Process.killProcessGroup(app.info.uid, app.pid);
2629            }
2630            if (lrui <= mLruProcessActivityStart) {
2631                mLruProcessActivityStart--;
2632            }
2633            if (lrui <= mLruProcessServiceStart) {
2634                mLruProcessServiceStart--;
2635            }
2636            mLruProcesses.remove(lrui);
2637        }
2638    }
2639
2640    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2641            ProcessRecord client) {
2642        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2643                || app.treatLikeActivity;
2644        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2645        if (!activityChange && hasActivity) {
2646            // The process has activities, so we are only allowing activity-based adjustments
2647            // to move it.  It should be kept in the front of the list with other
2648            // processes that have activities, and we don't want those to change their
2649            // order except due to activity operations.
2650            return;
2651        }
2652
2653        mLruSeq++;
2654        final long now = SystemClock.uptimeMillis();
2655        app.lastActivityTime = now;
2656
2657        // First a quick reject: if the app is already at the position we will
2658        // put it, then there is nothing to do.
2659        if (hasActivity) {
2660            final int N = mLruProcesses.size();
2661            if (N > 0 && mLruProcesses.get(N-1) == app) {
2662                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2663                return;
2664            }
2665        } else {
2666            if (mLruProcessServiceStart > 0
2667                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2668                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2669                return;
2670            }
2671        }
2672
2673        int lrui = mLruProcesses.lastIndexOf(app);
2674
2675        if (app.persistent && lrui >= 0) {
2676            // We don't care about the position of persistent processes, as long as
2677            // they are in the list.
2678            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2679            return;
2680        }
2681
2682        /* In progress: compute new position first, so we can avoid doing work
2683           if the process is not actually going to move.  Not yet working.
2684        int addIndex;
2685        int nextIndex;
2686        boolean inActivity = false, inService = false;
2687        if (hasActivity) {
2688            // Process has activities, put it at the very tipsy-top.
2689            addIndex = mLruProcesses.size();
2690            nextIndex = mLruProcessServiceStart;
2691            inActivity = true;
2692        } else if (hasService) {
2693            // Process has services, put it at the top of the service list.
2694            addIndex = mLruProcessActivityStart;
2695            nextIndex = mLruProcessServiceStart;
2696            inActivity = true;
2697            inService = true;
2698        } else  {
2699            // Process not otherwise of interest, it goes to the top of the non-service area.
2700            addIndex = mLruProcessServiceStart;
2701            if (client != null) {
2702                int clientIndex = mLruProcesses.lastIndexOf(client);
2703                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2704                        + app);
2705                if (clientIndex >= 0 && addIndex > clientIndex) {
2706                    addIndex = clientIndex;
2707                }
2708            }
2709            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2710        }
2711
2712        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2713                + mLruProcessActivityStart + "): " + app);
2714        */
2715
2716        if (lrui >= 0) {
2717            if (lrui < mLruProcessActivityStart) {
2718                mLruProcessActivityStart--;
2719            }
2720            if (lrui < mLruProcessServiceStart) {
2721                mLruProcessServiceStart--;
2722            }
2723            /*
2724            if (addIndex > lrui) {
2725                addIndex--;
2726            }
2727            if (nextIndex > lrui) {
2728                nextIndex--;
2729            }
2730            */
2731            mLruProcesses.remove(lrui);
2732        }
2733
2734        /*
2735        mLruProcesses.add(addIndex, app);
2736        if (inActivity) {
2737            mLruProcessActivityStart++;
2738        }
2739        if (inService) {
2740            mLruProcessActivityStart++;
2741        }
2742        */
2743
2744        int nextIndex;
2745        if (hasActivity) {
2746            final int N = mLruProcesses.size();
2747            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2748                // Process doesn't have activities, but has clients with
2749                // activities...  move it up, but one below the top (the top
2750                // should always have a real activity).
2751                if (DEBUG_LRU) Slog.d(TAG_LRU,
2752                        "Adding to second-top of LRU activity list: " + app);
2753                mLruProcesses.add(N - 1, app);
2754                // To keep it from spamming the LRU list (by making a bunch of clients),
2755                // we will push down any other entries owned by the app.
2756                final int uid = app.info.uid;
2757                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2758                    ProcessRecord subProc = mLruProcesses.get(i);
2759                    if (subProc.info.uid == uid) {
2760                        // We want to push this one down the list.  If the process after
2761                        // it is for the same uid, however, don't do so, because we don't
2762                        // want them internally to be re-ordered.
2763                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2764                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2765                                    "Pushing uid " + uid + " swapping at " + i + ": "
2766                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2767                            ProcessRecord tmp = mLruProcesses.get(i);
2768                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2769                            mLruProcesses.set(i - 1, tmp);
2770                            i--;
2771                        }
2772                    } else {
2773                        // A gap, we can stop here.
2774                        break;
2775                    }
2776                }
2777            } else {
2778                // Process has activities, put it at the very tipsy-top.
2779                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2780                mLruProcesses.add(app);
2781            }
2782            nextIndex = mLruProcessServiceStart;
2783        } else if (hasService) {
2784            // Process has services, put it at the top of the service list.
2785            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2786            mLruProcesses.add(mLruProcessActivityStart, app);
2787            nextIndex = mLruProcessServiceStart;
2788            mLruProcessActivityStart++;
2789        } else  {
2790            // Process not otherwise of interest, it goes to the top of the non-service area.
2791            int index = mLruProcessServiceStart;
2792            if (client != null) {
2793                // If there is a client, don't allow the process to be moved up higher
2794                // in the list than that client.
2795                int clientIndex = mLruProcesses.lastIndexOf(client);
2796                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2797                        + " when updating " + app);
2798                if (clientIndex <= lrui) {
2799                    // Don't allow the client index restriction to push it down farther in the
2800                    // list than it already is.
2801                    clientIndex = lrui;
2802                }
2803                if (clientIndex >= 0 && index > clientIndex) {
2804                    index = clientIndex;
2805                }
2806            }
2807            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2808            mLruProcesses.add(index, app);
2809            nextIndex = index-1;
2810            mLruProcessActivityStart++;
2811            mLruProcessServiceStart++;
2812        }
2813
2814        // If the app is currently using a content provider or service,
2815        // bump those processes as well.
2816        for (int j=app.connections.size()-1; j>=0; j--) {
2817            ConnectionRecord cr = app.connections.valueAt(j);
2818            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2819                    && cr.binding.service.app != null
2820                    && cr.binding.service.app.lruSeq != mLruSeq
2821                    && !cr.binding.service.app.persistent) {
2822                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2823                        "service connection", cr, app);
2824            }
2825        }
2826        for (int j=app.conProviders.size()-1; j>=0; j--) {
2827            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2828            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2829                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2830                        "provider reference", cpr, app);
2831            }
2832        }
2833    }
2834
2835    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2836        if (uid == Process.SYSTEM_UID) {
2837            // The system gets to run in any process.  If there are multiple
2838            // processes with the same uid, just pick the first (this
2839            // should never happen).
2840            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2841            if (procs == null) return null;
2842            final int N = procs.size();
2843            for (int i = 0; i < N; i++) {
2844                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2845            }
2846        }
2847        ProcessRecord proc = mProcessNames.get(processName, uid);
2848        if (false && proc != null && !keepIfLarge
2849                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2850                && proc.lastCachedPss >= 4000) {
2851            // Turn this condition on to cause killing to happen regularly, for testing.
2852            if (proc.baseProcessTracker != null) {
2853                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2854            }
2855            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2856        } else if (proc != null && !keepIfLarge
2857                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2858                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2859            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2860            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2861                if (proc.baseProcessTracker != null) {
2862                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2863                }
2864                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2865            }
2866        }
2867        return proc;
2868    }
2869
2870    void ensurePackageDexOpt(String packageName) {
2871        IPackageManager pm = AppGlobals.getPackageManager();
2872        try {
2873            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2874                mDidDexOpt = true;
2875            }
2876        } catch (RemoteException e) {
2877        }
2878    }
2879
2880    boolean isNextTransitionForward() {
2881        int transit = mWindowManager.getPendingAppTransition();
2882        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2883                || transit == AppTransition.TRANSIT_TASK_OPEN
2884                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2885    }
2886
2887    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2888            String processName, String abiOverride, int uid, Runnable crashHandler) {
2889        synchronized(this) {
2890            ApplicationInfo info = new ApplicationInfo();
2891            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2892            // For isolated processes, the former contains the parent's uid and the latter the
2893            // actual uid of the isolated process.
2894            // In the special case introduced by this method (which is, starting an isolated
2895            // process directly from the SystemServer without an actual parent app process) the
2896            // closest thing to a parent's uid is SYSTEM_UID.
2897            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2898            // the |isolated| logic in the ProcessRecord constructor.
2899            info.uid = Process.SYSTEM_UID;
2900            info.processName = processName;
2901            info.className = entryPoint;
2902            info.packageName = "android";
2903            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2904                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2905                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2906                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2907                    crashHandler);
2908            return proc != null ? proc.pid : 0;
2909        }
2910    }
2911
2912    final ProcessRecord startProcessLocked(String processName,
2913            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2914            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2915            boolean isolated, boolean keepIfLarge) {
2916        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2917                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2918                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2919                null /* crashHandler */);
2920    }
2921
2922    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2923            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2924            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2925            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2926        long startTime = SystemClock.elapsedRealtime();
2927        ProcessRecord app;
2928        if (!isolated) {
2929            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2930            checkTime(startTime, "startProcess: after getProcessRecord");
2931
2932            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
2933                // If we are in the background, then check to see if this process
2934                // is bad.  If so, we will just silently fail.
2935                if (mBadProcesses.get(info.processName, info.uid) != null) {
2936                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2937                            + "/" + info.processName);
2938                    return null;
2939                }
2940            } else {
2941                // When the user is explicitly starting a process, then clear its
2942                // crash count so that we won't make it bad until they see at
2943                // least one crash dialog again, and make the process good again
2944                // if it had been bad.
2945                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2946                        + "/" + info.processName);
2947                mProcessCrashTimes.remove(info.processName, info.uid);
2948                if (mBadProcesses.get(info.processName, info.uid) != null) {
2949                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2950                            UserHandle.getUserId(info.uid), info.uid,
2951                            info.processName);
2952                    mBadProcesses.remove(info.processName, info.uid);
2953                    if (app != null) {
2954                        app.bad = false;
2955                    }
2956                }
2957            }
2958        } else {
2959            // If this is an isolated process, it can't re-use an existing process.
2960            app = null;
2961        }
2962
2963        // We don't have to do anything more if:
2964        // (1) There is an existing application record; and
2965        // (2) The caller doesn't think it is dead, OR there is no thread
2966        //     object attached to it so we know it couldn't have crashed; and
2967        // (3) There is a pid assigned to it, so it is either starting or
2968        //     already running.
2969        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
2970                + " app=" + app + " knownToBeDead=" + knownToBeDead
2971                + " thread=" + (app != null ? app.thread : null)
2972                + " pid=" + (app != null ? app.pid : -1));
2973        if (app != null && app.pid > 0) {
2974            if (!knownToBeDead || app.thread == null) {
2975                // We already have the app running, or are waiting for it to
2976                // come up (we have a pid but not yet its thread), so keep it.
2977                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
2978                // If this is a new package in the process, add the package to the list
2979                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2980                checkTime(startTime, "startProcess: done, added package to proc");
2981                return app;
2982            }
2983
2984            // An application record is attached to a previous process,
2985            // clean it up now.
2986            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
2987            checkTime(startTime, "startProcess: bad proc running, killing");
2988            Process.killProcessGroup(app.info.uid, app.pid);
2989            handleAppDiedLocked(app, true, true);
2990            checkTime(startTime, "startProcess: done killing old proc");
2991        }
2992
2993        String hostingNameStr = hostingName != null
2994                ? hostingName.flattenToShortString() : null;
2995
2996        if (app == null) {
2997            checkTime(startTime, "startProcess: creating new process record");
2998            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2999            if (app == null) {
3000                Slog.w(TAG, "Failed making new process record for "
3001                        + processName + "/" + info.uid + " isolated=" + isolated);
3002                return null;
3003            }
3004            app.crashHandler = crashHandler;
3005            mProcessNames.put(processName, app.uid, app);
3006            if (isolated) {
3007                mIsolatedProcesses.put(app.uid, app);
3008            }
3009            checkTime(startTime, "startProcess: done creating new process record");
3010        } else {
3011            // If this is a new package in the process, add the package to the list
3012            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3013            checkTime(startTime, "startProcess: added package to existing proc");
3014        }
3015
3016        // If the system is not ready yet, then hold off on starting this
3017        // process until it is.
3018        if (!mProcessesReady
3019                && !isAllowedWhileBooting(info)
3020                && !allowWhileBooting) {
3021            if (!mProcessesOnHold.contains(app)) {
3022                mProcessesOnHold.add(app);
3023            }
3024            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3025                    "System not ready, putting on hold: " + app);
3026            checkTime(startTime, "startProcess: returning with proc on hold");
3027            return app;
3028        }
3029
3030        checkTime(startTime, "startProcess: stepping in to startProcess");
3031        startProcessLocked(
3032                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3033        checkTime(startTime, "startProcess: done starting proc!");
3034        return (app.pid != 0) ? app : null;
3035    }
3036
3037    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3038        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3039    }
3040
3041    private final void startProcessLocked(ProcessRecord app,
3042            String hostingType, String hostingNameStr) {
3043        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3044                null /* entryPoint */, null /* entryPointArgs */);
3045    }
3046
3047    private final void startProcessLocked(ProcessRecord app, String hostingType,
3048            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3049        long startTime = SystemClock.elapsedRealtime();
3050        if (app.pid > 0 && app.pid != MY_PID) {
3051            checkTime(startTime, "startProcess: removing from pids map");
3052            synchronized (mPidsSelfLocked) {
3053                mPidsSelfLocked.remove(app.pid);
3054                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3055            }
3056            checkTime(startTime, "startProcess: done removing from pids map");
3057            app.setPid(0);
3058        }
3059
3060        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3061                "startProcessLocked removing on hold: " + app);
3062        mProcessesOnHold.remove(app);
3063
3064        checkTime(startTime, "startProcess: starting to update cpu stats");
3065        updateCpuStats();
3066        checkTime(startTime, "startProcess: done updating cpu stats");
3067
3068        try {
3069            int uid = app.uid;
3070
3071            int[] gids = null;
3072            int mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
3073            if (!app.isolated) {
3074                int[] permGids = null;
3075                try {
3076                    checkTime(startTime, "startProcess: getting gids from package manager");
3077                    permGids = AppGlobals.getPackageManager().getPackageGids(app.info.packageName,
3078                            app.userId);
3079                } catch (RemoteException e) {
3080                    Slog.w(TAG, "Unable to retrieve gids", e);
3081                }
3082
3083                /*
3084                 * Add shared application and profile GIDs so applications can share some
3085                 * resources like shared libraries and access user-wide resources
3086                 */
3087                if (ArrayUtils.isEmpty(permGids)) {
3088                    gids = new int[2];
3089                } else {
3090                    gids = new int[permGids.length + 2];
3091                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3092                }
3093                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3094                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3095            }
3096            checkTime(startTime, "startProcess: building args");
3097            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3098                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3099                        && mTopComponent != null
3100                        && app.processName.equals(mTopComponent.getPackageName())) {
3101                    uid = 0;
3102                }
3103                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3104                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3105                    uid = 0;
3106                }
3107            }
3108            int debugFlags = 0;
3109            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3110                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3111                // Also turn on CheckJNI for debuggable apps. It's quite
3112                // awkward to turn on otherwise.
3113                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3114            }
3115            // Run the app in safe mode if its manifest requests so or the
3116            // system is booted in safe mode.
3117            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3118                mSafeMode == true) {
3119                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3120            }
3121            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3122                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3123            }
3124            String jitDebugProperty = SystemProperties.get("debug.usejit");
3125            if ("true".equals(jitDebugProperty)) {
3126                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3127            } else if (!"false".equals(jitDebugProperty)) {
3128                // If we didn't force disable by setting false, defer to the dalvik vm options.
3129                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3130                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3131                }
3132            }
3133            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3134                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3135            }
3136            if ("1".equals(SystemProperties.get("debug.assert"))) {
3137                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3138            }
3139
3140            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3141            if (requiredAbi == null) {
3142                requiredAbi = Build.SUPPORTED_ABIS[0];
3143            }
3144
3145            String instructionSet = null;
3146            if (app.info.primaryCpuAbi != null) {
3147                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3148            }
3149
3150            app.gids = gids;
3151            app.requiredAbi = requiredAbi;
3152            app.instructionSet = instructionSet;
3153
3154            // Start the process.  It will either succeed and return a result containing
3155            // the PID of the new process, or else throw a RuntimeException.
3156            boolean isActivityProcess = (entryPoint == null);
3157            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3158            checkTime(startTime, "startProcess: asking zygote to start proc");
3159            Process.ProcessStartResult startResult = Process.start(entryPoint,
3160                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3161                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3162                    app.info.dataDir, entryPointArgs);
3163            checkTime(startTime, "startProcess: returned from zygote!");
3164
3165            if (app.isolated) {
3166                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3167            }
3168            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3169            checkTime(startTime, "startProcess: done updating battery stats");
3170
3171            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3172                    UserHandle.getUserId(uid), startResult.pid, uid,
3173                    app.processName, hostingType,
3174                    hostingNameStr != null ? hostingNameStr : "");
3175
3176            if (app.persistent) {
3177                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3178            }
3179
3180            checkTime(startTime, "startProcess: building log message");
3181            StringBuilder buf = mStringBuilder;
3182            buf.setLength(0);
3183            buf.append("Start proc ");
3184            buf.append(startResult.pid);
3185            buf.append(':');
3186            buf.append(app.processName);
3187            buf.append('/');
3188            UserHandle.formatUid(buf, uid);
3189            if (!isActivityProcess) {
3190                buf.append(" [");
3191                buf.append(entryPoint);
3192                buf.append("]");
3193            }
3194            buf.append(" for ");
3195            buf.append(hostingType);
3196            if (hostingNameStr != null) {
3197                buf.append(" ");
3198                buf.append(hostingNameStr);
3199            }
3200            Slog.i(TAG, buf.toString());
3201            app.setPid(startResult.pid);
3202            app.usingWrapper = startResult.usingWrapper;
3203            app.removed = false;
3204            app.killed = false;
3205            app.killedByAm = false;
3206            checkTime(startTime, "startProcess: starting to update pids map");
3207            synchronized (mPidsSelfLocked) {
3208                this.mPidsSelfLocked.put(startResult.pid, app);
3209                if (isActivityProcess) {
3210                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3211                    msg.obj = app;
3212                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3213                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3214                }
3215            }
3216            checkTime(startTime, "startProcess: done updating pids map");
3217        } catch (RuntimeException e) {
3218            // XXX do better error recovery.
3219            app.setPid(0);
3220            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3221            if (app.isolated) {
3222                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3223            }
3224            Slog.e(TAG, "Failure starting process " + app.processName, e);
3225        }
3226    }
3227
3228    void updateUsageStats(ActivityRecord component, boolean resumed) {
3229        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3230                "updateUsageStats: comp=" + component + "res=" + resumed);
3231        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3232        if (resumed) {
3233            if (mUsageStatsService != null) {
3234                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3235                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3236            }
3237            synchronized (stats) {
3238                stats.noteActivityResumedLocked(component.app.uid);
3239            }
3240        } else {
3241            if (mUsageStatsService != null) {
3242                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3243                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3244            }
3245            synchronized (stats) {
3246                stats.noteActivityPausedLocked(component.app.uid);
3247            }
3248        }
3249    }
3250
3251    Intent getHomeIntent() {
3252        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3253        intent.setComponent(mTopComponent);
3254        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3255            intent.addCategory(Intent.CATEGORY_HOME);
3256        }
3257        return intent;
3258    }
3259
3260    boolean startHomeActivityLocked(int userId, String reason) {
3261        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3262                && mTopAction == null) {
3263            // We are running in factory test mode, but unable to find
3264            // the factory test app, so just sit around displaying the
3265            // error message and don't try to start anything.
3266            return false;
3267        }
3268        Intent intent = getHomeIntent();
3269        ActivityInfo aInfo =
3270            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3271        if (aInfo != null) {
3272            intent.setComponent(new ComponentName(
3273                    aInfo.applicationInfo.packageName, aInfo.name));
3274            // Don't do this if the home app is currently being
3275            // instrumented.
3276            aInfo = new ActivityInfo(aInfo);
3277            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3278            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3279                    aInfo.applicationInfo.uid, true);
3280            if (app == null || app.instrumentationClass == null) {
3281                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3282                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3283            }
3284        }
3285
3286        return true;
3287    }
3288
3289    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3290        ActivityInfo ai = null;
3291        ComponentName comp = intent.getComponent();
3292        try {
3293            if (comp != null) {
3294                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3295            } else {
3296                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3297                        intent,
3298                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3299                            flags, userId);
3300
3301                if (info != null) {
3302                    ai = info.activityInfo;
3303                }
3304            }
3305        } catch (RemoteException e) {
3306            // ignore
3307        }
3308
3309        return ai;
3310    }
3311
3312    /**
3313     * Starts the "new version setup screen" if appropriate.
3314     */
3315    void startSetupActivityLocked() {
3316        // Only do this once per boot.
3317        if (mCheckedForSetup) {
3318            return;
3319        }
3320
3321        // We will show this screen if the current one is a different
3322        // version than the last one shown, and we are not running in
3323        // low-level factory test mode.
3324        final ContentResolver resolver = mContext.getContentResolver();
3325        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3326                Settings.Global.getInt(resolver,
3327                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3328            mCheckedForSetup = true;
3329
3330            // See if we should be showing the platform update setup UI.
3331            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3332            List<ResolveInfo> ris = mContext.getPackageManager()
3333                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3334
3335            // We don't allow third party apps to replace this.
3336            ResolveInfo ri = null;
3337            for (int i=0; ris != null && i<ris.size(); i++) {
3338                if ((ris.get(i).activityInfo.applicationInfo.flags
3339                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3340                    ri = ris.get(i);
3341                    break;
3342                }
3343            }
3344
3345            if (ri != null) {
3346                String vers = ri.activityInfo.metaData != null
3347                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3348                        : null;
3349                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3350                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3351                            Intent.METADATA_SETUP_VERSION);
3352                }
3353                String lastVers = Settings.Secure.getString(
3354                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3355                if (vers != null && !vers.equals(lastVers)) {
3356                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3357                    intent.setComponent(new ComponentName(
3358                            ri.activityInfo.packageName, ri.activityInfo.name));
3359                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3360                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3361                            null);
3362                }
3363            }
3364        }
3365    }
3366
3367    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3368        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3369    }
3370
3371    void enforceNotIsolatedCaller(String caller) {
3372        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3373            throw new SecurityException("Isolated process not allowed to call " + caller);
3374        }
3375    }
3376
3377    void enforceShellRestriction(String restriction, int userHandle) {
3378        if (Binder.getCallingUid() == Process.SHELL_UID) {
3379            if (userHandle < 0
3380                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3381                throw new SecurityException("Shell does not have permission to access user "
3382                        + userHandle);
3383            }
3384        }
3385    }
3386
3387    @Override
3388    public int getFrontActivityScreenCompatMode() {
3389        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3390        synchronized (this) {
3391            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3392        }
3393    }
3394
3395    @Override
3396    public void setFrontActivityScreenCompatMode(int mode) {
3397        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3398                "setFrontActivityScreenCompatMode");
3399        synchronized (this) {
3400            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3401        }
3402    }
3403
3404    @Override
3405    public int getPackageScreenCompatMode(String packageName) {
3406        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3407        synchronized (this) {
3408            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3409        }
3410    }
3411
3412    @Override
3413    public void setPackageScreenCompatMode(String packageName, int mode) {
3414        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3415                "setPackageScreenCompatMode");
3416        synchronized (this) {
3417            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3418        }
3419    }
3420
3421    @Override
3422    public boolean getPackageAskScreenCompat(String packageName) {
3423        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3424        synchronized (this) {
3425            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3426        }
3427    }
3428
3429    @Override
3430    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3431        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3432                "setPackageAskScreenCompat");
3433        synchronized (this) {
3434            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3435        }
3436    }
3437
3438    private void dispatchProcessesChanged() {
3439        int N;
3440        synchronized (this) {
3441            N = mPendingProcessChanges.size();
3442            if (mActiveProcessChanges.length < N) {
3443                mActiveProcessChanges = new ProcessChangeItem[N];
3444            }
3445            mPendingProcessChanges.toArray(mActiveProcessChanges);
3446            mAvailProcessChanges.addAll(mPendingProcessChanges);
3447            mPendingProcessChanges.clear();
3448            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3449                    "*** Delivering " + N + " process changes");
3450        }
3451
3452        int i = mProcessObservers.beginBroadcast();
3453        while (i > 0) {
3454            i--;
3455            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3456            if (observer != null) {
3457                try {
3458                    for (int j=0; j<N; j++) {
3459                        ProcessChangeItem item = mActiveProcessChanges[j];
3460                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3461                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3462                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3463                                    + item.uid + ": " + item.foregroundActivities);
3464                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3465                                    item.foregroundActivities);
3466                        }
3467                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3468                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3469                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3470                                    + ": " + item.processState);
3471                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3472                        }
3473                    }
3474                } catch (RemoteException e) {
3475                }
3476            }
3477        }
3478        mProcessObservers.finishBroadcast();
3479    }
3480
3481    private void dispatchProcessDied(int pid, int uid) {
3482        int i = mProcessObservers.beginBroadcast();
3483        while (i > 0) {
3484            i--;
3485            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3486            if (observer != null) {
3487                try {
3488                    observer.onProcessDied(pid, uid);
3489                } catch (RemoteException e) {
3490                }
3491            }
3492        }
3493        mProcessObservers.finishBroadcast();
3494    }
3495
3496    @Override
3497    public final int startActivity(IApplicationThread caller, String callingPackage,
3498            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3499            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3500        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3501            resultWho, requestCode, startFlags, profilerInfo, options,
3502            UserHandle.getCallingUserId());
3503    }
3504
3505    @Override
3506    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3507            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3508            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3509        enforceNotIsolatedCaller("startActivity");
3510        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3511                false, ALLOW_FULL_ONLY, "startActivity", null);
3512        // TODO: Switch to user app stacks here.
3513        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3514                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3515                profilerInfo, null, null, options, userId, null, null);
3516    }
3517
3518    @Override
3519    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3520            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3521            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3522
3523        // This is very dangerous -- it allows you to perform a start activity (including
3524        // permission grants) as any app that may launch one of your own activities.  So
3525        // we will only allow this to be done from activities that are part of the core framework,
3526        // and then only when they are running as the system.
3527        final ActivityRecord sourceRecord;
3528        final int targetUid;
3529        final String targetPackage;
3530        synchronized (this) {
3531            if (resultTo == null) {
3532                throw new SecurityException("Must be called from an activity");
3533            }
3534            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3535            if (sourceRecord == null) {
3536                throw new SecurityException("Called with bad activity token: " + resultTo);
3537            }
3538            if (!sourceRecord.info.packageName.equals("android")) {
3539                throw new SecurityException(
3540                        "Must be called from an activity that is declared in the android package");
3541            }
3542            if (sourceRecord.app == null) {
3543                throw new SecurityException("Called without a process attached to activity");
3544            }
3545            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3546                // This is still okay, as long as this activity is running under the
3547                // uid of the original calling activity.
3548                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3549                    throw new SecurityException(
3550                            "Calling activity in uid " + sourceRecord.app.uid
3551                                    + " must be system uid or original calling uid "
3552                                    + sourceRecord.launchedFromUid);
3553                }
3554            }
3555            targetUid = sourceRecord.launchedFromUid;
3556            targetPackage = sourceRecord.launchedFromPackage;
3557        }
3558
3559        if (userId == UserHandle.USER_NULL) {
3560            userId = UserHandle.getUserId(sourceRecord.app.uid);
3561        }
3562
3563        // TODO: Switch to user app stacks here.
3564        try {
3565            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3566                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3567                    null, null, options, userId, null, null);
3568            return ret;
3569        } catch (SecurityException e) {
3570            // XXX need to figure out how to propagate to original app.
3571            // A SecurityException here is generally actually a fault of the original
3572            // calling activity (such as a fairly granting permissions), so propagate it
3573            // back to them.
3574            /*
3575            StringBuilder msg = new StringBuilder();
3576            msg.append("While launching");
3577            msg.append(intent.toString());
3578            msg.append(": ");
3579            msg.append(e.getMessage());
3580            */
3581            throw e;
3582        }
3583    }
3584
3585    @Override
3586    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3587            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3588            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3589        enforceNotIsolatedCaller("startActivityAndWait");
3590        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3591                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3592        WaitResult res = new WaitResult();
3593        // TODO: Switch to user app stacks here.
3594        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3595                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3596                options, userId, null, null);
3597        return res;
3598    }
3599
3600    @Override
3601    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3602            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3603            int startFlags, Configuration config, Bundle options, int userId) {
3604        enforceNotIsolatedCaller("startActivityWithConfig");
3605        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3606                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3607        // TODO: Switch to user app stacks here.
3608        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3609                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3610                null, null, config, options, userId, null, null);
3611        return ret;
3612    }
3613
3614    @Override
3615    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3616            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3617            int requestCode, int flagsMask, int flagsValues, Bundle options)
3618            throws TransactionTooLargeException {
3619        enforceNotIsolatedCaller("startActivityIntentSender");
3620        // Refuse possible leaked file descriptors
3621        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3622            throw new IllegalArgumentException("File descriptors passed in Intent");
3623        }
3624
3625        IIntentSender sender = intent.getTarget();
3626        if (!(sender instanceof PendingIntentRecord)) {
3627            throw new IllegalArgumentException("Bad PendingIntent object");
3628        }
3629
3630        PendingIntentRecord pir = (PendingIntentRecord)sender;
3631
3632        synchronized (this) {
3633            // If this is coming from the currently resumed activity, it is
3634            // effectively saying that app switches are allowed at this point.
3635            final ActivityStack stack = getFocusedStack();
3636            if (stack.mResumedActivity != null &&
3637                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3638                mAppSwitchesAllowedTime = 0;
3639            }
3640        }
3641        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3642                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3643        return ret;
3644    }
3645
3646    @Override
3647    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3648            Intent intent, String resolvedType, IVoiceInteractionSession session,
3649            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3650            Bundle options, int userId) {
3651        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3652                != PackageManager.PERMISSION_GRANTED) {
3653            String msg = "Permission Denial: startVoiceActivity() from pid="
3654                    + Binder.getCallingPid()
3655                    + ", uid=" + Binder.getCallingUid()
3656                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3657            Slog.w(TAG, msg);
3658            throw new SecurityException(msg);
3659        }
3660        if (session == null || interactor == null) {
3661            throw new NullPointerException("null session or interactor");
3662        }
3663        userId = handleIncomingUser(callingPid, callingUid, userId,
3664                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3665        // TODO: Switch to user app stacks here.
3666        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3667                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3668                null, options, userId, null, null);
3669    }
3670
3671    @Override
3672    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3673        synchronized (this) {
3674            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3675                if (keepAwake) {
3676                    mVoiceWakeLock.acquire();
3677                } else {
3678                    mVoiceWakeLock.release();
3679                }
3680            }
3681        }
3682    }
3683
3684    @Override
3685    public boolean startNextMatchingActivity(IBinder callingActivity,
3686            Intent intent, Bundle options) {
3687        // Refuse possible leaked file descriptors
3688        if (intent != null && intent.hasFileDescriptors() == true) {
3689            throw new IllegalArgumentException("File descriptors passed in Intent");
3690        }
3691
3692        synchronized (this) {
3693            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3694            if (r == null) {
3695                ActivityOptions.abort(options);
3696                return false;
3697            }
3698            if (r.app == null || r.app.thread == null) {
3699                // The caller is not running...  d'oh!
3700                ActivityOptions.abort(options);
3701                return false;
3702            }
3703            intent = new Intent(intent);
3704            // The caller is not allowed to change the data.
3705            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3706            // And we are resetting to find the next component...
3707            intent.setComponent(null);
3708
3709            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3710
3711            ActivityInfo aInfo = null;
3712            try {
3713                List<ResolveInfo> resolves =
3714                    AppGlobals.getPackageManager().queryIntentActivities(
3715                            intent, r.resolvedType,
3716                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3717                            UserHandle.getCallingUserId());
3718
3719                // Look for the original activity in the list...
3720                final int N = resolves != null ? resolves.size() : 0;
3721                for (int i=0; i<N; i++) {
3722                    ResolveInfo rInfo = resolves.get(i);
3723                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3724                            && rInfo.activityInfo.name.equals(r.info.name)) {
3725                        // We found the current one...  the next matching is
3726                        // after it.
3727                        i++;
3728                        if (i<N) {
3729                            aInfo = resolves.get(i).activityInfo;
3730                        }
3731                        if (debug) {
3732                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3733                                    + "/" + r.info.name);
3734                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3735                                    + "/" + aInfo.name);
3736                        }
3737                        break;
3738                    }
3739                }
3740            } catch (RemoteException e) {
3741            }
3742
3743            if (aInfo == null) {
3744                // Nobody who is next!
3745                ActivityOptions.abort(options);
3746                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3747                return false;
3748            }
3749
3750            intent.setComponent(new ComponentName(
3751                    aInfo.applicationInfo.packageName, aInfo.name));
3752            intent.setFlags(intent.getFlags()&~(
3753                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3754                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3755                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3756                    Intent.FLAG_ACTIVITY_NEW_TASK));
3757
3758            // Okay now we need to start the new activity, replacing the
3759            // currently running activity.  This is a little tricky because
3760            // we want to start the new one as if the current one is finished,
3761            // but not finish the current one first so that there is no flicker.
3762            // And thus...
3763            final boolean wasFinishing = r.finishing;
3764            r.finishing = true;
3765
3766            // Propagate reply information over to the new activity.
3767            final ActivityRecord resultTo = r.resultTo;
3768            final String resultWho = r.resultWho;
3769            final int requestCode = r.requestCode;
3770            r.resultTo = null;
3771            if (resultTo != null) {
3772                resultTo.removeResultsLocked(r, resultWho, requestCode);
3773            }
3774
3775            final long origId = Binder.clearCallingIdentity();
3776            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3777                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3778                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3779                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3780            Binder.restoreCallingIdentity(origId);
3781
3782            r.finishing = wasFinishing;
3783            if (res != ActivityManager.START_SUCCESS) {
3784                return false;
3785            }
3786            return true;
3787        }
3788    }
3789
3790    @Override
3791    public final int startActivityFromRecents(int taskId, Bundle options) {
3792        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3793            String msg = "Permission Denial: startActivityFromRecents called without " +
3794                    START_TASKS_FROM_RECENTS;
3795            Slog.w(TAG, msg);
3796            throw new SecurityException(msg);
3797        }
3798        return startActivityFromRecentsInner(taskId, options);
3799    }
3800
3801    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3802        final TaskRecord task;
3803        final int callingUid;
3804        final String callingPackage;
3805        final Intent intent;
3806        final int userId;
3807        synchronized (this) {
3808            task = mRecentTasks.taskForIdLocked(taskId);
3809            if (task == null) {
3810                throw new IllegalArgumentException("Task " + taskId + " not found.");
3811            }
3812            if (task.getRootActivity() != null) {
3813                moveTaskToFrontLocked(task.taskId, 0, null);
3814                return ActivityManager.START_TASK_TO_FRONT;
3815            }
3816            callingUid = task.mCallingUid;
3817            callingPackage = task.mCallingPackage;
3818            intent = task.intent;
3819            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3820            userId = task.userId;
3821        }
3822        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3823                options, userId, null, task);
3824    }
3825
3826    final int startActivityInPackage(int uid, String callingPackage,
3827            Intent intent, String resolvedType, IBinder resultTo,
3828            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3829            IActivityContainer container, TaskRecord inTask) {
3830
3831        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3832                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3833
3834        // TODO: Switch to user app stacks here.
3835        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3836                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3837                null, null, null, options, userId, container, inTask);
3838        return ret;
3839    }
3840
3841    @Override
3842    public final int startActivities(IApplicationThread caller, String callingPackage,
3843            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3844            int userId) {
3845        enforceNotIsolatedCaller("startActivities");
3846        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3847                false, ALLOW_FULL_ONLY, "startActivity", null);
3848        // TODO: Switch to user app stacks here.
3849        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3850                resolvedTypes, resultTo, options, userId);
3851        return ret;
3852    }
3853
3854    final int startActivitiesInPackage(int uid, String callingPackage,
3855            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3856            Bundle options, int userId) {
3857
3858        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3859                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3860        // TODO: Switch to user app stacks here.
3861        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3862                resultTo, options, userId);
3863        return ret;
3864    }
3865
3866    @Override
3867    public void reportActivityFullyDrawn(IBinder token) {
3868        synchronized (this) {
3869            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3870            if (r == null) {
3871                return;
3872            }
3873            r.reportFullyDrawnLocked();
3874        }
3875    }
3876
3877    @Override
3878    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3879        synchronized (this) {
3880            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3881            if (r == null) {
3882                return;
3883            }
3884            if (r.task != null && r.task.mResizeable) {
3885                // Fixed screen orientation isn't supported with resizeable activities.
3886                return;
3887            }
3888            final long origId = Binder.clearCallingIdentity();
3889            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3890            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3891                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3892            if (config != null) {
3893                r.frozenBeforeDestroy = true;
3894                if (!updateConfigurationLocked(config, r, false, false)) {
3895                    mStackSupervisor.resumeTopActivitiesLocked();
3896                }
3897            }
3898            Binder.restoreCallingIdentity(origId);
3899        }
3900    }
3901
3902    @Override
3903    public int getRequestedOrientation(IBinder token) {
3904        synchronized (this) {
3905            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3906            if (r == null) {
3907                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3908            }
3909            return mWindowManager.getAppOrientation(r.appToken);
3910        }
3911    }
3912
3913    /**
3914     * This is the internal entry point for handling Activity.finish().
3915     *
3916     * @param token The Binder token referencing the Activity we want to finish.
3917     * @param resultCode Result code, if any, from this Activity.
3918     * @param resultData Result data (Intent), if any, from this Activity.
3919     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3920     *            the root Activity in the task.
3921     *
3922     * @return Returns true if the activity successfully finished, or false if it is still running.
3923     */
3924    @Override
3925    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3926            boolean finishTask) {
3927        // Refuse possible leaked file descriptors
3928        if (resultData != null && resultData.hasFileDescriptors() == true) {
3929            throw new IllegalArgumentException("File descriptors passed in Intent");
3930        }
3931
3932        synchronized(this) {
3933            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3934            if (r == null) {
3935                return true;
3936            }
3937            // Keep track of the root activity of the task before we finish it
3938            TaskRecord tr = r.task;
3939            ActivityRecord rootR = tr.getRootActivity();
3940            if (rootR == null) {
3941                Slog.w(TAG, "Finishing task with all activities already finished");
3942            }
3943            // Do not allow task to finish in Lock Task mode.
3944            if (tr == mStackSupervisor.mLockTaskModeTask) {
3945                if (rootR == r) {
3946                    Slog.i(TAG, "Not finishing task in lock task mode");
3947                    mStackSupervisor.showLockTaskToast();
3948                    return false;
3949                }
3950            }
3951            if (mController != null) {
3952                // Find the first activity that is not finishing.
3953                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3954                if (next != null) {
3955                    // ask watcher if this is allowed
3956                    boolean resumeOK = true;
3957                    try {
3958                        resumeOK = mController.activityResuming(next.packageName);
3959                    } catch (RemoteException e) {
3960                        mController = null;
3961                        Watchdog.getInstance().setActivityController(null);
3962                    }
3963
3964                    if (!resumeOK) {
3965                        Slog.i(TAG, "Not finishing activity because controller resumed");
3966                        return false;
3967                    }
3968                }
3969            }
3970            final long origId = Binder.clearCallingIdentity();
3971            try {
3972                boolean res;
3973                if (finishTask && r == rootR) {
3974                    // If requested, remove the task that is associated to this activity only if it
3975                    // was the root activity in the task. The result code and data is ignored
3976                    // because we don't support returning them across task boundaries.
3977                    res = removeTaskByIdLocked(tr.taskId, false);
3978                    if (!res) {
3979                        Slog.i(TAG, "Removing task failed to finish activity");
3980                    }
3981                } else {
3982                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3983                            resultData, "app-request", true);
3984                    if (!res) {
3985                        Slog.i(TAG, "Failed to finish by app-request");
3986                    }
3987                }
3988                return res;
3989            } finally {
3990                Binder.restoreCallingIdentity(origId);
3991            }
3992        }
3993    }
3994
3995    @Override
3996    public final void finishHeavyWeightApp() {
3997        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3998                != PackageManager.PERMISSION_GRANTED) {
3999            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4000                    + Binder.getCallingPid()
4001                    + ", uid=" + Binder.getCallingUid()
4002                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4003            Slog.w(TAG, msg);
4004            throw new SecurityException(msg);
4005        }
4006
4007        synchronized(this) {
4008            if (mHeavyWeightProcess == null) {
4009                return;
4010            }
4011
4012            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4013            for (int i = 0; i < activities.size(); i++) {
4014                ActivityRecord r = activities.get(i);
4015                if (!r.finishing && r.isInStackLocked()) {
4016                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4017                            null, "finish-heavy", true);
4018                }
4019            }
4020
4021            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4022                    mHeavyWeightProcess.userId, 0));
4023            mHeavyWeightProcess = null;
4024        }
4025    }
4026
4027    @Override
4028    public void crashApplication(int uid, int initialPid, String packageName,
4029            String message) {
4030        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4031                != PackageManager.PERMISSION_GRANTED) {
4032            String msg = "Permission Denial: crashApplication() from pid="
4033                    + Binder.getCallingPid()
4034                    + ", uid=" + Binder.getCallingUid()
4035                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4036            Slog.w(TAG, msg);
4037            throw new SecurityException(msg);
4038        }
4039
4040        synchronized(this) {
4041            ProcessRecord proc = null;
4042
4043            // Figure out which process to kill.  We don't trust that initialPid
4044            // still has any relation to current pids, so must scan through the
4045            // list.
4046            synchronized (mPidsSelfLocked) {
4047                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4048                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4049                    if (p.uid != uid) {
4050                        continue;
4051                    }
4052                    if (p.pid == initialPid) {
4053                        proc = p;
4054                        break;
4055                    }
4056                    if (p.pkgList.containsKey(packageName)) {
4057                        proc = p;
4058                    }
4059                }
4060            }
4061
4062            if (proc == null) {
4063                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4064                        + " initialPid=" + initialPid
4065                        + " packageName=" + packageName);
4066                return;
4067            }
4068
4069            if (proc.thread != null) {
4070                if (proc.pid == Process.myPid()) {
4071                    Log.w(TAG, "crashApplication: trying to crash self!");
4072                    return;
4073                }
4074                long ident = Binder.clearCallingIdentity();
4075                try {
4076                    proc.thread.scheduleCrash(message);
4077                } catch (RemoteException e) {
4078                }
4079                Binder.restoreCallingIdentity(ident);
4080            }
4081        }
4082    }
4083
4084    @Override
4085    public final void finishSubActivity(IBinder token, String resultWho,
4086            int requestCode) {
4087        synchronized(this) {
4088            final long origId = Binder.clearCallingIdentity();
4089            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4090            if (r != null) {
4091                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4092            }
4093            Binder.restoreCallingIdentity(origId);
4094        }
4095    }
4096
4097    @Override
4098    public boolean finishActivityAffinity(IBinder token) {
4099        synchronized(this) {
4100            final long origId = Binder.clearCallingIdentity();
4101            try {
4102                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4103
4104                ActivityRecord rootR = r.task.getRootActivity();
4105                // Do not allow task to finish in Lock Task mode.
4106                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4107                    if (rootR == r) {
4108                        mStackSupervisor.showLockTaskToast();
4109                        return false;
4110                    }
4111                }
4112                boolean res = false;
4113                if (r != null) {
4114                    res = r.task.stack.finishActivityAffinityLocked(r);
4115                }
4116                return res;
4117            } finally {
4118                Binder.restoreCallingIdentity(origId);
4119            }
4120        }
4121    }
4122
4123    @Override
4124    public void finishVoiceTask(IVoiceInteractionSession session) {
4125        synchronized(this) {
4126            final long origId = Binder.clearCallingIdentity();
4127            try {
4128                mStackSupervisor.finishVoiceTask(session);
4129            } finally {
4130                Binder.restoreCallingIdentity(origId);
4131            }
4132        }
4133
4134    }
4135
4136    @Override
4137    public boolean releaseActivityInstance(IBinder token) {
4138        synchronized(this) {
4139            final long origId = Binder.clearCallingIdentity();
4140            try {
4141                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4142                if (r == null) {
4143                    return false;
4144                }
4145                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4146            } finally {
4147                Binder.restoreCallingIdentity(origId);
4148            }
4149        }
4150    }
4151
4152    @Override
4153    public void releaseSomeActivities(IApplicationThread appInt) {
4154        synchronized(this) {
4155            final long origId = Binder.clearCallingIdentity();
4156            try {
4157                ProcessRecord app = getRecordForAppLocked(appInt);
4158                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4159            } finally {
4160                Binder.restoreCallingIdentity(origId);
4161            }
4162        }
4163    }
4164
4165    @Override
4166    public boolean willActivityBeVisible(IBinder token) {
4167        synchronized(this) {
4168            ActivityStack stack = ActivityRecord.getStackLocked(token);
4169            if (stack != null) {
4170                return stack.willActivityBeVisibleLocked(token);
4171            }
4172            return false;
4173        }
4174    }
4175
4176    @Override
4177    public void overridePendingTransition(IBinder token, String packageName,
4178            int enterAnim, int exitAnim) {
4179        synchronized(this) {
4180            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4181            if (self == null) {
4182                return;
4183            }
4184
4185            final long origId = Binder.clearCallingIdentity();
4186
4187            if (self.state == ActivityState.RESUMED
4188                    || self.state == ActivityState.PAUSING) {
4189                mWindowManager.overridePendingAppTransition(packageName,
4190                        enterAnim, exitAnim, null);
4191            }
4192
4193            Binder.restoreCallingIdentity(origId);
4194        }
4195    }
4196
4197    /**
4198     * Main function for removing an existing process from the activity manager
4199     * as a result of that process going away.  Clears out all connections
4200     * to the process.
4201     */
4202    private final void handleAppDiedLocked(ProcessRecord app,
4203            boolean restarting, boolean allowRestart) {
4204        int pid = app.pid;
4205        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4206        if (!kept && !restarting) {
4207            removeLruProcessLocked(app);
4208            if (pid > 0) {
4209                ProcessList.remove(pid);
4210            }
4211        }
4212
4213        if (mProfileProc == app) {
4214            clearProfilerLocked();
4215        }
4216
4217        // Remove this application's activities from active lists.
4218        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4219
4220        app.activities.clear();
4221
4222        if (app.instrumentationClass != null) {
4223            Slog.w(TAG, "Crash of app " + app.processName
4224                  + " running instrumentation " + app.instrumentationClass);
4225            Bundle info = new Bundle();
4226            info.putString("shortMsg", "Process crashed.");
4227            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4228        }
4229
4230        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4231            // If there was nothing to resume, and we are not already
4232            // restarting this process, but there is a visible activity that
4233            // is hosted by the process...  then make sure all visible
4234            // activities are running, taking care of restarting this
4235            // process.
4236            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4237        }
4238    }
4239
4240    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4241        IBinder threadBinder = thread.asBinder();
4242        // Find the application record.
4243        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4244            ProcessRecord rec = mLruProcesses.get(i);
4245            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4246                return i;
4247            }
4248        }
4249        return -1;
4250    }
4251
4252    final ProcessRecord getRecordForAppLocked(
4253            IApplicationThread thread) {
4254        if (thread == null) {
4255            return null;
4256        }
4257
4258        int appIndex = getLRURecordIndexForAppLocked(thread);
4259        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4260    }
4261
4262    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4263        // If there are no longer any background processes running,
4264        // and the app that died was not running instrumentation,
4265        // then tell everyone we are now low on memory.
4266        boolean haveBg = false;
4267        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4268            ProcessRecord rec = mLruProcesses.get(i);
4269            if (rec.thread != null
4270                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4271                haveBg = true;
4272                break;
4273            }
4274        }
4275
4276        if (!haveBg) {
4277            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4278            if (doReport) {
4279                long now = SystemClock.uptimeMillis();
4280                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4281                    doReport = false;
4282                } else {
4283                    mLastMemUsageReportTime = now;
4284                }
4285            }
4286            final ArrayList<ProcessMemInfo> memInfos
4287                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4288            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4289            long now = SystemClock.uptimeMillis();
4290            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4291                ProcessRecord rec = mLruProcesses.get(i);
4292                if (rec == dyingProc || rec.thread == null) {
4293                    continue;
4294                }
4295                if (doReport) {
4296                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4297                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4298                }
4299                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4300                    // The low memory report is overriding any current
4301                    // state for a GC request.  Make sure to do
4302                    // heavy/important/visible/foreground processes first.
4303                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4304                        rec.lastRequestedGc = 0;
4305                    } else {
4306                        rec.lastRequestedGc = rec.lastLowMemory;
4307                    }
4308                    rec.reportLowMemory = true;
4309                    rec.lastLowMemory = now;
4310                    mProcessesToGc.remove(rec);
4311                    addProcessToGcListLocked(rec);
4312                }
4313            }
4314            if (doReport) {
4315                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4316                mHandler.sendMessage(msg);
4317            }
4318            scheduleAppGcsLocked();
4319        }
4320    }
4321
4322    final void appDiedLocked(ProcessRecord app) {
4323       appDiedLocked(app, app.pid, app.thread, false);
4324    }
4325
4326    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4327            boolean fromBinderDied) {
4328        // First check if this ProcessRecord is actually active for the pid.
4329        synchronized (mPidsSelfLocked) {
4330            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4331            if (curProc != app) {
4332                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4333                return;
4334            }
4335        }
4336
4337        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4338        synchronized (stats) {
4339            stats.noteProcessDiedLocked(app.info.uid, pid);
4340        }
4341
4342        if (!app.killed) {
4343            if (!fromBinderDied) {
4344                Process.killProcessQuiet(pid);
4345            }
4346            Process.killProcessGroup(app.info.uid, pid);
4347            app.killed = true;
4348        }
4349
4350        // Clean up already done if the process has been re-started.
4351        if (app.pid == pid && app.thread != null &&
4352                app.thread.asBinder() == thread.asBinder()) {
4353            boolean doLowMem = app.instrumentationClass == null;
4354            boolean doOomAdj = doLowMem;
4355            if (!app.killedByAm) {
4356                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4357                        + ") has died");
4358                mAllowLowerMemLevel = true;
4359            } else {
4360                // Note that we always want to do oom adj to update our state with the
4361                // new number of procs.
4362                mAllowLowerMemLevel = false;
4363                doLowMem = false;
4364            }
4365            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4366            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4367                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4368            handleAppDiedLocked(app, false, true);
4369
4370            if (doOomAdj) {
4371                updateOomAdjLocked();
4372            }
4373            if (doLowMem) {
4374                doLowMemReportIfNeededLocked(app);
4375            }
4376        } else if (app.pid != pid) {
4377            // A new process has already been started.
4378            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4379                    + ") has died and restarted (pid " + app.pid + ").");
4380            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4381        } else if (DEBUG_PROCESSES) {
4382            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4383                    + thread.asBinder());
4384        }
4385    }
4386
4387    /**
4388     * If a stack trace dump file is configured, dump process stack traces.
4389     * @param clearTraces causes the dump file to be erased prior to the new
4390     *    traces being written, if true; when false, the new traces will be
4391     *    appended to any existing file content.
4392     * @param firstPids of dalvik VM processes to dump stack traces for first
4393     * @param lastPids of dalvik VM processes to dump stack traces for last
4394     * @param nativeProcs optional list of native process names to dump stack crawls
4395     * @return file containing stack traces, or null if no dump file is configured
4396     */
4397    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4398            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4399        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4400        if (tracesPath == null || tracesPath.length() == 0) {
4401            return null;
4402        }
4403
4404        File tracesFile = new File(tracesPath);
4405        try {
4406            File tracesDir = tracesFile.getParentFile();
4407            if (!tracesDir.exists()) {
4408                tracesDir.mkdirs();
4409                if (!SELinux.restorecon(tracesDir)) {
4410                    return null;
4411                }
4412            }
4413            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4414
4415            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4416            tracesFile.createNewFile();
4417            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4418        } catch (IOException e) {
4419            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4420            return null;
4421        }
4422
4423        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4424        return tracesFile;
4425    }
4426
4427    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4428            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4429        // Use a FileObserver to detect when traces finish writing.
4430        // The order of traces is considered important to maintain for legibility.
4431        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4432            @Override
4433            public synchronized void onEvent(int event, String path) { notify(); }
4434        };
4435
4436        try {
4437            observer.startWatching();
4438
4439            // First collect all of the stacks of the most important pids.
4440            if (firstPids != null) {
4441                try {
4442                    int num = firstPids.size();
4443                    for (int i = 0; i < num; i++) {
4444                        synchronized (observer) {
4445                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4446                            observer.wait(200);  // Wait for write-close, give up after 200msec
4447                        }
4448                    }
4449                } catch (InterruptedException e) {
4450                    Slog.wtf(TAG, e);
4451                }
4452            }
4453
4454            // Next collect the stacks of the native pids
4455            if (nativeProcs != null) {
4456                int[] pids = Process.getPidsForCommands(nativeProcs);
4457                if (pids != null) {
4458                    for (int pid : pids) {
4459                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4460                    }
4461                }
4462            }
4463
4464            // Lastly, measure CPU usage.
4465            if (processCpuTracker != null) {
4466                processCpuTracker.init();
4467                System.gc();
4468                processCpuTracker.update();
4469                try {
4470                    synchronized (processCpuTracker) {
4471                        processCpuTracker.wait(500); // measure over 1/2 second.
4472                    }
4473                } catch (InterruptedException e) {
4474                }
4475                processCpuTracker.update();
4476
4477                // We'll take the stack crawls of just the top apps using CPU.
4478                final int N = processCpuTracker.countWorkingStats();
4479                int numProcs = 0;
4480                for (int i=0; i<N && numProcs<5; i++) {
4481                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4482                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4483                        numProcs++;
4484                        try {
4485                            synchronized (observer) {
4486                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4487                                observer.wait(200);  // Wait for write-close, give up after 200msec
4488                            }
4489                        } catch (InterruptedException e) {
4490                            Slog.wtf(TAG, e);
4491                        }
4492
4493                    }
4494                }
4495            }
4496        } finally {
4497            observer.stopWatching();
4498        }
4499    }
4500
4501    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4502        if (true || IS_USER_BUILD) {
4503            return;
4504        }
4505        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4506        if (tracesPath == null || tracesPath.length() == 0) {
4507            return;
4508        }
4509
4510        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4511        StrictMode.allowThreadDiskWrites();
4512        try {
4513            final File tracesFile = new File(tracesPath);
4514            final File tracesDir = tracesFile.getParentFile();
4515            final File tracesTmp = new File(tracesDir, "__tmp__");
4516            try {
4517                if (!tracesDir.exists()) {
4518                    tracesDir.mkdirs();
4519                    if (!SELinux.restorecon(tracesDir.getPath())) {
4520                        return;
4521                    }
4522                }
4523                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4524
4525                if (tracesFile.exists()) {
4526                    tracesTmp.delete();
4527                    tracesFile.renameTo(tracesTmp);
4528                }
4529                StringBuilder sb = new StringBuilder();
4530                Time tobj = new Time();
4531                tobj.set(System.currentTimeMillis());
4532                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4533                sb.append(": ");
4534                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4535                sb.append(" since ");
4536                sb.append(msg);
4537                FileOutputStream fos = new FileOutputStream(tracesFile);
4538                fos.write(sb.toString().getBytes());
4539                if (app == null) {
4540                    fos.write("\n*** No application process!".getBytes());
4541                }
4542                fos.close();
4543                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4544            } catch (IOException e) {
4545                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4546                return;
4547            }
4548
4549            if (app != null) {
4550                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4551                firstPids.add(app.pid);
4552                dumpStackTraces(tracesPath, firstPids, null, null, null);
4553            }
4554
4555            File lastTracesFile = null;
4556            File curTracesFile = null;
4557            for (int i=9; i>=0; i--) {
4558                String name = String.format(Locale.US, "slow%02d.txt", i);
4559                curTracesFile = new File(tracesDir, name);
4560                if (curTracesFile.exists()) {
4561                    if (lastTracesFile != null) {
4562                        curTracesFile.renameTo(lastTracesFile);
4563                    } else {
4564                        curTracesFile.delete();
4565                    }
4566                }
4567                lastTracesFile = curTracesFile;
4568            }
4569            tracesFile.renameTo(curTracesFile);
4570            if (tracesTmp.exists()) {
4571                tracesTmp.renameTo(tracesFile);
4572            }
4573        } finally {
4574            StrictMode.setThreadPolicy(oldPolicy);
4575        }
4576    }
4577
4578    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4579            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4580        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4581        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4582
4583        if (mController != null) {
4584            try {
4585                // 0 == continue, -1 = kill process immediately
4586                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4587                if (res < 0 && app.pid != MY_PID) {
4588                    app.kill("anr", true);
4589                }
4590            } catch (RemoteException e) {
4591                mController = null;
4592                Watchdog.getInstance().setActivityController(null);
4593            }
4594        }
4595
4596        long anrTime = SystemClock.uptimeMillis();
4597        if (MONITOR_CPU_USAGE) {
4598            updateCpuStatsNow();
4599        }
4600
4601        synchronized (this) {
4602            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4603            if (mShuttingDown) {
4604                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4605                return;
4606            } else if (app.notResponding) {
4607                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4608                return;
4609            } else if (app.crashing) {
4610                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4611                return;
4612            }
4613
4614            // In case we come through here for the same app before completing
4615            // this one, mark as anring now so we will bail out.
4616            app.notResponding = true;
4617
4618            // Log the ANR to the event log.
4619            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4620                    app.processName, app.info.flags, annotation);
4621
4622            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4623            firstPids.add(app.pid);
4624
4625            int parentPid = app.pid;
4626            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4627            if (parentPid != app.pid) firstPids.add(parentPid);
4628
4629            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4630
4631            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4632                ProcessRecord r = mLruProcesses.get(i);
4633                if (r != null && r.thread != null) {
4634                    int pid = r.pid;
4635                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4636                        if (r.persistent) {
4637                            firstPids.add(pid);
4638                        } else {
4639                            lastPids.put(pid, Boolean.TRUE);
4640                        }
4641                    }
4642                }
4643            }
4644        }
4645
4646        // Log the ANR to the main log.
4647        StringBuilder info = new StringBuilder();
4648        info.setLength(0);
4649        info.append("ANR in ").append(app.processName);
4650        if (activity != null && activity.shortComponentName != null) {
4651            info.append(" (").append(activity.shortComponentName).append(")");
4652        }
4653        info.append("\n");
4654        info.append("PID: ").append(app.pid).append("\n");
4655        if (annotation != null) {
4656            info.append("Reason: ").append(annotation).append("\n");
4657        }
4658        if (parent != null && parent != activity) {
4659            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4660        }
4661
4662        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4663
4664        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4665                NATIVE_STACKS_OF_INTEREST);
4666
4667        String cpuInfo = null;
4668        if (MONITOR_CPU_USAGE) {
4669            updateCpuStatsNow();
4670            synchronized (mProcessCpuTracker) {
4671                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4672            }
4673            info.append(processCpuTracker.printCurrentLoad());
4674            info.append(cpuInfo);
4675        }
4676
4677        info.append(processCpuTracker.printCurrentState(anrTime));
4678
4679        Slog.e(TAG, info.toString());
4680        if (tracesFile == null) {
4681            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4682            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4683        }
4684
4685        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4686                cpuInfo, tracesFile, null);
4687
4688        if (mController != null) {
4689            try {
4690                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4691                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4692                if (res != 0) {
4693                    if (res < 0 && app.pid != MY_PID) {
4694                        app.kill("anr", true);
4695                    } else {
4696                        synchronized (this) {
4697                            mServices.scheduleServiceTimeoutLocked(app);
4698                        }
4699                    }
4700                    return;
4701                }
4702            } catch (RemoteException e) {
4703                mController = null;
4704                Watchdog.getInstance().setActivityController(null);
4705            }
4706        }
4707
4708        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4709        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4710                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4711
4712        synchronized (this) {
4713            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
4714
4715            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4716                app.kill("bg anr", true);
4717                return;
4718            }
4719
4720            // Set the app's notResponding state, and look up the errorReportReceiver
4721            makeAppNotRespondingLocked(app,
4722                    activity != null ? activity.shortComponentName : null,
4723                    annotation != null ? "ANR " + annotation : "ANR",
4724                    info.toString());
4725
4726            // Bring up the infamous App Not Responding dialog
4727            Message msg = Message.obtain();
4728            HashMap<String, Object> map = new HashMap<String, Object>();
4729            msg.what = SHOW_NOT_RESPONDING_MSG;
4730            msg.obj = map;
4731            msg.arg1 = aboveSystem ? 1 : 0;
4732            map.put("app", app);
4733            if (activity != null) {
4734                map.put("activity", activity);
4735            }
4736
4737            mHandler.sendMessage(msg);
4738        }
4739    }
4740
4741    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4742        if (!mLaunchWarningShown) {
4743            mLaunchWarningShown = true;
4744            mHandler.post(new Runnable() {
4745                @Override
4746                public void run() {
4747                    synchronized (ActivityManagerService.this) {
4748                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4749                        d.show();
4750                        mHandler.postDelayed(new Runnable() {
4751                            @Override
4752                            public void run() {
4753                                synchronized (ActivityManagerService.this) {
4754                                    d.dismiss();
4755                                    mLaunchWarningShown = false;
4756                                }
4757                            }
4758                        }, 4000);
4759                    }
4760                }
4761            });
4762        }
4763    }
4764
4765    @Override
4766    public boolean clearApplicationUserData(final String packageName,
4767            final IPackageDataObserver observer, int userId) {
4768        enforceNotIsolatedCaller("clearApplicationUserData");
4769        int uid = Binder.getCallingUid();
4770        int pid = Binder.getCallingPid();
4771        userId = handleIncomingUser(pid, uid,
4772                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4773        long callingId = Binder.clearCallingIdentity();
4774        try {
4775            IPackageManager pm = AppGlobals.getPackageManager();
4776            int pkgUid = -1;
4777            synchronized(this) {
4778                try {
4779                    pkgUid = pm.getPackageUid(packageName, userId);
4780                } catch (RemoteException e) {
4781                }
4782                if (pkgUid == -1) {
4783                    Slog.w(TAG, "Invalid packageName: " + packageName);
4784                    if (observer != null) {
4785                        try {
4786                            observer.onRemoveCompleted(packageName, false);
4787                        } catch (RemoteException e) {
4788                            Slog.i(TAG, "Observer no longer exists.");
4789                        }
4790                    }
4791                    return false;
4792                }
4793                if (uid == pkgUid || checkComponentPermission(
4794                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4795                        pid, uid, -1, true)
4796                        == PackageManager.PERMISSION_GRANTED) {
4797                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4798                } else {
4799                    throw new SecurityException("PID " + pid + " does not have permission "
4800                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4801                                    + " of package " + packageName);
4802                }
4803
4804                // Remove all tasks match the cleared application package and user
4805                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4806                    final TaskRecord tr = mRecentTasks.get(i);
4807                    final String taskPackageName =
4808                            tr.getBaseIntent().getComponent().getPackageName();
4809                    if (tr.userId != userId) continue;
4810                    if (!taskPackageName.equals(packageName)) continue;
4811                    removeTaskByIdLocked(tr.taskId, false);
4812                }
4813            }
4814
4815            try {
4816                // Clear application user data
4817                pm.clearApplicationUserData(packageName, observer, userId);
4818
4819                synchronized(this) {
4820                    // Remove all permissions granted from/to this package
4821                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4822                }
4823
4824                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4825                        Uri.fromParts("package", packageName, null));
4826                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4827                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4828                        null, null, 0, null, null, null, false, false, userId);
4829            } catch (RemoteException e) {
4830            }
4831        } finally {
4832            Binder.restoreCallingIdentity(callingId);
4833        }
4834        return true;
4835    }
4836
4837    @Override
4838    public void killBackgroundProcesses(final String packageName, int userId) {
4839        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4840                != PackageManager.PERMISSION_GRANTED &&
4841                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4842                        != PackageManager.PERMISSION_GRANTED) {
4843            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4844                    + Binder.getCallingPid()
4845                    + ", uid=" + Binder.getCallingUid()
4846                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4847            Slog.w(TAG, msg);
4848            throw new SecurityException(msg);
4849        }
4850
4851        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4852                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4853        long callingId = Binder.clearCallingIdentity();
4854        try {
4855            IPackageManager pm = AppGlobals.getPackageManager();
4856            synchronized(this) {
4857                int appId = -1;
4858                try {
4859                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4860                } catch (RemoteException e) {
4861                }
4862                if (appId == -1) {
4863                    Slog.w(TAG, "Invalid packageName: " + packageName);
4864                    return;
4865                }
4866                killPackageProcessesLocked(packageName, appId, userId,
4867                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4868            }
4869        } finally {
4870            Binder.restoreCallingIdentity(callingId);
4871        }
4872    }
4873
4874    @Override
4875    public void killAllBackgroundProcesses() {
4876        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4877                != PackageManager.PERMISSION_GRANTED) {
4878            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4879                    + Binder.getCallingPid()
4880                    + ", uid=" + Binder.getCallingUid()
4881                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4882            Slog.w(TAG, msg);
4883            throw new SecurityException(msg);
4884        }
4885
4886        long callingId = Binder.clearCallingIdentity();
4887        try {
4888            synchronized(this) {
4889                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4890                final int NP = mProcessNames.getMap().size();
4891                for (int ip=0; ip<NP; ip++) {
4892                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4893                    final int NA = apps.size();
4894                    for (int ia=0; ia<NA; ia++) {
4895                        ProcessRecord app = apps.valueAt(ia);
4896                        if (app.persistent) {
4897                            // we don't kill persistent processes
4898                            continue;
4899                        }
4900                        if (app.removed) {
4901                            procs.add(app);
4902                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4903                            app.removed = true;
4904                            procs.add(app);
4905                        }
4906                    }
4907                }
4908
4909                int N = procs.size();
4910                for (int i=0; i<N; i++) {
4911                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4912                }
4913                mAllowLowerMemLevel = true;
4914                updateOomAdjLocked();
4915                doLowMemReportIfNeededLocked(null);
4916            }
4917        } finally {
4918            Binder.restoreCallingIdentity(callingId);
4919        }
4920    }
4921
4922    @Override
4923    public void forceStopPackage(final String packageName, int userId) {
4924        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4925                != PackageManager.PERMISSION_GRANTED) {
4926            String msg = "Permission Denial: forceStopPackage() from pid="
4927                    + Binder.getCallingPid()
4928                    + ", uid=" + Binder.getCallingUid()
4929                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4930            Slog.w(TAG, msg);
4931            throw new SecurityException(msg);
4932        }
4933        final int callingPid = Binder.getCallingPid();
4934        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4935                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4936        long callingId = Binder.clearCallingIdentity();
4937        try {
4938            IPackageManager pm = AppGlobals.getPackageManager();
4939            synchronized(this) {
4940                int[] users = userId == UserHandle.USER_ALL
4941                        ? getUsersLocked() : new int[] { userId };
4942                for (int user : users) {
4943                    int pkgUid = -1;
4944                    try {
4945                        pkgUid = pm.getPackageUid(packageName, user);
4946                    } catch (RemoteException e) {
4947                    }
4948                    if (pkgUid == -1) {
4949                        Slog.w(TAG, "Invalid packageName: " + packageName);
4950                        continue;
4951                    }
4952                    try {
4953                        pm.setPackageStoppedState(packageName, true, user);
4954                    } catch (RemoteException e) {
4955                    } catch (IllegalArgumentException e) {
4956                        Slog.w(TAG, "Failed trying to unstop package "
4957                                + packageName + ": " + e);
4958                    }
4959                    if (isUserRunningLocked(user, false)) {
4960                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4961                    }
4962                }
4963            }
4964        } finally {
4965            Binder.restoreCallingIdentity(callingId);
4966        }
4967    }
4968
4969    @Override
4970    public void addPackageDependency(String packageName) {
4971        synchronized (this) {
4972            int callingPid = Binder.getCallingPid();
4973            if (callingPid == Process.myPid()) {
4974                //  Yeah, um, no.
4975                return;
4976            }
4977            ProcessRecord proc;
4978            synchronized (mPidsSelfLocked) {
4979                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4980            }
4981            if (proc != null) {
4982                if (proc.pkgDeps == null) {
4983                    proc.pkgDeps = new ArraySet<String>(1);
4984                }
4985                proc.pkgDeps.add(packageName);
4986            }
4987        }
4988    }
4989
4990    /*
4991     * The pkg name and app id have to be specified.
4992     */
4993    @Override
4994    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4995        if (pkg == null) {
4996            return;
4997        }
4998        // Make sure the uid is valid.
4999        if (appid < 0) {
5000            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5001            return;
5002        }
5003        int callerUid = Binder.getCallingUid();
5004        // Only the system server can kill an application
5005        if (callerUid == Process.SYSTEM_UID) {
5006            // Post an aysnc message to kill the application
5007            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5008            msg.arg1 = appid;
5009            msg.arg2 = 0;
5010            Bundle bundle = new Bundle();
5011            bundle.putString("pkg", pkg);
5012            bundle.putString("reason", reason);
5013            msg.obj = bundle;
5014            mHandler.sendMessage(msg);
5015        } else {
5016            throw new SecurityException(callerUid + " cannot kill pkg: " +
5017                    pkg);
5018        }
5019    }
5020
5021    @Override
5022    public void closeSystemDialogs(String reason) {
5023        enforceNotIsolatedCaller("closeSystemDialogs");
5024
5025        final int pid = Binder.getCallingPid();
5026        final int uid = Binder.getCallingUid();
5027        final long origId = Binder.clearCallingIdentity();
5028        try {
5029            synchronized (this) {
5030                // Only allow this from foreground processes, so that background
5031                // applications can't abuse it to prevent system UI from being shown.
5032                if (uid >= Process.FIRST_APPLICATION_UID) {
5033                    ProcessRecord proc;
5034                    synchronized (mPidsSelfLocked) {
5035                        proc = mPidsSelfLocked.get(pid);
5036                    }
5037                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5038                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5039                                + " from background process " + proc);
5040                        return;
5041                    }
5042                }
5043                closeSystemDialogsLocked(reason);
5044            }
5045        } finally {
5046            Binder.restoreCallingIdentity(origId);
5047        }
5048    }
5049
5050    void closeSystemDialogsLocked(String reason) {
5051        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5052        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5053                | Intent.FLAG_RECEIVER_FOREGROUND);
5054        if (reason != null) {
5055            intent.putExtra("reason", reason);
5056        }
5057        mWindowManager.closeSystemDialogs(reason);
5058
5059        mStackSupervisor.closeSystemDialogsLocked();
5060
5061        broadcastIntentLocked(null, null, intent, null,
5062                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5063                Process.SYSTEM_UID, UserHandle.USER_ALL);
5064    }
5065
5066    @Override
5067    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5068        enforceNotIsolatedCaller("getProcessMemoryInfo");
5069        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5070        for (int i=pids.length-1; i>=0; i--) {
5071            ProcessRecord proc;
5072            int oomAdj;
5073            synchronized (this) {
5074                synchronized (mPidsSelfLocked) {
5075                    proc = mPidsSelfLocked.get(pids[i]);
5076                    oomAdj = proc != null ? proc.setAdj : 0;
5077                }
5078            }
5079            infos[i] = new Debug.MemoryInfo();
5080            Debug.getMemoryInfo(pids[i], infos[i]);
5081            if (proc != null) {
5082                synchronized (this) {
5083                    if (proc.thread != null && proc.setAdj == oomAdj) {
5084                        // Record this for posterity if the process has been stable.
5085                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5086                                infos[i].getTotalUss(), false, proc.pkgList);
5087                    }
5088                }
5089            }
5090        }
5091        return infos;
5092    }
5093
5094    @Override
5095    public long[] getProcessPss(int[] pids) {
5096        enforceNotIsolatedCaller("getProcessPss");
5097        long[] pss = new long[pids.length];
5098        for (int i=pids.length-1; i>=0; i--) {
5099            ProcessRecord proc;
5100            int oomAdj;
5101            synchronized (this) {
5102                synchronized (mPidsSelfLocked) {
5103                    proc = mPidsSelfLocked.get(pids[i]);
5104                    oomAdj = proc != null ? proc.setAdj : 0;
5105                }
5106            }
5107            long[] tmpUss = new long[1];
5108            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5109            if (proc != null) {
5110                synchronized (this) {
5111                    if (proc.thread != null && proc.setAdj == oomAdj) {
5112                        // Record this for posterity if the process has been stable.
5113                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5114                    }
5115                }
5116            }
5117        }
5118        return pss;
5119    }
5120
5121    @Override
5122    public void killApplicationProcess(String processName, int uid) {
5123        if (processName == null) {
5124            return;
5125        }
5126
5127        int callerUid = Binder.getCallingUid();
5128        // Only the system server can kill an application
5129        if (callerUid == Process.SYSTEM_UID) {
5130            synchronized (this) {
5131                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5132                if (app != null && app.thread != null) {
5133                    try {
5134                        app.thread.scheduleSuicide();
5135                    } catch (RemoteException e) {
5136                        // If the other end already died, then our work here is done.
5137                    }
5138                } else {
5139                    Slog.w(TAG, "Process/uid not found attempting kill of "
5140                            + processName + " / " + uid);
5141                }
5142            }
5143        } else {
5144            throw new SecurityException(callerUid + " cannot kill app process: " +
5145                    processName);
5146        }
5147    }
5148
5149    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5150        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5151                false, true, false, false, UserHandle.getUserId(uid), reason);
5152        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5153                Uri.fromParts("package", packageName, null));
5154        if (!mProcessesReady) {
5155            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5156                    | Intent.FLAG_RECEIVER_FOREGROUND);
5157        }
5158        intent.putExtra(Intent.EXTRA_UID, uid);
5159        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5160        broadcastIntentLocked(null, null, intent,
5161                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5162                false, false,
5163                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5164    }
5165
5166    private void forceStopUserLocked(int userId, String reason) {
5167        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5168        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5169        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5170                | Intent.FLAG_RECEIVER_FOREGROUND);
5171        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5172        broadcastIntentLocked(null, null, intent,
5173                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5174                false, false,
5175                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5176    }
5177
5178    private final boolean killPackageProcessesLocked(String packageName, int appId,
5179            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5180            boolean doit, boolean evenPersistent, String reason) {
5181        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5182
5183        // Remove all processes this package may have touched: all with the
5184        // same UID (except for the system or root user), and all whose name
5185        // matches the package name.
5186        final int NP = mProcessNames.getMap().size();
5187        for (int ip=0; ip<NP; ip++) {
5188            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5189            final int NA = apps.size();
5190            for (int ia=0; ia<NA; ia++) {
5191                ProcessRecord app = apps.valueAt(ia);
5192                if (app.persistent && !evenPersistent) {
5193                    // we don't kill persistent processes
5194                    continue;
5195                }
5196                if (app.removed) {
5197                    if (doit) {
5198                        procs.add(app);
5199                    }
5200                    continue;
5201                }
5202
5203                // Skip process if it doesn't meet our oom adj requirement.
5204                if (app.setAdj < minOomAdj) {
5205                    continue;
5206                }
5207
5208                // If no package is specified, we call all processes under the
5209                // give user id.
5210                if (packageName == null) {
5211                    if (app.userId != userId) {
5212                        continue;
5213                    }
5214                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5215                        continue;
5216                    }
5217                // Package has been specified, we want to hit all processes
5218                // that match it.  We need to qualify this by the processes
5219                // that are running under the specified app and user ID.
5220                } else {
5221                    final boolean isDep = app.pkgDeps != null
5222                            && app.pkgDeps.contains(packageName);
5223                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5224                        continue;
5225                    }
5226                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5227                        continue;
5228                    }
5229                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5230                        continue;
5231                    }
5232                }
5233
5234                // Process has passed all conditions, kill it!
5235                if (!doit) {
5236                    return true;
5237                }
5238                app.removed = true;
5239                procs.add(app);
5240            }
5241        }
5242
5243        int N = procs.size();
5244        for (int i=0; i<N; i++) {
5245            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5246        }
5247        updateOomAdjLocked();
5248        return N > 0;
5249    }
5250
5251    private final boolean forceStopPackageLocked(String name, int appId,
5252            boolean callerWillRestart, boolean purgeCache, boolean doit,
5253            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5254        int i;
5255        int N;
5256
5257        if (userId == UserHandle.USER_ALL && name == null) {
5258            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5259        }
5260
5261        if (appId < 0 && name != null) {
5262            try {
5263                appId = UserHandle.getAppId(
5264                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5265            } catch (RemoteException e) {
5266            }
5267        }
5268
5269        if (doit) {
5270            if (name != null) {
5271                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5272                        + " user=" + userId + ": " + reason);
5273            } else {
5274                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5275            }
5276
5277            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5278            for (int ip=pmap.size()-1; ip>=0; ip--) {
5279                SparseArray<Long> ba = pmap.valueAt(ip);
5280                for (i=ba.size()-1; i>=0; i--) {
5281                    boolean remove = false;
5282                    final int entUid = ba.keyAt(i);
5283                    if (name != null) {
5284                        if (userId == UserHandle.USER_ALL) {
5285                            if (UserHandle.getAppId(entUid) == appId) {
5286                                remove = true;
5287                            }
5288                        } else {
5289                            if (entUid == UserHandle.getUid(userId, appId)) {
5290                                remove = true;
5291                            }
5292                        }
5293                    } else if (UserHandle.getUserId(entUid) == userId) {
5294                        remove = true;
5295                    }
5296                    if (remove) {
5297                        ba.removeAt(i);
5298                    }
5299                }
5300                if (ba.size() == 0) {
5301                    pmap.removeAt(ip);
5302                }
5303            }
5304        }
5305
5306        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5307                -100, callerWillRestart, true, doit, evenPersistent,
5308                name == null ? ("stop user " + userId) : ("stop " + name));
5309
5310        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5311            if (!doit) {
5312                return true;
5313            }
5314            didSomething = true;
5315        }
5316
5317        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5318            if (!doit) {
5319                return true;
5320            }
5321            didSomething = true;
5322        }
5323
5324        if (name == null) {
5325            // Remove all sticky broadcasts from this user.
5326            mStickyBroadcasts.remove(userId);
5327        }
5328
5329        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5330        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5331                userId, providers)) {
5332            if (!doit) {
5333                return true;
5334            }
5335            didSomething = true;
5336        }
5337        N = providers.size();
5338        for (i=0; i<N; i++) {
5339            removeDyingProviderLocked(null, providers.get(i), true);
5340        }
5341
5342        // Remove transient permissions granted from/to this package/user
5343        removeUriPermissionsForPackageLocked(name, userId, false);
5344
5345        if (name == null || uninstalling) {
5346            // Remove pending intents.  For now we only do this when force
5347            // stopping users, because we have some problems when doing this
5348            // for packages -- app widgets are not currently cleaned up for
5349            // such packages, so they can be left with bad pending intents.
5350            if (mIntentSenderRecords.size() > 0) {
5351                Iterator<WeakReference<PendingIntentRecord>> it
5352                        = mIntentSenderRecords.values().iterator();
5353                while (it.hasNext()) {
5354                    WeakReference<PendingIntentRecord> wpir = it.next();
5355                    if (wpir == null) {
5356                        it.remove();
5357                        continue;
5358                    }
5359                    PendingIntentRecord pir = wpir.get();
5360                    if (pir == null) {
5361                        it.remove();
5362                        continue;
5363                    }
5364                    if (name == null) {
5365                        // Stopping user, remove all objects for the user.
5366                        if (pir.key.userId != userId) {
5367                            // Not the same user, skip it.
5368                            continue;
5369                        }
5370                    } else {
5371                        if (UserHandle.getAppId(pir.uid) != appId) {
5372                            // Different app id, skip it.
5373                            continue;
5374                        }
5375                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5376                            // Different user, skip it.
5377                            continue;
5378                        }
5379                        if (!pir.key.packageName.equals(name)) {
5380                            // Different package, skip it.
5381                            continue;
5382                        }
5383                    }
5384                    if (!doit) {
5385                        return true;
5386                    }
5387                    didSomething = true;
5388                    it.remove();
5389                    pir.canceled = true;
5390                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5391                        pir.key.activity.pendingResults.remove(pir.ref);
5392                    }
5393                }
5394            }
5395        }
5396
5397        if (doit) {
5398            if (purgeCache && name != null) {
5399                AttributeCache ac = AttributeCache.instance();
5400                if (ac != null) {
5401                    ac.removePackage(name);
5402                }
5403            }
5404            if (mBooted) {
5405                mStackSupervisor.resumeTopActivitiesLocked();
5406                mStackSupervisor.scheduleIdleLocked();
5407            }
5408        }
5409
5410        return didSomething;
5411    }
5412
5413    private final boolean removeProcessLocked(ProcessRecord app,
5414            boolean callerWillRestart, boolean allowRestart, String reason) {
5415        final String name = app.processName;
5416        final int uid = app.uid;
5417        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5418            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5419
5420        mProcessNames.remove(name, uid);
5421        mIsolatedProcesses.remove(app.uid);
5422        if (mHeavyWeightProcess == app) {
5423            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5424                    mHeavyWeightProcess.userId, 0));
5425            mHeavyWeightProcess = null;
5426        }
5427        boolean needRestart = false;
5428        if (app.pid > 0 && app.pid != MY_PID) {
5429            int pid = app.pid;
5430            synchronized (mPidsSelfLocked) {
5431                mPidsSelfLocked.remove(pid);
5432                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5433            }
5434            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5435            if (app.isolated) {
5436                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5437            }
5438            app.kill(reason, true);
5439            handleAppDiedLocked(app, true, allowRestart);
5440            removeLruProcessLocked(app);
5441
5442            if (app.persistent && !app.isolated) {
5443                if (!callerWillRestart) {
5444                    addAppLocked(app.info, false, null /* ABI override */);
5445                } else {
5446                    needRestart = true;
5447                }
5448            }
5449        } else {
5450            mRemovedProcesses.add(app);
5451        }
5452
5453        return needRestart;
5454    }
5455
5456    private final void processStartTimedOutLocked(ProcessRecord app) {
5457        final int pid = app.pid;
5458        boolean gone = false;
5459        synchronized (mPidsSelfLocked) {
5460            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5461            if (knownApp != null && knownApp.thread == null) {
5462                mPidsSelfLocked.remove(pid);
5463                gone = true;
5464            }
5465        }
5466
5467        if (gone) {
5468            Slog.w(TAG, "Process " + app + " failed to attach");
5469            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5470                    pid, app.uid, app.processName);
5471            mProcessNames.remove(app.processName, app.uid);
5472            mIsolatedProcesses.remove(app.uid);
5473            if (mHeavyWeightProcess == app) {
5474                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5475                        mHeavyWeightProcess.userId, 0));
5476                mHeavyWeightProcess = null;
5477            }
5478            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5479            if (app.isolated) {
5480                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5481            }
5482            // Take care of any launching providers waiting for this process.
5483            checkAppInLaunchingProvidersLocked(app, true);
5484            // Take care of any services that are waiting for the process.
5485            mServices.processStartTimedOutLocked(app);
5486            app.kill("start timeout", true);
5487            removeLruProcessLocked(app);
5488            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5489                Slog.w(TAG, "Unattached app died before backup, skipping");
5490                try {
5491                    IBackupManager bm = IBackupManager.Stub.asInterface(
5492                            ServiceManager.getService(Context.BACKUP_SERVICE));
5493                    bm.agentDisconnected(app.info.packageName);
5494                } catch (RemoteException e) {
5495                    // Can't happen; the backup manager is local
5496                }
5497            }
5498            if (isPendingBroadcastProcessLocked(pid)) {
5499                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5500                skipPendingBroadcastLocked(pid);
5501            }
5502        } else {
5503            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5504        }
5505    }
5506
5507    private final boolean attachApplicationLocked(IApplicationThread thread,
5508            int pid) {
5509
5510        // Find the application record that is being attached...  either via
5511        // the pid if we are running in multiple processes, or just pull the
5512        // next app record if we are emulating process with anonymous threads.
5513        ProcessRecord app;
5514        if (pid != MY_PID && pid >= 0) {
5515            synchronized (mPidsSelfLocked) {
5516                app = mPidsSelfLocked.get(pid);
5517            }
5518        } else {
5519            app = null;
5520        }
5521
5522        if (app == null) {
5523            Slog.w(TAG, "No pending application record for pid " + pid
5524                    + " (IApplicationThread " + thread + "); dropping process");
5525            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5526            if (pid > 0 && pid != MY_PID) {
5527                Process.killProcessQuiet(pid);
5528                //TODO: Process.killProcessGroup(app.info.uid, pid);
5529            } else {
5530                try {
5531                    thread.scheduleExit();
5532                } catch (Exception e) {
5533                    // Ignore exceptions.
5534                }
5535            }
5536            return false;
5537        }
5538
5539        // If this application record is still attached to a previous
5540        // process, clean it up now.
5541        if (app.thread != null) {
5542            handleAppDiedLocked(app, true, true);
5543        }
5544
5545        // Tell the process all about itself.
5546
5547        if (DEBUG_ALL) Slog.v(
5548                TAG, "Binding process pid " + pid + " to record " + app);
5549
5550        final String processName = app.processName;
5551        try {
5552            AppDeathRecipient adr = new AppDeathRecipient(
5553                    app, pid, thread);
5554            thread.asBinder().linkToDeath(adr, 0);
5555            app.deathRecipient = adr;
5556        } catch (RemoteException e) {
5557            app.resetPackageList(mProcessStats);
5558            startProcessLocked(app, "link fail", processName);
5559            return false;
5560        }
5561
5562        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5563
5564        app.makeActive(thread, mProcessStats);
5565        app.curAdj = app.setAdj = -100;
5566        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5567        app.forcingToForeground = null;
5568        updateProcessForegroundLocked(app, false, false);
5569        app.hasShownUi = false;
5570        app.debugging = false;
5571        app.cached = false;
5572        app.killedByAm = false;
5573
5574        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5575
5576        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5577        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5578
5579        if (!normalMode) {
5580            Slog.i(TAG, "Launching preboot mode app: " + app);
5581        }
5582
5583        if (DEBUG_ALL) Slog.v(
5584            TAG, "New app record " + app
5585            + " thread=" + thread.asBinder() + " pid=" + pid);
5586        try {
5587            int testMode = IApplicationThread.DEBUG_OFF;
5588            if (mDebugApp != null && mDebugApp.equals(processName)) {
5589                testMode = mWaitForDebugger
5590                    ? IApplicationThread.DEBUG_WAIT
5591                    : IApplicationThread.DEBUG_ON;
5592                app.debugging = true;
5593                if (mDebugTransient) {
5594                    mDebugApp = mOrigDebugApp;
5595                    mWaitForDebugger = mOrigWaitForDebugger;
5596                }
5597            }
5598            String profileFile = app.instrumentationProfileFile;
5599            ParcelFileDescriptor profileFd = null;
5600            int samplingInterval = 0;
5601            boolean profileAutoStop = false;
5602            if (mProfileApp != null && mProfileApp.equals(processName)) {
5603                mProfileProc = app;
5604                profileFile = mProfileFile;
5605                profileFd = mProfileFd;
5606                samplingInterval = mSamplingInterval;
5607                profileAutoStop = mAutoStopProfiler;
5608            }
5609            boolean enableOpenGlTrace = false;
5610            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5611                enableOpenGlTrace = true;
5612                mOpenGlTraceApp = null;
5613            }
5614
5615            // If the app is being launched for restore or full backup, set it up specially
5616            boolean isRestrictedBackupMode = false;
5617            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5618                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5619                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5620                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5621            }
5622
5623            ensurePackageDexOpt(app.instrumentationInfo != null
5624                    ? app.instrumentationInfo.packageName
5625                    : app.info.packageName);
5626            if (app.instrumentationClass != null) {
5627                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5628            }
5629            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
5630                    + processName + " with config " + mConfiguration);
5631            ApplicationInfo appInfo = app.instrumentationInfo != null
5632                    ? app.instrumentationInfo : app.info;
5633            app.compat = compatibilityInfoForPackageLocked(appInfo);
5634            if (profileFd != null) {
5635                profileFd = profileFd.dup();
5636            }
5637            ProfilerInfo profilerInfo = profileFile == null ? null
5638                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5639            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5640                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5641                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5642                    isRestrictedBackupMode || !normalMode, app.persistent,
5643                    new Configuration(mConfiguration), app.compat,
5644                    getCommonServicesLocked(app.isolated),
5645                    mCoreSettingsObserver.getCoreSettingsLocked());
5646            updateLruProcessLocked(app, false, null);
5647            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5648        } catch (Exception e) {
5649            // todo: Yikes!  What should we do?  For now we will try to
5650            // start another process, but that could easily get us in
5651            // an infinite loop of restarting processes...
5652            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5653
5654            app.resetPackageList(mProcessStats);
5655            app.unlinkDeathRecipient();
5656            startProcessLocked(app, "bind fail", processName);
5657            return false;
5658        }
5659
5660        // Remove this record from the list of starting applications.
5661        mPersistentStartingProcesses.remove(app);
5662        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
5663                "Attach application locked removing on hold: " + app);
5664        mProcessesOnHold.remove(app);
5665
5666        boolean badApp = false;
5667        boolean didSomething = false;
5668
5669        // See if the top visible activity is waiting to run in this process...
5670        if (normalMode) {
5671            try {
5672                if (mStackSupervisor.attachApplicationLocked(app)) {
5673                    didSomething = true;
5674                }
5675            } catch (Exception e) {
5676                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5677                badApp = true;
5678            }
5679        }
5680
5681        // Find any services that should be running in this process...
5682        if (!badApp) {
5683            try {
5684                didSomething |= mServices.attachApplicationLocked(app, processName);
5685            } catch (Exception e) {
5686                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5687                badApp = true;
5688            }
5689        }
5690
5691        // Check if a next-broadcast receiver is in this process...
5692        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5693            try {
5694                didSomething |= sendPendingBroadcastsLocked(app);
5695            } catch (Exception e) {
5696                // If the app died trying to launch the receiver we declare it 'bad'
5697                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
5698                badApp = true;
5699            }
5700        }
5701
5702        // Check whether the next backup agent is in this process...
5703        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5704            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
5705                    "New app is backup target, launching agent for " + app);
5706            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5707            try {
5708                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5709                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5710                        mBackupTarget.backupMode);
5711            } catch (Exception e) {
5712                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
5713                badApp = true;
5714            }
5715        }
5716
5717        if (badApp) {
5718            app.kill("error during init", true);
5719            handleAppDiedLocked(app, false, true);
5720            return false;
5721        }
5722
5723        if (!didSomething) {
5724            updateOomAdjLocked();
5725        }
5726
5727        return true;
5728    }
5729
5730    @Override
5731    public final void attachApplication(IApplicationThread thread) {
5732        synchronized (this) {
5733            int callingPid = Binder.getCallingPid();
5734            final long origId = Binder.clearCallingIdentity();
5735            attachApplicationLocked(thread, callingPid);
5736            Binder.restoreCallingIdentity(origId);
5737        }
5738    }
5739
5740    @Override
5741    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5742        final long origId = Binder.clearCallingIdentity();
5743        synchronized (this) {
5744            ActivityStack stack = ActivityRecord.getStackLocked(token);
5745            if (stack != null) {
5746                ActivityRecord r =
5747                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5748                if (stopProfiling) {
5749                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5750                        try {
5751                            mProfileFd.close();
5752                        } catch (IOException e) {
5753                        }
5754                        clearProfilerLocked();
5755                    }
5756                }
5757            }
5758        }
5759        Binder.restoreCallingIdentity(origId);
5760    }
5761
5762    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
5763        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
5764                finishBooting? 1 : 0, enableScreen ? 1 : 0));
5765    }
5766
5767    void enableScreenAfterBoot() {
5768        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5769                SystemClock.uptimeMillis());
5770        mWindowManager.enableScreenAfterBoot();
5771
5772        synchronized (this) {
5773            updateEventDispatchingLocked();
5774        }
5775    }
5776
5777    @Override
5778    public void showBootMessage(final CharSequence msg, final boolean always) {
5779        if (Binder.getCallingUid() != Process.myUid()) {
5780            // These days only the core system can call this, so apps can't get in
5781            // the way of what we show about running them.
5782        }
5783        mWindowManager.showBootMessage(msg, always);
5784    }
5785
5786    @Override
5787    public void keyguardWaitingForActivityDrawn() {
5788        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5789        final long token = Binder.clearCallingIdentity();
5790        try {
5791            synchronized (this) {
5792                if (DEBUG_LOCKSCREEN) logLockScreen("");
5793                mWindowManager.keyguardWaitingForActivityDrawn();
5794                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
5795                    mLockScreenShown = LOCK_SCREEN_LEAVING;
5796                    updateSleepIfNeededLocked();
5797                }
5798            }
5799        } finally {
5800            Binder.restoreCallingIdentity(token);
5801        }
5802    }
5803
5804    final void finishBooting() {
5805        synchronized (this) {
5806            if (!mBootAnimationComplete) {
5807                mCallFinishBooting = true;
5808                return;
5809            }
5810            mCallFinishBooting = false;
5811        }
5812
5813        ArraySet<String> completedIsas = new ArraySet<String>();
5814        for (String abi : Build.SUPPORTED_ABIS) {
5815            Process.establishZygoteConnectionForAbi(abi);
5816            final String instructionSet = VMRuntime.getInstructionSet(abi);
5817            if (!completedIsas.contains(instructionSet)) {
5818                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
5819                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
5820                }
5821                completedIsas.add(instructionSet);
5822            }
5823        }
5824
5825        IntentFilter pkgFilter = new IntentFilter();
5826        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5827        pkgFilter.addDataScheme("package");
5828        mContext.registerReceiver(new BroadcastReceiver() {
5829            @Override
5830            public void onReceive(Context context, Intent intent) {
5831                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5832                if (pkgs != null) {
5833                    for (String pkg : pkgs) {
5834                        synchronized (ActivityManagerService.this) {
5835                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
5836                                    0, "query restart")) {
5837                                setResultCode(Activity.RESULT_OK);
5838                                return;
5839                            }
5840                        }
5841                    }
5842                }
5843            }
5844        }, pkgFilter);
5845
5846        IntentFilter dumpheapFilter = new IntentFilter();
5847        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
5848        mContext.registerReceiver(new BroadcastReceiver() {
5849            @Override
5850            public void onReceive(Context context, Intent intent) {
5851                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
5852                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
5853                } else {
5854                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
5855                }
5856            }
5857        }, dumpheapFilter);
5858
5859        // Let system services know.
5860        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5861
5862        synchronized (this) {
5863            // Ensure that any processes we had put on hold are now started
5864            // up.
5865            final int NP = mProcessesOnHold.size();
5866            if (NP > 0) {
5867                ArrayList<ProcessRecord> procs =
5868                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5869                for (int ip=0; ip<NP; ip++) {
5870                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
5871                            + procs.get(ip));
5872                    startProcessLocked(procs.get(ip), "on-hold", null);
5873                }
5874            }
5875
5876            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5877                // Start looking for apps that are abusing wake locks.
5878                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5879                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5880                // Tell anyone interested that we are done booting!
5881                SystemProperties.set("sys.boot_completed", "1");
5882
5883                // And trigger dev.bootcomplete if we are not showing encryption progress
5884                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
5885                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
5886                    SystemProperties.set("dev.bootcomplete", "1");
5887                }
5888                for (int i=0; i<mStartedUsers.size(); i++) {
5889                    UserStartedState uss = mStartedUsers.valueAt(i);
5890                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5891                        uss.mState = UserStartedState.STATE_RUNNING;
5892                        final int userId = mStartedUsers.keyAt(i);
5893                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5894                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5895                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5896                        broadcastIntentLocked(null, null, intent, null,
5897                                new IIntentReceiver.Stub() {
5898                                    @Override
5899                                    public void performReceive(Intent intent, int resultCode,
5900                                            String data, Bundle extras, boolean ordered,
5901                                            boolean sticky, int sendingUser) {
5902                                        synchronized (ActivityManagerService.this) {
5903                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5904                                                    true, false);
5905                                        }
5906                                    }
5907                                },
5908                                0, null, null,
5909                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5910                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5911                                userId);
5912                    }
5913                }
5914                scheduleStartProfilesLocked();
5915            }
5916        }
5917    }
5918
5919    @Override
5920    public void bootAnimationComplete() {
5921        final boolean callFinishBooting;
5922        synchronized (this) {
5923            callFinishBooting = mCallFinishBooting;
5924            mBootAnimationComplete = true;
5925        }
5926        if (callFinishBooting) {
5927            finishBooting();
5928        }
5929    }
5930
5931    @Override
5932    public void systemBackupRestored() {
5933        synchronized (this) {
5934            if (mSystemReady) {
5935                mTaskPersister.restoreTasksFromOtherDeviceLocked();
5936            } else {
5937                Slog.w(TAG, "System backup restored before system is ready");
5938            }
5939        }
5940    }
5941
5942    final void ensureBootCompleted() {
5943        boolean booting;
5944        boolean enableScreen;
5945        synchronized (this) {
5946            booting = mBooting;
5947            mBooting = false;
5948            enableScreen = !mBooted;
5949            mBooted = true;
5950        }
5951
5952        if (booting) {
5953            finishBooting();
5954        }
5955
5956        if (enableScreen) {
5957            enableScreenAfterBoot();
5958        }
5959    }
5960
5961    @Override
5962    public final void activityResumed(IBinder token) {
5963        final long origId = Binder.clearCallingIdentity();
5964        synchronized(this) {
5965            ActivityStack stack = ActivityRecord.getStackLocked(token);
5966            if (stack != null) {
5967                ActivityRecord.activityResumedLocked(token);
5968            }
5969        }
5970        Binder.restoreCallingIdentity(origId);
5971    }
5972
5973    @Override
5974    public final void activityPaused(IBinder token) {
5975        final long origId = Binder.clearCallingIdentity();
5976        synchronized(this) {
5977            ActivityStack stack = ActivityRecord.getStackLocked(token);
5978            if (stack != null) {
5979                stack.activityPausedLocked(token, false);
5980            }
5981        }
5982        Binder.restoreCallingIdentity(origId);
5983    }
5984
5985    @Override
5986    public final void activityStopped(IBinder token, Bundle icicle,
5987            PersistableBundle persistentState, CharSequence description) {
5988        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
5989
5990        // Refuse possible leaked file descriptors
5991        if (icicle != null && icicle.hasFileDescriptors()) {
5992            throw new IllegalArgumentException("File descriptors passed in Bundle");
5993        }
5994
5995        final long origId = Binder.clearCallingIdentity();
5996
5997        synchronized (this) {
5998            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5999            if (r != null) {
6000                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6001            }
6002        }
6003
6004        trimApplications();
6005
6006        Binder.restoreCallingIdentity(origId);
6007    }
6008
6009    @Override
6010    public final void activityDestroyed(IBinder token) {
6011        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6012        synchronized (this) {
6013            ActivityStack stack = ActivityRecord.getStackLocked(token);
6014            if (stack != null) {
6015                stack.activityDestroyedLocked(token, "activityDestroyed");
6016            }
6017        }
6018    }
6019
6020    @Override
6021    public final void backgroundResourcesReleased(IBinder token) {
6022        final long origId = Binder.clearCallingIdentity();
6023        try {
6024            synchronized (this) {
6025                ActivityStack stack = ActivityRecord.getStackLocked(token);
6026                if (stack != null) {
6027                    stack.backgroundResourcesReleased();
6028                }
6029            }
6030        } finally {
6031            Binder.restoreCallingIdentity(origId);
6032        }
6033    }
6034
6035    @Override
6036    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6037        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6038    }
6039
6040    @Override
6041    public final void notifyEnterAnimationComplete(IBinder token) {
6042        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6043    }
6044
6045    @Override
6046    public String getCallingPackage(IBinder token) {
6047        synchronized (this) {
6048            ActivityRecord r = getCallingRecordLocked(token);
6049            return r != null ? r.info.packageName : null;
6050        }
6051    }
6052
6053    @Override
6054    public ComponentName getCallingActivity(IBinder token) {
6055        synchronized (this) {
6056            ActivityRecord r = getCallingRecordLocked(token);
6057            return r != null ? r.intent.getComponent() : null;
6058        }
6059    }
6060
6061    private ActivityRecord getCallingRecordLocked(IBinder token) {
6062        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6063        if (r == null) {
6064            return null;
6065        }
6066        return r.resultTo;
6067    }
6068
6069    @Override
6070    public ComponentName getActivityClassForToken(IBinder token) {
6071        synchronized(this) {
6072            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6073            if (r == null) {
6074                return null;
6075            }
6076            return r.intent.getComponent();
6077        }
6078    }
6079
6080    @Override
6081    public String getPackageForToken(IBinder token) {
6082        synchronized(this) {
6083            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6084            if (r == null) {
6085                return null;
6086            }
6087            return r.packageName;
6088        }
6089    }
6090
6091    @Override
6092    public IIntentSender getIntentSender(int type,
6093            String packageName, IBinder token, String resultWho,
6094            int requestCode, Intent[] intents, String[] resolvedTypes,
6095            int flags, Bundle options, int userId) {
6096        enforceNotIsolatedCaller("getIntentSender");
6097        // Refuse possible leaked file descriptors
6098        if (intents != null) {
6099            if (intents.length < 1) {
6100                throw new IllegalArgumentException("Intents array length must be >= 1");
6101            }
6102            for (int i=0; i<intents.length; i++) {
6103                Intent intent = intents[i];
6104                if (intent != null) {
6105                    if (intent.hasFileDescriptors()) {
6106                        throw new IllegalArgumentException("File descriptors passed in Intent");
6107                    }
6108                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6109                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6110                        throw new IllegalArgumentException(
6111                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6112                    }
6113                    intents[i] = new Intent(intent);
6114                }
6115            }
6116            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6117                throw new IllegalArgumentException(
6118                        "Intent array length does not match resolvedTypes length");
6119            }
6120        }
6121        if (options != null) {
6122            if (options.hasFileDescriptors()) {
6123                throw new IllegalArgumentException("File descriptors passed in options");
6124            }
6125        }
6126
6127        synchronized(this) {
6128            int callingUid = Binder.getCallingUid();
6129            int origUserId = userId;
6130            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6131                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6132                    ALLOW_NON_FULL, "getIntentSender", null);
6133            if (origUserId == UserHandle.USER_CURRENT) {
6134                // We don't want to evaluate this until the pending intent is
6135                // actually executed.  However, we do want to always do the
6136                // security checking for it above.
6137                userId = UserHandle.USER_CURRENT;
6138            }
6139            try {
6140                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6141                    int uid = AppGlobals.getPackageManager()
6142                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6143                    if (!UserHandle.isSameApp(callingUid, uid)) {
6144                        String msg = "Permission Denial: getIntentSender() from pid="
6145                            + Binder.getCallingPid()
6146                            + ", uid=" + Binder.getCallingUid()
6147                            + ", (need uid=" + uid + ")"
6148                            + " is not allowed to send as package " + packageName;
6149                        Slog.w(TAG, msg);
6150                        throw new SecurityException(msg);
6151                    }
6152                }
6153
6154                return getIntentSenderLocked(type, packageName, callingUid, userId,
6155                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6156
6157            } catch (RemoteException e) {
6158                throw new SecurityException(e);
6159            }
6160        }
6161    }
6162
6163    IIntentSender getIntentSenderLocked(int type, String packageName,
6164            int callingUid, int userId, IBinder token, String resultWho,
6165            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6166            Bundle options) {
6167        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6168        ActivityRecord activity = null;
6169        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6170            activity = ActivityRecord.isInStackLocked(token);
6171            if (activity == null) {
6172                return null;
6173            }
6174            if (activity.finishing) {
6175                return null;
6176            }
6177        }
6178
6179        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6180        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6181        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6182        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6183                |PendingIntent.FLAG_UPDATE_CURRENT);
6184
6185        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6186                type, packageName, activity, resultWho,
6187                requestCode, intents, resolvedTypes, flags, options, userId);
6188        WeakReference<PendingIntentRecord> ref;
6189        ref = mIntentSenderRecords.get(key);
6190        PendingIntentRecord rec = ref != null ? ref.get() : null;
6191        if (rec != null) {
6192            if (!cancelCurrent) {
6193                if (updateCurrent) {
6194                    if (rec.key.requestIntent != null) {
6195                        rec.key.requestIntent.replaceExtras(intents != null ?
6196                                intents[intents.length - 1] : null);
6197                    }
6198                    if (intents != null) {
6199                        intents[intents.length-1] = rec.key.requestIntent;
6200                        rec.key.allIntents = intents;
6201                        rec.key.allResolvedTypes = resolvedTypes;
6202                    } else {
6203                        rec.key.allIntents = null;
6204                        rec.key.allResolvedTypes = null;
6205                    }
6206                }
6207                return rec;
6208            }
6209            rec.canceled = true;
6210            mIntentSenderRecords.remove(key);
6211        }
6212        if (noCreate) {
6213            return rec;
6214        }
6215        rec = new PendingIntentRecord(this, key, callingUid);
6216        mIntentSenderRecords.put(key, rec.ref);
6217        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6218            if (activity.pendingResults == null) {
6219                activity.pendingResults
6220                        = new HashSet<WeakReference<PendingIntentRecord>>();
6221            }
6222            activity.pendingResults.add(rec.ref);
6223        }
6224        return rec;
6225    }
6226
6227    @Override
6228    public void cancelIntentSender(IIntentSender sender) {
6229        if (!(sender instanceof PendingIntentRecord)) {
6230            return;
6231        }
6232        synchronized(this) {
6233            PendingIntentRecord rec = (PendingIntentRecord)sender;
6234            try {
6235                int uid = AppGlobals.getPackageManager()
6236                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6237                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6238                    String msg = "Permission Denial: cancelIntentSender() from pid="
6239                        + Binder.getCallingPid()
6240                        + ", uid=" + Binder.getCallingUid()
6241                        + " is not allowed to cancel packges "
6242                        + rec.key.packageName;
6243                    Slog.w(TAG, msg);
6244                    throw new SecurityException(msg);
6245                }
6246            } catch (RemoteException e) {
6247                throw new SecurityException(e);
6248            }
6249            cancelIntentSenderLocked(rec, true);
6250        }
6251    }
6252
6253    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6254        rec.canceled = true;
6255        mIntentSenderRecords.remove(rec.key);
6256        if (cleanActivity && rec.key.activity != null) {
6257            rec.key.activity.pendingResults.remove(rec.ref);
6258        }
6259    }
6260
6261    @Override
6262    public String getPackageForIntentSender(IIntentSender pendingResult) {
6263        if (!(pendingResult instanceof PendingIntentRecord)) {
6264            return null;
6265        }
6266        try {
6267            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6268            return res.key.packageName;
6269        } catch (ClassCastException e) {
6270        }
6271        return null;
6272    }
6273
6274    @Override
6275    public int getUidForIntentSender(IIntentSender sender) {
6276        if (sender instanceof PendingIntentRecord) {
6277            try {
6278                PendingIntentRecord res = (PendingIntentRecord)sender;
6279                return res.uid;
6280            } catch (ClassCastException e) {
6281            }
6282        }
6283        return -1;
6284    }
6285
6286    @Override
6287    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6288        if (!(pendingResult instanceof PendingIntentRecord)) {
6289            return false;
6290        }
6291        try {
6292            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6293            if (res.key.allIntents == null) {
6294                return false;
6295            }
6296            for (int i=0; i<res.key.allIntents.length; i++) {
6297                Intent intent = res.key.allIntents[i];
6298                if (intent.getPackage() != null && intent.getComponent() != null) {
6299                    return false;
6300                }
6301            }
6302            return true;
6303        } catch (ClassCastException e) {
6304        }
6305        return false;
6306    }
6307
6308    @Override
6309    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6310        if (!(pendingResult instanceof PendingIntentRecord)) {
6311            return false;
6312        }
6313        try {
6314            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6315            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6316                return true;
6317            }
6318            return false;
6319        } catch (ClassCastException e) {
6320        }
6321        return false;
6322    }
6323
6324    @Override
6325    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6326        if (!(pendingResult instanceof PendingIntentRecord)) {
6327            return null;
6328        }
6329        try {
6330            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6331            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6332        } catch (ClassCastException e) {
6333        }
6334        return null;
6335    }
6336
6337    @Override
6338    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6339        if (!(pendingResult instanceof PendingIntentRecord)) {
6340            return null;
6341        }
6342        try {
6343            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6344            synchronized (this) {
6345                return getTagForIntentSenderLocked(res, prefix);
6346            }
6347        } catch (ClassCastException e) {
6348        }
6349        return null;
6350    }
6351
6352    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6353        final Intent intent = res.key.requestIntent;
6354        if (intent != null) {
6355            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6356                    || res.lastTagPrefix.equals(prefix))) {
6357                return res.lastTag;
6358            }
6359            res.lastTagPrefix = prefix;
6360            final StringBuilder sb = new StringBuilder(128);
6361            if (prefix != null) {
6362                sb.append(prefix);
6363            }
6364            if (intent.getAction() != null) {
6365                sb.append(intent.getAction());
6366            } else if (intent.getComponent() != null) {
6367                intent.getComponent().appendShortString(sb);
6368            } else {
6369                sb.append("?");
6370            }
6371            return res.lastTag = sb.toString();
6372        }
6373        return null;
6374    }
6375
6376    @Override
6377    public void setProcessLimit(int max) {
6378        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6379                "setProcessLimit()");
6380        synchronized (this) {
6381            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6382            mProcessLimitOverride = max;
6383        }
6384        trimApplications();
6385    }
6386
6387    @Override
6388    public int getProcessLimit() {
6389        synchronized (this) {
6390            return mProcessLimitOverride;
6391        }
6392    }
6393
6394    void foregroundTokenDied(ForegroundToken token) {
6395        synchronized (ActivityManagerService.this) {
6396            synchronized (mPidsSelfLocked) {
6397                ForegroundToken cur
6398                    = mForegroundProcesses.get(token.pid);
6399                if (cur != token) {
6400                    return;
6401                }
6402                mForegroundProcesses.remove(token.pid);
6403                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6404                if (pr == null) {
6405                    return;
6406                }
6407                pr.forcingToForeground = null;
6408                updateProcessForegroundLocked(pr, false, false);
6409            }
6410            updateOomAdjLocked();
6411        }
6412    }
6413
6414    @Override
6415    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6416        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6417                "setProcessForeground()");
6418        synchronized(this) {
6419            boolean changed = false;
6420
6421            synchronized (mPidsSelfLocked) {
6422                ProcessRecord pr = mPidsSelfLocked.get(pid);
6423                if (pr == null && isForeground) {
6424                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6425                    return;
6426                }
6427                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6428                if (oldToken != null) {
6429                    oldToken.token.unlinkToDeath(oldToken, 0);
6430                    mForegroundProcesses.remove(pid);
6431                    if (pr != null) {
6432                        pr.forcingToForeground = null;
6433                    }
6434                    changed = true;
6435                }
6436                if (isForeground && token != null) {
6437                    ForegroundToken newToken = new ForegroundToken() {
6438                        @Override
6439                        public void binderDied() {
6440                            foregroundTokenDied(this);
6441                        }
6442                    };
6443                    newToken.pid = pid;
6444                    newToken.token = token;
6445                    try {
6446                        token.linkToDeath(newToken, 0);
6447                        mForegroundProcesses.put(pid, newToken);
6448                        pr.forcingToForeground = token;
6449                        changed = true;
6450                    } catch (RemoteException e) {
6451                        // If the process died while doing this, we will later
6452                        // do the cleanup with the process death link.
6453                    }
6454                }
6455            }
6456
6457            if (changed) {
6458                updateOomAdjLocked();
6459            }
6460        }
6461    }
6462
6463    // =========================================================
6464    // PROCESS INFO
6465    // =========================================================
6466
6467    static class ProcessInfoService extends IProcessInfoService.Stub {
6468        final ActivityManagerService mActivityManagerService;
6469        ProcessInfoService(ActivityManagerService activityManagerService) {
6470            mActivityManagerService = activityManagerService;
6471        }
6472
6473        @Override
6474        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6475            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6476        }
6477    }
6478
6479    /**
6480     * For each PID in the given input array, write the current process state
6481     * for that process into the output array, or -1 to indicate that no
6482     * process with the given PID exists.
6483     */
6484    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6485        if (pids == null) {
6486            throw new NullPointerException("pids");
6487        } else if (states == null) {
6488            throw new NullPointerException("states");
6489        } else if (pids.length != states.length) {
6490            throw new IllegalArgumentException("input and output arrays have different lengths!");
6491        }
6492
6493        synchronized (mPidsSelfLocked) {
6494            for (int i = 0; i < pids.length; i++) {
6495                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6496                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6497                        pr.curProcState;
6498            }
6499        }
6500    }
6501
6502    // =========================================================
6503    // PERMISSIONS
6504    // =========================================================
6505
6506    static class PermissionController extends IPermissionController.Stub {
6507        ActivityManagerService mActivityManagerService;
6508        PermissionController(ActivityManagerService activityManagerService) {
6509            mActivityManagerService = activityManagerService;
6510        }
6511
6512        @Override
6513        public boolean checkPermission(String permission, int pid, int uid) {
6514            return mActivityManagerService.checkPermission(permission, pid,
6515                    uid) == PackageManager.PERMISSION_GRANTED;
6516        }
6517    }
6518
6519    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6520        @Override
6521        public int checkComponentPermission(String permission, int pid, int uid,
6522                int owningUid, boolean exported) {
6523            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6524                    owningUid, exported);
6525        }
6526
6527        @Override
6528        public Object getAMSLock() {
6529            return ActivityManagerService.this;
6530        }
6531    }
6532
6533    /**
6534     * This can be called with or without the global lock held.
6535     */
6536    int checkComponentPermission(String permission, int pid, int uid,
6537            int owningUid, boolean exported) {
6538        if (pid == MY_PID) {
6539            return PackageManager.PERMISSION_GRANTED;
6540        }
6541        return ActivityManager.checkComponentPermission(permission, uid,
6542                owningUid, exported);
6543    }
6544
6545    /**
6546     * As the only public entry point for permissions checking, this method
6547     * can enforce the semantic that requesting a check on a null global
6548     * permission is automatically denied.  (Internally a null permission
6549     * string is used when calling {@link #checkComponentPermission} in cases
6550     * when only uid-based security is needed.)
6551     *
6552     * This can be called with or without the global lock held.
6553     */
6554    @Override
6555    public int checkPermission(String permission, int pid, int uid) {
6556        if (permission == null) {
6557            return PackageManager.PERMISSION_DENIED;
6558        }
6559        return checkComponentPermission(permission, pid, uid, -1, true);
6560    }
6561
6562    @Override
6563    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6564        if (permission == null) {
6565            return PackageManager.PERMISSION_DENIED;
6566        }
6567
6568        // We might be performing an operation on behalf of an indirect binder
6569        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6570        // client identity accordingly before proceeding.
6571        Identity tlsIdentity = sCallerIdentity.get();
6572        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6573            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6574                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6575            uid = tlsIdentity.uid;
6576            pid = tlsIdentity.pid;
6577        }
6578
6579        return checkComponentPermission(permission, pid, uid, -1, true);
6580    }
6581
6582    /**
6583     * Binder IPC calls go through the public entry point.
6584     * This can be called with or without the global lock held.
6585     */
6586    int checkCallingPermission(String permission) {
6587        return checkPermission(permission,
6588                Binder.getCallingPid(),
6589                UserHandle.getAppId(Binder.getCallingUid()));
6590    }
6591
6592    /**
6593     * This can be called with or without the global lock held.
6594     */
6595    void enforceCallingPermission(String permission, String func) {
6596        if (checkCallingPermission(permission)
6597                == PackageManager.PERMISSION_GRANTED) {
6598            return;
6599        }
6600
6601        String msg = "Permission Denial: " + func + " from pid="
6602                + Binder.getCallingPid()
6603                + ", uid=" + Binder.getCallingUid()
6604                + " requires " + permission;
6605        Slog.w(TAG, msg);
6606        throw new SecurityException(msg);
6607    }
6608
6609    /**
6610     * Determine if UID is holding permissions required to access {@link Uri} in
6611     * the given {@link ProviderInfo}. Final permission checking is always done
6612     * in {@link ContentProvider}.
6613     */
6614    private final boolean checkHoldingPermissionsLocked(
6615            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6616        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6617                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6618        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6619            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6620                    != PERMISSION_GRANTED) {
6621                return false;
6622            }
6623        }
6624        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6625    }
6626
6627    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6628            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6629        if (pi.applicationInfo.uid == uid) {
6630            return true;
6631        } else if (!pi.exported) {
6632            return false;
6633        }
6634
6635        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6636        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6637        try {
6638            // check if target holds top-level <provider> permissions
6639            if (!readMet && pi.readPermission != null && considerUidPermissions
6640                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6641                readMet = true;
6642            }
6643            if (!writeMet && pi.writePermission != null && considerUidPermissions
6644                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6645                writeMet = true;
6646            }
6647
6648            // track if unprotected read/write is allowed; any denied
6649            // <path-permission> below removes this ability
6650            boolean allowDefaultRead = pi.readPermission == null;
6651            boolean allowDefaultWrite = pi.writePermission == null;
6652
6653            // check if target holds any <path-permission> that match uri
6654            final PathPermission[] pps = pi.pathPermissions;
6655            if (pps != null) {
6656                final String path = grantUri.uri.getPath();
6657                int i = pps.length;
6658                while (i > 0 && (!readMet || !writeMet)) {
6659                    i--;
6660                    PathPermission pp = pps[i];
6661                    if (pp.match(path)) {
6662                        if (!readMet) {
6663                            final String pprperm = pp.getReadPermission();
6664                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6665                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
6666                                    + ": match=" + pp.match(path)
6667                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6668                            if (pprperm != null) {
6669                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6670                                        == PERMISSION_GRANTED) {
6671                                    readMet = true;
6672                                } else {
6673                                    allowDefaultRead = false;
6674                                }
6675                            }
6676                        }
6677                        if (!writeMet) {
6678                            final String ppwperm = pp.getWritePermission();
6679                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6680                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
6681                                    + ": match=" + pp.match(path)
6682                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6683                            if (ppwperm != null) {
6684                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6685                                        == PERMISSION_GRANTED) {
6686                                    writeMet = true;
6687                                } else {
6688                                    allowDefaultWrite = false;
6689                                }
6690                            }
6691                        }
6692                    }
6693                }
6694            }
6695
6696            // grant unprotected <provider> read/write, if not blocked by
6697            // <path-permission> above
6698            if (allowDefaultRead) readMet = true;
6699            if (allowDefaultWrite) writeMet = true;
6700
6701        } catch (RemoteException e) {
6702            return false;
6703        }
6704
6705        return readMet && writeMet;
6706    }
6707
6708    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6709        ProviderInfo pi = null;
6710        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6711        if (cpr != null) {
6712            pi = cpr.info;
6713        } else {
6714            try {
6715                pi = AppGlobals.getPackageManager().resolveContentProvider(
6716                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6717            } catch (RemoteException ex) {
6718            }
6719        }
6720        return pi;
6721    }
6722
6723    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6724        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6725        if (targetUris != null) {
6726            return targetUris.get(grantUri);
6727        }
6728        return null;
6729    }
6730
6731    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6732            String targetPkg, int targetUid, GrantUri grantUri) {
6733        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6734        if (targetUris == null) {
6735            targetUris = Maps.newArrayMap();
6736            mGrantedUriPermissions.put(targetUid, targetUris);
6737        }
6738
6739        UriPermission perm = targetUris.get(grantUri);
6740        if (perm == null) {
6741            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6742            targetUris.put(grantUri, perm);
6743        }
6744
6745        return perm;
6746    }
6747
6748    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6749            final int modeFlags) {
6750        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6751        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6752                : UriPermission.STRENGTH_OWNED;
6753
6754        // Root gets to do everything.
6755        if (uid == 0) {
6756            return true;
6757        }
6758
6759        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6760        if (perms == null) return false;
6761
6762        // First look for exact match
6763        final UriPermission exactPerm = perms.get(grantUri);
6764        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6765            return true;
6766        }
6767
6768        // No exact match, look for prefixes
6769        final int N = perms.size();
6770        for (int i = 0; i < N; i++) {
6771            final UriPermission perm = perms.valueAt(i);
6772            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6773                    && perm.getStrength(modeFlags) >= minStrength) {
6774                return true;
6775            }
6776        }
6777
6778        return false;
6779    }
6780
6781    /**
6782     * @param uri This uri must NOT contain an embedded userId.
6783     * @param userId The userId in which the uri is to be resolved.
6784     */
6785    @Override
6786    public int checkUriPermission(Uri uri, int pid, int uid,
6787            final int modeFlags, int userId, IBinder callerToken) {
6788        enforceNotIsolatedCaller("checkUriPermission");
6789
6790        // Another redirected-binder-call permissions check as in
6791        // {@link checkPermissionWithToken}.
6792        Identity tlsIdentity = sCallerIdentity.get();
6793        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6794            uid = tlsIdentity.uid;
6795            pid = tlsIdentity.pid;
6796        }
6797
6798        // Our own process gets to do everything.
6799        if (pid == MY_PID) {
6800            return PackageManager.PERMISSION_GRANTED;
6801        }
6802        synchronized (this) {
6803            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6804                    ? PackageManager.PERMISSION_GRANTED
6805                    : PackageManager.PERMISSION_DENIED;
6806        }
6807    }
6808
6809    /**
6810     * Check if the targetPkg can be granted permission to access uri by
6811     * the callingUid using the given modeFlags.  Throws a security exception
6812     * if callingUid is not allowed to do this.  Returns the uid of the target
6813     * if the URI permission grant should be performed; returns -1 if it is not
6814     * needed (for example targetPkg already has permission to access the URI).
6815     * If you already know the uid of the target, you can supply it in
6816     * lastTargetUid else set that to -1.
6817     */
6818    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6819            final int modeFlags, int lastTargetUid) {
6820        if (!Intent.isAccessUriMode(modeFlags)) {
6821            return -1;
6822        }
6823
6824        if (targetPkg != null) {
6825            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6826                    "Checking grant " + targetPkg + " permission to " + grantUri);
6827        }
6828
6829        final IPackageManager pm = AppGlobals.getPackageManager();
6830
6831        // If this is not a content: uri, we can't do anything with it.
6832        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6833            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6834                    "Can't grant URI permission for non-content URI: " + grantUri);
6835            return -1;
6836        }
6837
6838        final String authority = grantUri.uri.getAuthority();
6839        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6840        if (pi == null) {
6841            Slog.w(TAG, "No content provider found for permission check: " +
6842                    grantUri.uri.toSafeString());
6843            return -1;
6844        }
6845
6846        int targetUid = lastTargetUid;
6847        if (targetUid < 0 && targetPkg != null) {
6848            try {
6849                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6850                if (targetUid < 0) {
6851                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6852                            "Can't grant URI permission no uid for: " + targetPkg);
6853                    return -1;
6854                }
6855            } catch (RemoteException ex) {
6856                return -1;
6857            }
6858        }
6859
6860        if (targetUid >= 0) {
6861            // First...  does the target actually need this permission?
6862            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6863                // No need to grant the target this permission.
6864                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6865                        "Target " + targetPkg + " already has full permission to " + grantUri);
6866                return -1;
6867            }
6868        } else {
6869            // First...  there is no target package, so can anyone access it?
6870            boolean allowed = pi.exported;
6871            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6872                if (pi.readPermission != null) {
6873                    allowed = false;
6874                }
6875            }
6876            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6877                if (pi.writePermission != null) {
6878                    allowed = false;
6879                }
6880            }
6881            if (allowed) {
6882                return -1;
6883            }
6884        }
6885
6886        /* There is a special cross user grant if:
6887         * - The target is on another user.
6888         * - Apps on the current user can access the uri without any uid permissions.
6889         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6890         * grant uri permissions.
6891         */
6892        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6893                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6894                modeFlags, false /*without considering the uid permissions*/);
6895
6896        // Second...  is the provider allowing granting of URI permissions?
6897        if (!specialCrossUserGrant) {
6898            if (!pi.grantUriPermissions) {
6899                throw new SecurityException("Provider " + pi.packageName
6900                        + "/" + pi.name
6901                        + " does not allow granting of Uri permissions (uri "
6902                        + grantUri + ")");
6903            }
6904            if (pi.uriPermissionPatterns != null) {
6905                final int N = pi.uriPermissionPatterns.length;
6906                boolean allowed = false;
6907                for (int i=0; i<N; i++) {
6908                    if (pi.uriPermissionPatterns[i] != null
6909                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6910                        allowed = true;
6911                        break;
6912                    }
6913                }
6914                if (!allowed) {
6915                    throw new SecurityException("Provider " + pi.packageName
6916                            + "/" + pi.name
6917                            + " does not allow granting of permission to path of Uri "
6918                            + grantUri);
6919                }
6920            }
6921        }
6922
6923        // Third...  does the caller itself have permission to access
6924        // this uri?
6925        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6926            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6927                // Require they hold a strong enough Uri permission
6928                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6929                    throw new SecurityException("Uid " + callingUid
6930                            + " does not have permission to uri " + grantUri);
6931                }
6932            }
6933        }
6934        return targetUid;
6935    }
6936
6937    /**
6938     * @param uri This uri must NOT contain an embedded userId.
6939     * @param userId The userId in which the uri is to be resolved.
6940     */
6941    @Override
6942    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6943            final int modeFlags, int userId) {
6944        enforceNotIsolatedCaller("checkGrantUriPermission");
6945        synchronized(this) {
6946            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6947                    new GrantUri(userId, uri, false), modeFlags, -1);
6948        }
6949    }
6950
6951    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6952            final int modeFlags, UriPermissionOwner owner) {
6953        if (!Intent.isAccessUriMode(modeFlags)) {
6954            return;
6955        }
6956
6957        // So here we are: the caller has the assumed permission
6958        // to the uri, and the target doesn't.  Let's now give this to
6959        // the target.
6960
6961        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6962                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6963
6964        final String authority = grantUri.uri.getAuthority();
6965        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6966        if (pi == null) {
6967            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6968            return;
6969        }
6970
6971        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6972            grantUri.prefix = true;
6973        }
6974        final UriPermission perm = findOrCreateUriPermissionLocked(
6975                pi.packageName, targetPkg, targetUid, grantUri);
6976        perm.grantModes(modeFlags, owner);
6977    }
6978
6979    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6980            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6981        if (targetPkg == null) {
6982            throw new NullPointerException("targetPkg");
6983        }
6984        int targetUid;
6985        final IPackageManager pm = AppGlobals.getPackageManager();
6986        try {
6987            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6988        } catch (RemoteException ex) {
6989            return;
6990        }
6991
6992        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6993                targetUid);
6994        if (targetUid < 0) {
6995            return;
6996        }
6997
6998        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6999                owner);
7000    }
7001
7002    static class NeededUriGrants extends ArrayList<GrantUri> {
7003        final String targetPkg;
7004        final int targetUid;
7005        final int flags;
7006
7007        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7008            this.targetPkg = targetPkg;
7009            this.targetUid = targetUid;
7010            this.flags = flags;
7011        }
7012    }
7013
7014    /**
7015     * Like checkGrantUriPermissionLocked, but takes an Intent.
7016     */
7017    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7018            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7019        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7020                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7021                + " clip=" + (intent != null ? intent.getClipData() : null)
7022                + " from " + intent + "; flags=0x"
7023                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7024
7025        if (targetPkg == null) {
7026            throw new NullPointerException("targetPkg");
7027        }
7028
7029        if (intent == null) {
7030            return null;
7031        }
7032        Uri data = intent.getData();
7033        ClipData clip = intent.getClipData();
7034        if (data == null && clip == null) {
7035            return null;
7036        }
7037        // Default userId for uris in the intent (if they don't specify it themselves)
7038        int contentUserHint = intent.getContentUserHint();
7039        if (contentUserHint == UserHandle.USER_CURRENT) {
7040            contentUserHint = UserHandle.getUserId(callingUid);
7041        }
7042        final IPackageManager pm = AppGlobals.getPackageManager();
7043        int targetUid;
7044        if (needed != null) {
7045            targetUid = needed.targetUid;
7046        } else {
7047            try {
7048                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7049            } catch (RemoteException ex) {
7050                return null;
7051            }
7052            if (targetUid < 0) {
7053                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7054                        "Can't grant URI permission no uid for: " + targetPkg
7055                        + " on user " + targetUserId);
7056                return null;
7057            }
7058        }
7059        if (data != null) {
7060            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7061            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7062                    targetUid);
7063            if (targetUid > 0) {
7064                if (needed == null) {
7065                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7066                }
7067                needed.add(grantUri);
7068            }
7069        }
7070        if (clip != null) {
7071            for (int i=0; i<clip.getItemCount(); i++) {
7072                Uri uri = clip.getItemAt(i).getUri();
7073                if (uri != null) {
7074                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7075                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7076                            targetUid);
7077                    if (targetUid > 0) {
7078                        if (needed == null) {
7079                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7080                        }
7081                        needed.add(grantUri);
7082                    }
7083                } else {
7084                    Intent clipIntent = clip.getItemAt(i).getIntent();
7085                    if (clipIntent != null) {
7086                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7087                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7088                        if (newNeeded != null) {
7089                            needed = newNeeded;
7090                        }
7091                    }
7092                }
7093            }
7094        }
7095
7096        return needed;
7097    }
7098
7099    /**
7100     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7101     */
7102    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7103            UriPermissionOwner owner) {
7104        if (needed != null) {
7105            for (int i=0; i<needed.size(); i++) {
7106                GrantUri grantUri = needed.get(i);
7107                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7108                        grantUri, needed.flags, owner);
7109            }
7110        }
7111    }
7112
7113    void grantUriPermissionFromIntentLocked(int callingUid,
7114            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7115        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7116                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7117        if (needed == null) {
7118            return;
7119        }
7120
7121        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7122    }
7123
7124    /**
7125     * @param uri This uri must NOT contain an embedded userId.
7126     * @param userId The userId in which the uri is to be resolved.
7127     */
7128    @Override
7129    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7130            final int modeFlags, int userId) {
7131        enforceNotIsolatedCaller("grantUriPermission");
7132        GrantUri grantUri = new GrantUri(userId, uri, false);
7133        synchronized(this) {
7134            final ProcessRecord r = getRecordForAppLocked(caller);
7135            if (r == null) {
7136                throw new SecurityException("Unable to find app for caller "
7137                        + caller
7138                        + " when granting permission to uri " + grantUri);
7139            }
7140            if (targetPkg == null) {
7141                throw new IllegalArgumentException("null target");
7142            }
7143            if (grantUri == null) {
7144                throw new IllegalArgumentException("null uri");
7145            }
7146
7147            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7148                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7149                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7150                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7151
7152            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7153                    UserHandle.getUserId(r.uid));
7154        }
7155    }
7156
7157    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7158        if (perm.modeFlags == 0) {
7159            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7160                    perm.targetUid);
7161            if (perms != null) {
7162                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7163                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7164
7165                perms.remove(perm.uri);
7166                if (perms.isEmpty()) {
7167                    mGrantedUriPermissions.remove(perm.targetUid);
7168                }
7169            }
7170        }
7171    }
7172
7173    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7174        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7175                "Revoking all granted permissions to " + grantUri);
7176
7177        final IPackageManager pm = AppGlobals.getPackageManager();
7178        final String authority = grantUri.uri.getAuthority();
7179        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7180        if (pi == null) {
7181            Slog.w(TAG, "No content provider found for permission revoke: "
7182                    + grantUri.toSafeString());
7183            return;
7184        }
7185
7186        // Does the caller have this permission on the URI?
7187        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7188            // If they don't have direct access to the URI, then revoke any
7189            // ownerless URI permissions that have been granted to them.
7190            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7191            if (perms != null) {
7192                boolean persistChanged = false;
7193                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7194                    final UriPermission perm = it.next();
7195                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7196                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7197                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7198                                "Revoking non-owned " + perm.targetUid
7199                                + " permission to " + perm.uri);
7200                        persistChanged |= perm.revokeModes(
7201                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7202                        if (perm.modeFlags == 0) {
7203                            it.remove();
7204                        }
7205                    }
7206                }
7207                if (perms.isEmpty()) {
7208                    mGrantedUriPermissions.remove(callingUid);
7209                }
7210                if (persistChanged) {
7211                    schedulePersistUriGrants();
7212                }
7213            }
7214            return;
7215        }
7216
7217        boolean persistChanged = false;
7218
7219        // Go through all of the permissions and remove any that match.
7220        int N = mGrantedUriPermissions.size();
7221        for (int i = 0; i < N; i++) {
7222            final int targetUid = mGrantedUriPermissions.keyAt(i);
7223            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7224
7225            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7226                final UriPermission perm = it.next();
7227                if (perm.uri.sourceUserId == grantUri.sourceUserId
7228                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7229                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7230                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7231                    persistChanged |= perm.revokeModes(
7232                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7233                    if (perm.modeFlags == 0) {
7234                        it.remove();
7235                    }
7236                }
7237            }
7238
7239            if (perms.isEmpty()) {
7240                mGrantedUriPermissions.remove(targetUid);
7241                N--;
7242                i--;
7243            }
7244        }
7245
7246        if (persistChanged) {
7247            schedulePersistUriGrants();
7248        }
7249    }
7250
7251    /**
7252     * @param uri This uri must NOT contain an embedded userId.
7253     * @param userId The userId in which the uri is to be resolved.
7254     */
7255    @Override
7256    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7257            int userId) {
7258        enforceNotIsolatedCaller("revokeUriPermission");
7259        synchronized(this) {
7260            final ProcessRecord r = getRecordForAppLocked(caller);
7261            if (r == null) {
7262                throw new SecurityException("Unable to find app for caller "
7263                        + caller
7264                        + " when revoking permission to uri " + uri);
7265            }
7266            if (uri == null) {
7267                Slog.w(TAG, "revokeUriPermission: null uri");
7268                return;
7269            }
7270
7271            if (!Intent.isAccessUriMode(modeFlags)) {
7272                return;
7273            }
7274
7275            final String authority = uri.getAuthority();
7276            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7277            if (pi == null) {
7278                Slog.w(TAG, "No content provider found for permission revoke: "
7279                        + uri.toSafeString());
7280                return;
7281            }
7282
7283            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7284        }
7285    }
7286
7287    /**
7288     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7289     * given package.
7290     *
7291     * @param packageName Package name to match, or {@code null} to apply to all
7292     *            packages.
7293     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7294     *            to all users.
7295     * @param persistable If persistable grants should be removed.
7296     */
7297    private void removeUriPermissionsForPackageLocked(
7298            String packageName, int userHandle, boolean persistable) {
7299        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7300            throw new IllegalArgumentException("Must narrow by either package or user");
7301        }
7302
7303        boolean persistChanged = false;
7304
7305        int N = mGrantedUriPermissions.size();
7306        for (int i = 0; i < N; i++) {
7307            final int targetUid = mGrantedUriPermissions.keyAt(i);
7308            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7309
7310            // Only inspect grants matching user
7311            if (userHandle == UserHandle.USER_ALL
7312                    || userHandle == UserHandle.getUserId(targetUid)) {
7313                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7314                    final UriPermission perm = it.next();
7315
7316                    // Only inspect grants matching package
7317                    if (packageName == null || perm.sourcePkg.equals(packageName)
7318                            || perm.targetPkg.equals(packageName)) {
7319                        persistChanged |= perm.revokeModes(persistable
7320                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7321
7322                        // Only remove when no modes remain; any persisted grants
7323                        // will keep this alive.
7324                        if (perm.modeFlags == 0) {
7325                            it.remove();
7326                        }
7327                    }
7328                }
7329
7330                if (perms.isEmpty()) {
7331                    mGrantedUriPermissions.remove(targetUid);
7332                    N--;
7333                    i--;
7334                }
7335            }
7336        }
7337
7338        if (persistChanged) {
7339            schedulePersistUriGrants();
7340        }
7341    }
7342
7343    @Override
7344    public IBinder newUriPermissionOwner(String name) {
7345        enforceNotIsolatedCaller("newUriPermissionOwner");
7346        synchronized(this) {
7347            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7348            return owner.getExternalTokenLocked();
7349        }
7350    }
7351
7352    /**
7353     * @param uri This uri must NOT contain an embedded userId.
7354     * @param sourceUserId The userId in which the uri is to be resolved.
7355     * @param targetUserId The userId of the app that receives the grant.
7356     */
7357    @Override
7358    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7359            final int modeFlags, int sourceUserId, int targetUserId) {
7360        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7361                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7362        synchronized(this) {
7363            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7364            if (owner == null) {
7365                throw new IllegalArgumentException("Unknown owner: " + token);
7366            }
7367            if (fromUid != Binder.getCallingUid()) {
7368                if (Binder.getCallingUid() != Process.myUid()) {
7369                    // Only system code can grant URI permissions on behalf
7370                    // of other users.
7371                    throw new SecurityException("nice try");
7372                }
7373            }
7374            if (targetPkg == null) {
7375                throw new IllegalArgumentException("null target");
7376            }
7377            if (uri == null) {
7378                throw new IllegalArgumentException("null uri");
7379            }
7380
7381            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7382                    modeFlags, owner, targetUserId);
7383        }
7384    }
7385
7386    /**
7387     * @param uri This uri must NOT contain an embedded userId.
7388     * @param userId The userId in which the uri is to be resolved.
7389     */
7390    @Override
7391    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7392        synchronized(this) {
7393            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7394            if (owner == null) {
7395                throw new IllegalArgumentException("Unknown owner: " + token);
7396            }
7397
7398            if (uri == null) {
7399                owner.removeUriPermissionsLocked(mode);
7400            } else {
7401                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7402            }
7403        }
7404    }
7405
7406    private void schedulePersistUriGrants() {
7407        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7408            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7409                    10 * DateUtils.SECOND_IN_MILLIS);
7410        }
7411    }
7412
7413    private void writeGrantedUriPermissions() {
7414        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7415
7416        // Snapshot permissions so we can persist without lock
7417        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7418        synchronized (this) {
7419            final int size = mGrantedUriPermissions.size();
7420            for (int i = 0; i < size; i++) {
7421                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7422                for (UriPermission perm : perms.values()) {
7423                    if (perm.persistedModeFlags != 0) {
7424                        persist.add(perm.snapshot());
7425                    }
7426                }
7427            }
7428        }
7429
7430        FileOutputStream fos = null;
7431        try {
7432            fos = mGrantFile.startWrite();
7433
7434            XmlSerializer out = new FastXmlSerializer();
7435            out.setOutput(fos, "utf-8");
7436            out.startDocument(null, true);
7437            out.startTag(null, TAG_URI_GRANTS);
7438            for (UriPermission.Snapshot perm : persist) {
7439                out.startTag(null, TAG_URI_GRANT);
7440                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7441                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7442                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7443                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7444                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7445                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7446                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7447                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7448                out.endTag(null, TAG_URI_GRANT);
7449            }
7450            out.endTag(null, TAG_URI_GRANTS);
7451            out.endDocument();
7452
7453            mGrantFile.finishWrite(fos);
7454        } catch (IOException e) {
7455            if (fos != null) {
7456                mGrantFile.failWrite(fos);
7457            }
7458        }
7459    }
7460
7461    private void readGrantedUriPermissionsLocked() {
7462        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7463
7464        final long now = System.currentTimeMillis();
7465
7466        FileInputStream fis = null;
7467        try {
7468            fis = mGrantFile.openRead();
7469            final XmlPullParser in = Xml.newPullParser();
7470            in.setInput(fis, null);
7471
7472            int type;
7473            while ((type = in.next()) != END_DOCUMENT) {
7474                final String tag = in.getName();
7475                if (type == START_TAG) {
7476                    if (TAG_URI_GRANT.equals(tag)) {
7477                        final int sourceUserId;
7478                        final int targetUserId;
7479                        final int userHandle = readIntAttribute(in,
7480                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7481                        if (userHandle != UserHandle.USER_NULL) {
7482                            // For backwards compatibility.
7483                            sourceUserId = userHandle;
7484                            targetUserId = userHandle;
7485                        } else {
7486                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7487                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7488                        }
7489                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7490                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7491                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7492                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7493                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7494                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7495
7496                        // Sanity check that provider still belongs to source package
7497                        final ProviderInfo pi = getProviderInfoLocked(
7498                                uri.getAuthority(), sourceUserId);
7499                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7500                            int targetUid = -1;
7501                            try {
7502                                targetUid = AppGlobals.getPackageManager()
7503                                        .getPackageUid(targetPkg, targetUserId);
7504                            } catch (RemoteException e) {
7505                            }
7506                            if (targetUid != -1) {
7507                                final UriPermission perm = findOrCreateUriPermissionLocked(
7508                                        sourcePkg, targetPkg, targetUid,
7509                                        new GrantUri(sourceUserId, uri, prefix));
7510                                perm.initPersistedModes(modeFlags, createdTime);
7511                            }
7512                        } else {
7513                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7514                                    + " but instead found " + pi);
7515                        }
7516                    }
7517                }
7518            }
7519        } catch (FileNotFoundException e) {
7520            // Missing grants is okay
7521        } catch (IOException e) {
7522            Slog.wtf(TAG, "Failed reading Uri grants", e);
7523        } catch (XmlPullParserException e) {
7524            Slog.wtf(TAG, "Failed reading Uri grants", e);
7525        } finally {
7526            IoUtils.closeQuietly(fis);
7527        }
7528    }
7529
7530    /**
7531     * @param uri This uri must NOT contain an embedded userId.
7532     * @param userId The userId in which the uri is to be resolved.
7533     */
7534    @Override
7535    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7536        enforceNotIsolatedCaller("takePersistableUriPermission");
7537
7538        Preconditions.checkFlagsArgument(modeFlags,
7539                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7540
7541        synchronized (this) {
7542            final int callingUid = Binder.getCallingUid();
7543            boolean persistChanged = false;
7544            GrantUri grantUri = new GrantUri(userId, uri, false);
7545
7546            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7547                    new GrantUri(userId, uri, false));
7548            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7549                    new GrantUri(userId, uri, true));
7550
7551            final boolean exactValid = (exactPerm != null)
7552                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7553            final boolean prefixValid = (prefixPerm != null)
7554                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7555
7556            if (!(exactValid || prefixValid)) {
7557                throw new SecurityException("No persistable permission grants found for UID "
7558                        + callingUid + " and Uri " + grantUri.toSafeString());
7559            }
7560
7561            if (exactValid) {
7562                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7563            }
7564            if (prefixValid) {
7565                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7566            }
7567
7568            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7569
7570            if (persistChanged) {
7571                schedulePersistUriGrants();
7572            }
7573        }
7574    }
7575
7576    /**
7577     * @param uri This uri must NOT contain an embedded userId.
7578     * @param userId The userId in which the uri is to be resolved.
7579     */
7580    @Override
7581    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7582        enforceNotIsolatedCaller("releasePersistableUriPermission");
7583
7584        Preconditions.checkFlagsArgument(modeFlags,
7585                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7586
7587        synchronized (this) {
7588            final int callingUid = Binder.getCallingUid();
7589            boolean persistChanged = false;
7590
7591            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7592                    new GrantUri(userId, uri, false));
7593            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7594                    new GrantUri(userId, uri, true));
7595            if (exactPerm == null && prefixPerm == null) {
7596                throw new SecurityException("No permission grants found for UID " + callingUid
7597                        + " and Uri " + uri.toSafeString());
7598            }
7599
7600            if (exactPerm != null) {
7601                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7602                removeUriPermissionIfNeededLocked(exactPerm);
7603            }
7604            if (prefixPerm != null) {
7605                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7606                removeUriPermissionIfNeededLocked(prefixPerm);
7607            }
7608
7609            if (persistChanged) {
7610                schedulePersistUriGrants();
7611            }
7612        }
7613    }
7614
7615    /**
7616     * Prune any older {@link UriPermission} for the given UID until outstanding
7617     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7618     *
7619     * @return if any mutations occured that require persisting.
7620     */
7621    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7622        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7623        if (perms == null) return false;
7624        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7625
7626        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7627        for (UriPermission perm : perms.values()) {
7628            if (perm.persistedModeFlags != 0) {
7629                persisted.add(perm);
7630            }
7631        }
7632
7633        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7634        if (trimCount <= 0) return false;
7635
7636        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7637        for (int i = 0; i < trimCount; i++) {
7638            final UriPermission perm = persisted.get(i);
7639
7640            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7641                    "Trimming grant created at " + perm.persistedCreateTime);
7642
7643            perm.releasePersistableModes(~0);
7644            removeUriPermissionIfNeededLocked(perm);
7645        }
7646
7647        return true;
7648    }
7649
7650    @Override
7651    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7652            String packageName, boolean incoming) {
7653        enforceNotIsolatedCaller("getPersistedUriPermissions");
7654        Preconditions.checkNotNull(packageName, "packageName");
7655
7656        final int callingUid = Binder.getCallingUid();
7657        final IPackageManager pm = AppGlobals.getPackageManager();
7658        try {
7659            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7660            if (packageUid != callingUid) {
7661                throw new SecurityException(
7662                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7663            }
7664        } catch (RemoteException e) {
7665            throw new SecurityException("Failed to verify package name ownership");
7666        }
7667
7668        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7669        synchronized (this) {
7670            if (incoming) {
7671                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7672                        callingUid);
7673                if (perms == null) {
7674                    Slog.w(TAG, "No permission grants found for " + packageName);
7675                } else {
7676                    for (UriPermission perm : perms.values()) {
7677                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7678                            result.add(perm.buildPersistedPublicApiObject());
7679                        }
7680                    }
7681                }
7682            } else {
7683                final int size = mGrantedUriPermissions.size();
7684                for (int i = 0; i < size; i++) {
7685                    final ArrayMap<GrantUri, UriPermission> perms =
7686                            mGrantedUriPermissions.valueAt(i);
7687                    for (UriPermission perm : perms.values()) {
7688                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7689                            result.add(perm.buildPersistedPublicApiObject());
7690                        }
7691                    }
7692                }
7693            }
7694        }
7695        return new ParceledListSlice<android.content.UriPermission>(result);
7696    }
7697
7698    @Override
7699    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7700        synchronized (this) {
7701            ProcessRecord app =
7702                who != null ? getRecordForAppLocked(who) : null;
7703            if (app == null) return;
7704
7705            Message msg = Message.obtain();
7706            msg.what = WAIT_FOR_DEBUGGER_MSG;
7707            msg.obj = app;
7708            msg.arg1 = waiting ? 1 : 0;
7709            mHandler.sendMessage(msg);
7710        }
7711    }
7712
7713    @Override
7714    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7715        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7716        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7717        outInfo.availMem = Process.getFreeMemory();
7718        outInfo.totalMem = Process.getTotalMemory();
7719        outInfo.threshold = homeAppMem;
7720        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7721        outInfo.hiddenAppThreshold = cachedAppMem;
7722        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7723                ProcessList.SERVICE_ADJ);
7724        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7725                ProcessList.VISIBLE_APP_ADJ);
7726        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7727                ProcessList.FOREGROUND_APP_ADJ);
7728    }
7729
7730    // =========================================================
7731    // TASK MANAGEMENT
7732    // =========================================================
7733
7734    @Override
7735    public List<IAppTask> getAppTasks(String callingPackage) {
7736        int callingUid = Binder.getCallingUid();
7737        long ident = Binder.clearCallingIdentity();
7738
7739        synchronized(this) {
7740            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7741            try {
7742                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
7743
7744                final int N = mRecentTasks.size();
7745                for (int i = 0; i < N; i++) {
7746                    TaskRecord tr = mRecentTasks.get(i);
7747                    // Skip tasks that do not match the caller.  We don't need to verify
7748                    // callingPackage, because we are also limiting to callingUid and know
7749                    // that will limit to the correct security sandbox.
7750                    if (tr.effectiveUid != callingUid) {
7751                        continue;
7752                    }
7753                    Intent intent = tr.getBaseIntent();
7754                    if (intent == null ||
7755                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7756                        continue;
7757                    }
7758                    ActivityManager.RecentTaskInfo taskInfo =
7759                            createRecentTaskInfoFromTaskRecord(tr);
7760                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7761                    list.add(taskImpl);
7762                }
7763            } finally {
7764                Binder.restoreCallingIdentity(ident);
7765            }
7766            return list;
7767        }
7768    }
7769
7770    @Override
7771    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7772        final int callingUid = Binder.getCallingUid();
7773        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7774
7775        synchronized(this) {
7776            if (DEBUG_ALL) Slog.v(
7777                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7778
7779            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
7780                    callingUid);
7781
7782            // TODO: Improve with MRU list from all ActivityStacks.
7783            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7784        }
7785
7786        return list;
7787    }
7788
7789    /**
7790     * Creates a new RecentTaskInfo from a TaskRecord.
7791     */
7792    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7793        // Update the task description to reflect any changes in the task stack
7794        tr.updateTaskDescription();
7795
7796        // Compose the recent task info
7797        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7798        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
7799        rti.persistentId = tr.taskId;
7800        rti.baseIntent = new Intent(tr.getBaseIntent());
7801        rti.origActivity = tr.origActivity;
7802        rti.description = tr.lastDescription;
7803        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7804        rti.userId = tr.userId;
7805        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7806        rti.firstActiveTime = tr.firstActiveTime;
7807        rti.lastActiveTime = tr.lastActiveTime;
7808        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7809        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7810        return rti;
7811    }
7812
7813    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
7814        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
7815                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
7816        if (!allowed) {
7817            if (checkPermission(android.Manifest.permission.GET_TASKS,
7818                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
7819                // Temporary compatibility: some existing apps on the system image may
7820                // still be requesting the old permission and not switched to the new
7821                // one; if so, we'll still allow them full access.  This means we need
7822                // to see if they are holding the old permission and are a system app.
7823                try {
7824                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
7825                        allowed = true;
7826                        Slog.w(TAG, caller + ": caller " + callingUid
7827                                + " is using old GET_TASKS but privileged; allowing");
7828                    }
7829                } catch (RemoteException e) {
7830                }
7831            }
7832        }
7833        if (!allowed) {
7834            Slog.w(TAG, caller + ": caller " + callingUid
7835                    + " does not hold REAL_GET_TASKS; limiting output");
7836        }
7837        return allowed;
7838    }
7839
7840    @Override
7841    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7842        final int callingUid = Binder.getCallingUid();
7843        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7844                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7845
7846        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7847        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7848        synchronized (this) {
7849            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
7850                    callingUid);
7851            final boolean detailed = checkCallingPermission(
7852                    android.Manifest.permission.GET_DETAILED_TASKS)
7853                    == PackageManager.PERMISSION_GRANTED;
7854
7855            final int recentsCount = mRecentTasks.size();
7856            ArrayList<ActivityManager.RecentTaskInfo> res =
7857                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
7858
7859            final Set<Integer> includedUsers;
7860            if (includeProfiles) {
7861                includedUsers = getProfileIdsLocked(userId);
7862            } else {
7863                includedUsers = new HashSet<>();
7864            }
7865            includedUsers.add(Integer.valueOf(userId));
7866
7867            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
7868                TaskRecord tr = mRecentTasks.get(i);
7869                // Only add calling user or related users recent tasks
7870                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
7871                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
7872                    continue;
7873                }
7874
7875                // Return the entry if desired by the caller.  We always return
7876                // the first entry, because callers always expect this to be the
7877                // foreground app.  We may filter others if the caller has
7878                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7879                // we should exclude the entry.
7880
7881                if (i == 0
7882                        || withExcluded
7883                        || (tr.intent == null)
7884                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7885                                == 0)) {
7886                    if (!allowed) {
7887                        // If the caller doesn't have the GET_TASKS permission, then only
7888                        // allow them to see a small subset of tasks -- their own and home.
7889                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
7890                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
7891                            continue;
7892                        }
7893                    }
7894                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
7895                        if (tr.stack != null && tr.stack.isHomeStack()) {
7896                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
7897                                    "Skipping, home stack task: " + tr);
7898                            continue;
7899                        }
7900                    }
7901                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7902                        // Don't include auto remove tasks that are finished or finishing.
7903                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
7904                                "Skipping, auto-remove without activity: " + tr);
7905                        continue;
7906                    }
7907                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
7908                            && !tr.isAvailable) {
7909                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
7910                                "Skipping, unavail real act: " + tr);
7911                        continue;
7912                    }
7913
7914                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7915                    if (!detailed) {
7916                        rti.baseIntent.replaceExtras((Bundle)null);
7917                    }
7918
7919                    res.add(rti);
7920                    maxNum--;
7921                }
7922            }
7923            return res;
7924        }
7925    }
7926
7927    @Override
7928    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7929        synchronized (this) {
7930            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7931                    "getTaskThumbnail()");
7932            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
7933            if (tr != null) {
7934                return tr.getTaskThumbnailLocked();
7935            }
7936        }
7937        return null;
7938    }
7939
7940    @Override
7941    public int addAppTask(IBinder activityToken, Intent intent,
7942            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
7943        final int callingUid = Binder.getCallingUid();
7944        final long callingIdent = Binder.clearCallingIdentity();
7945
7946        try {
7947            synchronized (this) {
7948                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
7949                if (r == null) {
7950                    throw new IllegalArgumentException("Activity does not exist; token="
7951                            + activityToken);
7952                }
7953                ComponentName comp = intent.getComponent();
7954                if (comp == null) {
7955                    throw new IllegalArgumentException("Intent " + intent
7956                            + " must specify explicit component");
7957                }
7958                if (thumbnail.getWidth() != mThumbnailWidth
7959                        || thumbnail.getHeight() != mThumbnailHeight) {
7960                    throw new IllegalArgumentException("Bad thumbnail size: got "
7961                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
7962                            + mThumbnailWidth + "x" + mThumbnailHeight);
7963                }
7964                if (intent.getSelector() != null) {
7965                    intent.setSelector(null);
7966                }
7967                if (intent.getSourceBounds() != null) {
7968                    intent.setSourceBounds(null);
7969                }
7970                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
7971                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
7972                        // The caller has added this as an auto-remove task...  that makes no
7973                        // sense, so turn off auto-remove.
7974                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
7975                    }
7976                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
7977                    // Must be a new task.
7978                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7979                }
7980                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
7981                    mLastAddedTaskActivity = null;
7982                }
7983                ActivityInfo ainfo = mLastAddedTaskActivity;
7984                if (ainfo == null) {
7985                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
7986                            comp, 0, UserHandle.getUserId(callingUid));
7987                    if (ainfo.applicationInfo.uid != callingUid) {
7988                        throw new SecurityException(
7989                                "Can't add task for another application: target uid="
7990                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
7991                    }
7992                }
7993
7994                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
7995                        intent, description);
7996
7997                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
7998                if (trimIdx >= 0) {
7999                    // If this would have caused a trim, then we'll abort because that
8000                    // means it would be added at the end of the list but then just removed.
8001                    return INVALID_TASK_ID;
8002                }
8003
8004                final int N = mRecentTasks.size();
8005                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8006                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8007                    tr.removedFromRecents();
8008                }
8009
8010                task.inRecents = true;
8011                mRecentTasks.add(task);
8012                r.task.stack.addTask(task, false, false);
8013
8014                task.setLastThumbnail(thumbnail);
8015                task.freeLastThumbnail();
8016
8017                return task.taskId;
8018            }
8019        } finally {
8020            Binder.restoreCallingIdentity(callingIdent);
8021        }
8022    }
8023
8024    @Override
8025    public Point getAppTaskThumbnailSize() {
8026        synchronized (this) {
8027            return new Point(mThumbnailWidth,  mThumbnailHeight);
8028        }
8029    }
8030
8031    @Override
8032    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8033        synchronized (this) {
8034            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8035            if (r != null) {
8036                r.setTaskDescription(td);
8037                r.task.updateTaskDescription();
8038            }
8039        }
8040    }
8041
8042    @Override
8043    public void setTaskResizeable(int taskId, boolean resizeable) {
8044        synchronized (this) {
8045            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8046            if (task == null) {
8047                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8048                return;
8049            }
8050            if (task.mResizeable != resizeable) {
8051                task.mResizeable = resizeable;
8052                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8053                mStackSupervisor.resumeTopActivitiesLocked();
8054            }
8055        }
8056    }
8057
8058    @Override
8059    public void resizeTask(int taskId, Rect bounds) {
8060        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8061                "resizeTask()");
8062        long ident = Binder.clearCallingIdentity();
8063        try {
8064            synchronized (this) {
8065                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8066                if (task == null) {
8067                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8068                    return;
8069                }
8070                mStackSupervisor.resizeTaskLocked(task, bounds);
8071            }
8072        } finally {
8073            Binder.restoreCallingIdentity(ident);
8074        }
8075    }
8076
8077    @Override
8078    public Bitmap getTaskDescriptionIcon(String filename) {
8079        if (!FileUtils.isValidExtFilename(filename)
8080                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8081            throw new IllegalArgumentException("Bad filename: " + filename);
8082        }
8083        return mTaskPersister.getTaskDescriptionIcon(filename);
8084    }
8085
8086    @Override
8087    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8088            throws RemoteException {
8089        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8090                opts.getCustomInPlaceResId() == 0) {
8091            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8092                    "with valid animation");
8093        }
8094        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8095        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8096                opts.getCustomInPlaceResId());
8097        mWindowManager.executeAppTransition();
8098    }
8099
8100    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8101        mRecentTasks.remove(tr);
8102        tr.removedFromRecents();
8103        ComponentName component = tr.getBaseIntent().getComponent();
8104        if (component == null) {
8105            Slog.w(TAG, "No component for base intent of task: " + tr);
8106            return;
8107        }
8108
8109        if (!killProcess) {
8110            return;
8111        }
8112
8113        // Determine if the process(es) for this task should be killed.
8114        final String pkg = component.getPackageName();
8115        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8116        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8117        for (int i = 0; i < pmap.size(); i++) {
8118
8119            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8120            for (int j = 0; j < uids.size(); j++) {
8121                ProcessRecord proc = uids.valueAt(j);
8122                if (proc.userId != tr.userId) {
8123                    // Don't kill process for a different user.
8124                    continue;
8125                }
8126                if (proc == mHomeProcess) {
8127                    // Don't kill the home process along with tasks from the same package.
8128                    continue;
8129                }
8130                if (!proc.pkgList.containsKey(pkg)) {
8131                    // Don't kill process that is not associated with this task.
8132                    continue;
8133                }
8134
8135                for (int k = 0; k < proc.activities.size(); k++) {
8136                    TaskRecord otherTask = proc.activities.get(k).task;
8137                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8138                        // Don't kill process(es) that has an activity in a different task that is
8139                        // also in recents.
8140                        return;
8141                    }
8142                }
8143
8144                // Add process to kill list.
8145                procsToKill.add(proc);
8146            }
8147        }
8148
8149        // Find any running services associated with this app and stop if needed.
8150        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8151
8152        // Kill the running processes.
8153        for (int i = 0; i < procsToKill.size(); i++) {
8154            ProcessRecord pr = procsToKill.get(i);
8155            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8156                pr.kill("remove task", true);
8157            } else {
8158                pr.waitingToKill = "remove task";
8159            }
8160        }
8161    }
8162
8163    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8164        // Remove all tasks with activities in the specified package from the list of recent tasks
8165        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8166            TaskRecord tr = mRecentTasks.get(i);
8167            if (tr.userId != userId) continue;
8168
8169            ComponentName cn = tr.intent.getComponent();
8170            if (cn != null && cn.getPackageName().equals(packageName)) {
8171                // If the package name matches, remove the task.
8172                removeTaskByIdLocked(tr.taskId, true);
8173            }
8174        }
8175    }
8176
8177    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8178        final IPackageManager pm = AppGlobals.getPackageManager();
8179        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8180
8181        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8182            TaskRecord tr = mRecentTasks.get(i);
8183            if (tr.userId != userId) continue;
8184
8185            ComponentName cn = tr.intent.getComponent();
8186            if (cn != null && cn.getPackageName().equals(packageName)) {
8187                // Skip if component still exists in the package.
8188                if (componentsKnownToExist.contains(cn)) continue;
8189
8190                try {
8191                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8192                    if (info != null) {
8193                        componentsKnownToExist.add(cn);
8194                    } else {
8195                        removeTaskByIdLocked(tr.taskId, false);
8196                    }
8197                } catch (RemoteException e) {
8198                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8199                }
8200            }
8201        }
8202    }
8203
8204    /**
8205     * Removes the task with the specified task id.
8206     *
8207     * @param taskId Identifier of the task to be removed.
8208     * @param killProcess Kill any process associated with the task if possible.
8209     * @return Returns true if the given task was found and removed.
8210     */
8211    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8212        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8213        if (tr != null) {
8214            tr.removeTaskActivitiesLocked();
8215            cleanUpRemovedTaskLocked(tr, killProcess);
8216            if (tr.isPersistable) {
8217                notifyTaskPersisterLocked(null, true);
8218            }
8219            return true;
8220        }
8221        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8222        return false;
8223    }
8224
8225    @Override
8226    public boolean removeTask(int taskId) {
8227        synchronized (this) {
8228            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8229                    "removeTask()");
8230            long ident = Binder.clearCallingIdentity();
8231            try {
8232                return removeTaskByIdLocked(taskId, true);
8233            } finally {
8234                Binder.restoreCallingIdentity(ident);
8235            }
8236        }
8237    }
8238
8239    /**
8240     * TODO: Add mController hook
8241     */
8242    @Override
8243    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8244        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8245
8246        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8247        synchronized(this) {
8248            moveTaskToFrontLocked(taskId, flags, options);
8249        }
8250    }
8251
8252    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8253        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8254                Binder.getCallingUid(), -1, -1, "Task to front")) {
8255            ActivityOptions.abort(options);
8256            return;
8257        }
8258        final long origId = Binder.clearCallingIdentity();
8259        try {
8260            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8261            if (task == null) {
8262                Slog.d(TAG, "Could not find task for id: "+ taskId);
8263                return;
8264            }
8265            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8266                mStackSupervisor.showLockTaskToast();
8267                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8268                return;
8269            }
8270            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8271            if (prev != null && prev.isRecentsActivity()) {
8272                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8273            }
8274            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8275        } finally {
8276            Binder.restoreCallingIdentity(origId);
8277        }
8278        ActivityOptions.abort(options);
8279    }
8280
8281    /**
8282     * Moves an activity, and all of the other activities within the same task, to the bottom
8283     * of the history stack.  The activity's order within the task is unchanged.
8284     *
8285     * @param token A reference to the activity we wish to move
8286     * @param nonRoot If false then this only works if the activity is the root
8287     *                of a task; if true it will work for any activity in a task.
8288     * @return Returns true if the move completed, false if not.
8289     */
8290    @Override
8291    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8292        enforceNotIsolatedCaller("moveActivityTaskToBack");
8293        synchronized(this) {
8294            final long origId = Binder.clearCallingIdentity();
8295            try {
8296                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8297                if (taskId >= 0) {
8298                    if ((mStackSupervisor.mLockTaskModeTask != null)
8299                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8300                        mStackSupervisor.showLockTaskToast();
8301                        return false;
8302                    }
8303                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8304                }
8305            } finally {
8306                Binder.restoreCallingIdentity(origId);
8307            }
8308        }
8309        return false;
8310    }
8311
8312    @Override
8313    public void moveTaskBackwards(int task) {
8314        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8315                "moveTaskBackwards()");
8316
8317        synchronized(this) {
8318            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8319                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8320                return;
8321            }
8322            final long origId = Binder.clearCallingIdentity();
8323            moveTaskBackwardsLocked(task);
8324            Binder.restoreCallingIdentity(origId);
8325        }
8326    }
8327
8328    private final void moveTaskBackwardsLocked(int task) {
8329        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8330    }
8331
8332    @Override
8333    public IBinder getHomeActivityToken() throws RemoteException {
8334        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8335                "getHomeActivityToken()");
8336        synchronized (this) {
8337            return mStackSupervisor.getHomeActivityToken();
8338        }
8339    }
8340
8341    @Override
8342    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8343            IActivityContainerCallback callback) throws RemoteException {
8344        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8345                "createActivityContainer()");
8346        synchronized (this) {
8347            if (parentActivityToken == null) {
8348                throw new IllegalArgumentException("parent token must not be null");
8349            }
8350            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8351            if (r == null) {
8352                return null;
8353            }
8354            if (callback == null) {
8355                throw new IllegalArgumentException("callback must not be null");
8356            }
8357            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8358        }
8359    }
8360
8361    @Override
8362    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8363        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8364                "deleteActivityContainer()");
8365        synchronized (this) {
8366            mStackSupervisor.deleteActivityContainer(container);
8367        }
8368    }
8369
8370    @Override
8371    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8372        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8373                "createStackOnDisplay()");
8374        synchronized (this) {
8375            final int stackId = mStackSupervisor.getNextStackId();
8376            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8377            if (stack == null) {
8378                return null;
8379            }
8380            return stack.mActivityContainer;
8381        }
8382    }
8383
8384    @Override
8385    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8386        synchronized (this) {
8387            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8388            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8389                return stack.mActivityContainer.getDisplayId();
8390            }
8391            return Display.DEFAULT_DISPLAY;
8392        }
8393    }
8394
8395    @Override
8396    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8397        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8398                "moveTaskToStack()");
8399        if (stackId == HOME_STACK_ID) {
8400            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8401                    new RuntimeException("here").fillInStackTrace());
8402        }
8403        synchronized (this) {
8404            long ident = Binder.clearCallingIdentity();
8405            try {
8406                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8407                        + " to stackId=" + stackId + " toTop=" + toTop);
8408                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8409            } finally {
8410                Binder.restoreCallingIdentity(ident);
8411            }
8412        }
8413    }
8414
8415    @Override
8416    public void resizeStack(int stackId, Rect bounds) {
8417        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8418                "resizeStack()");
8419        long ident = Binder.clearCallingIdentity();
8420        try {
8421            synchronized (this) {
8422                mStackSupervisor.resizeStackLocked(stackId, bounds);
8423            }
8424        } finally {
8425            Binder.restoreCallingIdentity(ident);
8426        }
8427    }
8428
8429    @Override
8430    public List<StackInfo> getAllStackInfos() {
8431        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8432                "getAllStackInfos()");
8433        long ident = Binder.clearCallingIdentity();
8434        try {
8435            synchronized (this) {
8436                return mStackSupervisor.getAllStackInfosLocked();
8437            }
8438        } finally {
8439            Binder.restoreCallingIdentity(ident);
8440        }
8441    }
8442
8443    @Override
8444    public StackInfo getStackInfo(int stackId) {
8445        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8446                "getStackInfo()");
8447        long ident = Binder.clearCallingIdentity();
8448        try {
8449            synchronized (this) {
8450                return mStackSupervisor.getStackInfoLocked(stackId);
8451            }
8452        } finally {
8453            Binder.restoreCallingIdentity(ident);
8454        }
8455    }
8456
8457    @Override
8458    public boolean isInHomeStack(int taskId) {
8459        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8460                "getStackInfo()");
8461        long ident = Binder.clearCallingIdentity();
8462        try {
8463            synchronized (this) {
8464                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8465                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8466            }
8467        } finally {
8468            Binder.restoreCallingIdentity(ident);
8469        }
8470    }
8471
8472    @Override
8473    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8474        synchronized(this) {
8475            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8476        }
8477    }
8478
8479    @Override
8480    public void updateLockTaskPackages(int userId, String[] packages) {
8481        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8482            throw new SecurityException("updateLockTaskPackage called from non-system process");
8483        }
8484        synchronized (this) {
8485            mLockTaskPackages.put(userId, packages);
8486        }
8487    }
8488
8489    private boolean isLockTaskAuthorizedLocked(String pkg) {
8490        String[] packages = mLockTaskPackages.get(mCurrentUserId);
8491        if (packages == null) {
8492            return false;
8493        }
8494        for (int i = packages.length - 1; i >= 0; --i) {
8495            if (pkg.equals(packages[i])) {
8496                return true;
8497            }
8498        }
8499        return false;
8500    }
8501
8502    void startLockTaskModeLocked(TaskRecord task) {
8503        final String pkg = task.intent.getComponent().getPackageName();
8504        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
8505        // is initiated by system after the pinning request was shown and locked mode is initiated
8506        // by an authorized app directly
8507        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8508        long ident = Binder.clearCallingIdentity();
8509        try {
8510            if (!isSystemInitiated && !isLockTaskAuthorizedLocked(pkg)) {
8511                StatusBarManagerInternal statusBarManager =
8512                        LocalServices.getService(StatusBarManagerInternal.class);
8513                if (statusBarManager != null) {
8514                    statusBarManager.showScreenPinningRequest();
8515                }
8516                return;
8517            }
8518
8519            final ActivityStack stack = mStackSupervisor.getFocusedStack();
8520            if (!isSystemInitiated && (stack == null || task != stack.topTask())) {
8521                throw new IllegalArgumentException("Invalid task, not in foreground");
8522            }
8523            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
8524                    ActivityManager.LOCK_TASK_MODE_PINNED :
8525                    ActivityManager.LOCK_TASK_MODE_LOCKED,
8526                    "startLockTask");
8527        } finally {
8528            Binder.restoreCallingIdentity(ident);
8529        }
8530    }
8531
8532    @Override
8533    public void startLockTaskMode(int taskId) {
8534        synchronized (this) {
8535            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8536            if (task != null) {
8537                startLockTaskModeLocked(task);
8538            }
8539        }
8540    }
8541
8542    @Override
8543    public void startLockTaskMode(IBinder token) {
8544        synchronized (this) {
8545            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8546            if (r == null) {
8547                return;
8548            }
8549            final TaskRecord task = r.task;
8550            if (task != null) {
8551                startLockTaskModeLocked(task);
8552            }
8553        }
8554    }
8555
8556    @Override
8557    public void startLockTaskModeOnCurrent() throws RemoteException {
8558        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8559                "startLockTaskModeOnCurrent");
8560        long ident = Binder.clearCallingIdentity();
8561        try {
8562            synchronized (this) {
8563                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
8564                if (r != null) {
8565                    startLockTaskModeLocked(r.task);
8566                }
8567            }
8568        } finally {
8569            Binder.restoreCallingIdentity(ident);
8570        }
8571    }
8572
8573    @Override
8574    public void stopLockTaskMode() {
8575        // Verify that the user matches the package of the intent for the TaskRecord
8576        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8577        // and stopLockTaskMode.
8578        final int callingUid = Binder.getCallingUid();
8579        if (callingUid != Process.SYSTEM_UID) {
8580            try {
8581                String pkg =
8582                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8583                int uid = mContext.getPackageManager().getPackageUid(pkg,
8584                        Binder.getCallingUserHandle().getIdentifier());
8585                if (uid != callingUid) {
8586                    throw new SecurityException("Invalid uid, expected " + uid);
8587                }
8588            } catch (NameNotFoundException e) {
8589                Log.d(TAG, "stopLockTaskMode " + e);
8590                return;
8591            }
8592        }
8593        long ident = Binder.clearCallingIdentity();
8594        try {
8595            Log.d(TAG, "stopLockTaskMode");
8596            // Stop lock task
8597            synchronized (this) {
8598                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
8599                        "stopLockTask");
8600            }
8601        } finally {
8602            Binder.restoreCallingIdentity(ident);
8603        }
8604    }
8605
8606    @Override
8607    public void stopLockTaskModeOnCurrent() throws RemoteException {
8608        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8609                "stopLockTaskModeOnCurrent");
8610        long ident = Binder.clearCallingIdentity();
8611        try {
8612            stopLockTaskMode();
8613        } finally {
8614            Binder.restoreCallingIdentity(ident);
8615        }
8616    }
8617
8618    @Override
8619    public boolean isInLockTaskMode() {
8620        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
8621    }
8622
8623    @Override
8624    public int getLockTaskModeState() {
8625        synchronized (this) {
8626            return mStackSupervisor.getLockTaskModeState();
8627        }
8628    }
8629
8630    // =========================================================
8631    // CONTENT PROVIDERS
8632    // =========================================================
8633
8634    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8635        List<ProviderInfo> providers = null;
8636        try {
8637            providers = AppGlobals.getPackageManager().
8638                queryContentProviders(app.processName, app.uid,
8639                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8640        } catch (RemoteException ex) {
8641        }
8642        if (DEBUG_MU) Slog.v(TAG_MU,
8643                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8644        int userId = app.userId;
8645        if (providers != null) {
8646            int N = providers.size();
8647            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8648            for (int i=0; i<N; i++) {
8649                ProviderInfo cpi =
8650                    (ProviderInfo)providers.get(i);
8651                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8652                        cpi.name, cpi.flags);
8653                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
8654                    // This is a singleton provider, but a user besides the
8655                    // default user is asking to initialize a process it runs
8656                    // in...  well, no, it doesn't actually run in this process,
8657                    // it runs in the process of the default user.  Get rid of it.
8658                    providers.remove(i);
8659                    N--;
8660                    i--;
8661                    continue;
8662                }
8663
8664                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8665                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8666                if (cpr == null) {
8667                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8668                    mProviderMap.putProviderByClass(comp, cpr);
8669                }
8670                if (DEBUG_MU) Slog.v(TAG_MU,
8671                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8672                app.pubProviders.put(cpi.name, cpr);
8673                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8674                    // Don't add this if it is a platform component that is marked
8675                    // to run in multiple processes, because this is actually
8676                    // part of the framework so doesn't make sense to track as a
8677                    // separate apk in the process.
8678                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8679                            mProcessStats);
8680                }
8681                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8682            }
8683        }
8684        return providers;
8685    }
8686
8687    /**
8688     * Check if {@link ProcessRecord} has a possible chance at accessing the
8689     * given {@link ProviderInfo}. Final permission checking is always done
8690     * in {@link ContentProvider}.
8691     */
8692    private final String checkContentProviderPermissionLocked(
8693            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8694        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8695        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8696        boolean checkedGrants = false;
8697        if (checkUser) {
8698            // Looking for cross-user grants before enforcing the typical cross-users permissions
8699            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8700            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8701                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8702                    return null;
8703                }
8704                checkedGrants = true;
8705            }
8706            userId = handleIncomingUser(callingPid, callingUid, userId,
8707                    false, ALLOW_NON_FULL,
8708                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8709            if (userId != tmpTargetUserId) {
8710                // When we actually went to determine the final targer user ID, this ended
8711                // up different than our initial check for the authority.  This is because
8712                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8713                // SELF.  So we need to re-check the grants again.
8714                checkedGrants = false;
8715            }
8716        }
8717        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8718                cpi.applicationInfo.uid, cpi.exported)
8719                == PackageManager.PERMISSION_GRANTED) {
8720            return null;
8721        }
8722        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8723                cpi.applicationInfo.uid, cpi.exported)
8724                == PackageManager.PERMISSION_GRANTED) {
8725            return null;
8726        }
8727
8728        PathPermission[] pps = cpi.pathPermissions;
8729        if (pps != null) {
8730            int i = pps.length;
8731            while (i > 0) {
8732                i--;
8733                PathPermission pp = pps[i];
8734                String pprperm = pp.getReadPermission();
8735                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8736                        cpi.applicationInfo.uid, cpi.exported)
8737                        == PackageManager.PERMISSION_GRANTED) {
8738                    return null;
8739                }
8740                String ppwperm = pp.getWritePermission();
8741                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8742                        cpi.applicationInfo.uid, cpi.exported)
8743                        == PackageManager.PERMISSION_GRANTED) {
8744                    return null;
8745                }
8746            }
8747        }
8748        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8749            return null;
8750        }
8751
8752        String msg;
8753        if (!cpi.exported) {
8754            msg = "Permission Denial: opening provider " + cpi.name
8755                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8756                    + ", uid=" + callingUid + ") that is not exported from uid "
8757                    + cpi.applicationInfo.uid;
8758        } else {
8759            msg = "Permission Denial: opening provider " + cpi.name
8760                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8761                    + ", uid=" + callingUid + ") requires "
8762                    + cpi.readPermission + " or " + cpi.writePermission;
8763        }
8764        Slog.w(TAG, msg);
8765        return msg;
8766    }
8767
8768    /**
8769     * Returns if the ContentProvider has granted a uri to callingUid
8770     */
8771    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8772        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8773        if (perms != null) {
8774            for (int i=perms.size()-1; i>=0; i--) {
8775                GrantUri grantUri = perms.keyAt(i);
8776                if (grantUri.sourceUserId == userId || !checkUser) {
8777                    if (matchesProvider(grantUri.uri, cpi)) {
8778                        return true;
8779                    }
8780                }
8781            }
8782        }
8783        return false;
8784    }
8785
8786    /**
8787     * Returns true if the uri authority is one of the authorities specified in the provider.
8788     */
8789    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8790        String uriAuth = uri.getAuthority();
8791        String cpiAuth = cpi.authority;
8792        if (cpiAuth.indexOf(';') == -1) {
8793            return cpiAuth.equals(uriAuth);
8794        }
8795        String[] cpiAuths = cpiAuth.split(";");
8796        int length = cpiAuths.length;
8797        for (int i = 0; i < length; i++) {
8798            if (cpiAuths[i].equals(uriAuth)) return true;
8799        }
8800        return false;
8801    }
8802
8803    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8804            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8805        if (r != null) {
8806            for (int i=0; i<r.conProviders.size(); i++) {
8807                ContentProviderConnection conn = r.conProviders.get(i);
8808                if (conn.provider == cpr) {
8809                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
8810                            "Adding provider requested by "
8811                            + r.processName + " from process "
8812                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8813                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8814                    if (stable) {
8815                        conn.stableCount++;
8816                        conn.numStableIncs++;
8817                    } else {
8818                        conn.unstableCount++;
8819                        conn.numUnstableIncs++;
8820                    }
8821                    return conn;
8822                }
8823            }
8824            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8825            if (stable) {
8826                conn.stableCount = 1;
8827                conn.numStableIncs = 1;
8828            } else {
8829                conn.unstableCount = 1;
8830                conn.numUnstableIncs = 1;
8831            }
8832            cpr.connections.add(conn);
8833            r.conProviders.add(conn);
8834            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
8835            return conn;
8836        }
8837        cpr.addExternalProcessHandleLocked(externalProcessToken);
8838        return null;
8839    }
8840
8841    boolean decProviderCountLocked(ContentProviderConnection conn,
8842            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8843        if (conn != null) {
8844            cpr = conn.provider;
8845            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
8846                    "Removing provider requested by "
8847                    + conn.client.processName + " from process "
8848                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8849                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8850            if (stable) {
8851                conn.stableCount--;
8852            } else {
8853                conn.unstableCount--;
8854            }
8855            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8856                cpr.connections.remove(conn);
8857                conn.client.conProviders.remove(conn);
8858                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
8859                return true;
8860            }
8861            return false;
8862        }
8863        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8864        return false;
8865    }
8866
8867    private void checkTime(long startTime, String where) {
8868        long now = SystemClock.elapsedRealtime();
8869        if ((now-startTime) > 1000) {
8870            // If we are taking more than a second, log about it.
8871            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
8872        }
8873    }
8874
8875    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8876            String name, IBinder token, boolean stable, int userId) {
8877        ContentProviderRecord cpr;
8878        ContentProviderConnection conn = null;
8879        ProviderInfo cpi = null;
8880
8881        synchronized(this) {
8882            long startTime = SystemClock.elapsedRealtime();
8883
8884            ProcessRecord r = null;
8885            if (caller != null) {
8886                r = getRecordForAppLocked(caller);
8887                if (r == null) {
8888                    throw new SecurityException(
8889                            "Unable to find app for caller " + caller
8890                          + " (pid=" + Binder.getCallingPid()
8891                          + ") when getting content provider " + name);
8892                }
8893            }
8894
8895            boolean checkCrossUser = true;
8896
8897            checkTime(startTime, "getContentProviderImpl: getProviderByName");
8898
8899            // First check if this content provider has been published...
8900            cpr = mProviderMap.getProviderByName(name, userId);
8901            // If that didn't work, check if it exists for user 0 and then
8902            // verify that it's a singleton provider before using it.
8903            if (cpr == null && userId != UserHandle.USER_OWNER) {
8904                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8905                if (cpr != null) {
8906                    cpi = cpr.info;
8907                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8908                            cpi.name, cpi.flags)
8909                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8910                        userId = UserHandle.USER_OWNER;
8911                        checkCrossUser = false;
8912                    } else {
8913                        cpr = null;
8914                        cpi = null;
8915                    }
8916                }
8917            }
8918
8919            boolean providerRunning = cpr != null;
8920            if (providerRunning) {
8921                cpi = cpr.info;
8922                String msg;
8923                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
8924                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8925                        != null) {
8926                    throw new SecurityException(msg);
8927                }
8928                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
8929
8930                if (r != null && cpr.canRunHere(r)) {
8931                    // This provider has been published or is in the process
8932                    // of being published...  but it is also allowed to run
8933                    // in the caller's process, so don't make a connection
8934                    // and just let the caller instantiate its own instance.
8935                    ContentProviderHolder holder = cpr.newHolder(null);
8936                    // don't give caller the provider object, it needs
8937                    // to make its own.
8938                    holder.provider = null;
8939                    return holder;
8940                }
8941
8942                final long origId = Binder.clearCallingIdentity();
8943
8944                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
8945
8946                // In this case the provider instance already exists, so we can
8947                // return it right away.
8948                conn = incProviderCountLocked(r, cpr, token, stable);
8949                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8950                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8951                        // If this is a perceptible app accessing the provider,
8952                        // make sure to count it as being accessed and thus
8953                        // back up on the LRU list.  This is good because
8954                        // content providers are often expensive to start.
8955                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
8956                        updateLruProcessLocked(cpr.proc, false, null);
8957                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
8958                    }
8959                }
8960
8961                if (cpr.proc != null) {
8962                    if (false) {
8963                        if (cpr.name.flattenToShortString().equals(
8964                                "com.android.providers.calendar/.CalendarProvider2")) {
8965                            Slog.v(TAG, "****************** KILLING "
8966                                + cpr.name.flattenToShortString());
8967                            Process.killProcess(cpr.proc.pid);
8968                        }
8969                    }
8970                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
8971                    boolean success = updateOomAdjLocked(cpr.proc);
8972                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
8973                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
8974                    // NOTE: there is still a race here where a signal could be
8975                    // pending on the process even though we managed to update its
8976                    // adj level.  Not sure what to do about this, but at least
8977                    // the race is now smaller.
8978                    if (!success) {
8979                        // Uh oh...  it looks like the provider's process
8980                        // has been killed on us.  We need to wait for a new
8981                        // process to be started, and make sure its death
8982                        // doesn't kill our process.
8983                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
8984                                + " is crashing; detaching " + r);
8985                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8986                        checkTime(startTime, "getContentProviderImpl: before appDied");
8987                        appDiedLocked(cpr.proc);
8988                        checkTime(startTime, "getContentProviderImpl: after appDied");
8989                        if (!lastRef) {
8990                            // This wasn't the last ref our process had on
8991                            // the provider...  we have now been killed, bail.
8992                            return null;
8993                        }
8994                        providerRunning = false;
8995                        conn = null;
8996                    }
8997                }
8998
8999                Binder.restoreCallingIdentity(origId);
9000            }
9001
9002            boolean singleton;
9003            if (!providerRunning) {
9004                try {
9005                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9006                    cpi = AppGlobals.getPackageManager().
9007                        resolveContentProvider(name,
9008                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9009                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9010                } catch (RemoteException ex) {
9011                }
9012                if (cpi == null) {
9013                    return null;
9014                }
9015                // If the provider is a singleton AND
9016                // (it's a call within the same user || the provider is a
9017                // privileged app)
9018                // Then allow connecting to the singleton provider
9019                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9020                        cpi.name, cpi.flags)
9021                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9022                if (singleton) {
9023                    userId = UserHandle.USER_OWNER;
9024                }
9025                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9026                checkTime(startTime, "getContentProviderImpl: got app info for user");
9027
9028                String msg;
9029                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9030                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9031                        != null) {
9032                    throw new SecurityException(msg);
9033                }
9034                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9035
9036                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9037                        && !cpi.processName.equals("system")) {
9038                    // If this content provider does not run in the system
9039                    // process, and the system is not yet ready to run other
9040                    // processes, then fail fast instead of hanging.
9041                    throw new IllegalArgumentException(
9042                            "Attempt to launch content provider before system ready");
9043                }
9044
9045                // Make sure that the user who owns this provider is running.  If not,
9046                // we don't want to allow it to run.
9047                if (!isUserRunningLocked(userId, false)) {
9048                    Slog.w(TAG, "Unable to launch app "
9049                            + cpi.applicationInfo.packageName + "/"
9050                            + cpi.applicationInfo.uid + " for provider "
9051                            + name + ": user " + userId + " is stopped");
9052                    return null;
9053                }
9054
9055                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9056                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9057                cpr = mProviderMap.getProviderByClass(comp, userId);
9058                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9059                final boolean firstClass = cpr == null;
9060                if (firstClass) {
9061                    final long ident = Binder.clearCallingIdentity();
9062                    try {
9063                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9064                        ApplicationInfo ai =
9065                            AppGlobals.getPackageManager().
9066                                getApplicationInfo(
9067                                        cpi.applicationInfo.packageName,
9068                                        STOCK_PM_FLAGS, userId);
9069                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9070                        if (ai == null) {
9071                            Slog.w(TAG, "No package info for content provider "
9072                                    + cpi.name);
9073                            return null;
9074                        }
9075                        ai = getAppInfoForUser(ai, userId);
9076                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9077                    } catch (RemoteException ex) {
9078                        // pm is in same process, this will never happen.
9079                    } finally {
9080                        Binder.restoreCallingIdentity(ident);
9081                    }
9082                }
9083
9084                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9085
9086                if (r != null && cpr.canRunHere(r)) {
9087                    // If this is a multiprocess provider, then just return its
9088                    // info and allow the caller to instantiate it.  Only do
9089                    // this if the provider is the same user as the caller's
9090                    // process, or can run as root (so can be in any process).
9091                    return cpr.newHolder(null);
9092                }
9093
9094                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9095                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9096                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9097
9098                // This is single process, and our app is now connecting to it.
9099                // See if we are already in the process of launching this
9100                // provider.
9101                final int N = mLaunchingProviders.size();
9102                int i;
9103                for (i = 0; i < N; i++) {
9104                    if (mLaunchingProviders.get(i) == cpr) {
9105                        break;
9106                    }
9107                }
9108
9109                // If the provider is not already being launched, then get it
9110                // started.
9111                if (i >= N) {
9112                    final long origId = Binder.clearCallingIdentity();
9113
9114                    try {
9115                        // Content provider is now in use, its package can't be stopped.
9116                        try {
9117                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9118                            AppGlobals.getPackageManager().setPackageStoppedState(
9119                                    cpr.appInfo.packageName, false, userId);
9120                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9121                        } catch (RemoteException e) {
9122                        } catch (IllegalArgumentException e) {
9123                            Slog.w(TAG, "Failed trying to unstop package "
9124                                    + cpr.appInfo.packageName + ": " + e);
9125                        }
9126
9127                        // Use existing process if already started
9128                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9129                        ProcessRecord proc = getProcessRecordLocked(
9130                                cpi.processName, cpr.appInfo.uid, false);
9131                        if (proc != null && proc.thread != null) {
9132                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9133                                    "Installing in existing process " + proc);
9134                            if (!proc.pubProviders.containsKey(cpi.name)) {
9135                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9136                                proc.pubProviders.put(cpi.name, cpr);
9137                                try {
9138                                    proc.thread.scheduleInstallProvider(cpi);
9139                                } catch (RemoteException e) {
9140                                }
9141                            }
9142                        } else {
9143                            checkTime(startTime, "getContentProviderImpl: before start process");
9144                            proc = startProcessLocked(cpi.processName,
9145                                    cpr.appInfo, false, 0, "content provider",
9146                                    new ComponentName(cpi.applicationInfo.packageName,
9147                                            cpi.name), false, false, false);
9148                            checkTime(startTime, "getContentProviderImpl: after start process");
9149                            if (proc == null) {
9150                                Slog.w(TAG, "Unable to launch app "
9151                                        + cpi.applicationInfo.packageName + "/"
9152                                        + cpi.applicationInfo.uid + " for provider "
9153                                        + name + ": process is bad");
9154                                return null;
9155                            }
9156                        }
9157                        cpr.launchingApp = proc;
9158                        mLaunchingProviders.add(cpr);
9159                    } finally {
9160                        Binder.restoreCallingIdentity(origId);
9161                    }
9162                }
9163
9164                checkTime(startTime, "getContentProviderImpl: updating data structures");
9165
9166                // Make sure the provider is published (the same provider class
9167                // may be published under multiple names).
9168                if (firstClass) {
9169                    mProviderMap.putProviderByClass(comp, cpr);
9170                }
9171
9172                mProviderMap.putProviderByName(name, cpr);
9173                conn = incProviderCountLocked(r, cpr, token, stable);
9174                if (conn != null) {
9175                    conn.waiting = true;
9176                }
9177            }
9178            checkTime(startTime, "getContentProviderImpl: done!");
9179        }
9180
9181        // Wait for the provider to be published...
9182        synchronized (cpr) {
9183            while (cpr.provider == null) {
9184                if (cpr.launchingApp == null) {
9185                    Slog.w(TAG, "Unable to launch app "
9186                            + cpi.applicationInfo.packageName + "/"
9187                            + cpi.applicationInfo.uid + " for provider "
9188                            + name + ": launching app became null");
9189                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9190                            UserHandle.getUserId(cpi.applicationInfo.uid),
9191                            cpi.applicationInfo.packageName,
9192                            cpi.applicationInfo.uid, name);
9193                    return null;
9194                }
9195                try {
9196                    if (DEBUG_MU) Slog.v(TAG_MU,
9197                            "Waiting to start provider " + cpr
9198                            + " launchingApp=" + cpr.launchingApp);
9199                    if (conn != null) {
9200                        conn.waiting = true;
9201                    }
9202                    cpr.wait();
9203                } catch (InterruptedException ex) {
9204                } finally {
9205                    if (conn != null) {
9206                        conn.waiting = false;
9207                    }
9208                }
9209            }
9210        }
9211        return cpr != null ? cpr.newHolder(conn) : null;
9212    }
9213
9214    @Override
9215    public final ContentProviderHolder getContentProvider(
9216            IApplicationThread caller, String name, int userId, boolean stable) {
9217        enforceNotIsolatedCaller("getContentProvider");
9218        if (caller == null) {
9219            String msg = "null IApplicationThread when getting content provider "
9220                    + name;
9221            Slog.w(TAG, msg);
9222            throw new SecurityException(msg);
9223        }
9224        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9225        // with cross-user grant.
9226        return getContentProviderImpl(caller, name, null, stable, userId);
9227    }
9228
9229    public ContentProviderHolder getContentProviderExternal(
9230            String name, int userId, IBinder token) {
9231        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9232            "Do not have permission in call getContentProviderExternal()");
9233        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9234                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9235        return getContentProviderExternalUnchecked(name, token, userId);
9236    }
9237
9238    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9239            IBinder token, int userId) {
9240        return getContentProviderImpl(null, name, token, true, userId);
9241    }
9242
9243    /**
9244     * Drop a content provider from a ProcessRecord's bookkeeping
9245     */
9246    public void removeContentProvider(IBinder connection, boolean stable) {
9247        enforceNotIsolatedCaller("removeContentProvider");
9248        long ident = Binder.clearCallingIdentity();
9249        try {
9250            synchronized (this) {
9251                ContentProviderConnection conn;
9252                try {
9253                    conn = (ContentProviderConnection)connection;
9254                } catch (ClassCastException e) {
9255                    String msg ="removeContentProvider: " + connection
9256                            + " not a ContentProviderConnection";
9257                    Slog.w(TAG, msg);
9258                    throw new IllegalArgumentException(msg);
9259                }
9260                if (conn == null) {
9261                    throw new NullPointerException("connection is null");
9262                }
9263                if (decProviderCountLocked(conn, null, null, stable)) {
9264                    updateOomAdjLocked();
9265                }
9266            }
9267        } finally {
9268            Binder.restoreCallingIdentity(ident);
9269        }
9270    }
9271
9272    public void removeContentProviderExternal(String name, IBinder token) {
9273        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9274            "Do not have permission in call removeContentProviderExternal()");
9275        int userId = UserHandle.getCallingUserId();
9276        long ident = Binder.clearCallingIdentity();
9277        try {
9278            removeContentProviderExternalUnchecked(name, token, userId);
9279        } finally {
9280            Binder.restoreCallingIdentity(ident);
9281        }
9282    }
9283
9284    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9285        synchronized (this) {
9286            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9287            if(cpr == null) {
9288                //remove from mProvidersByClass
9289                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9290                return;
9291            }
9292
9293            //update content provider record entry info
9294            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9295            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9296            if (localCpr.hasExternalProcessHandles()) {
9297                if (localCpr.removeExternalProcessHandleLocked(token)) {
9298                    updateOomAdjLocked();
9299                } else {
9300                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9301                            + " with no external reference for token: "
9302                            + token + ".");
9303                }
9304            } else {
9305                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9306                        + " with no external references.");
9307            }
9308        }
9309    }
9310
9311    public final void publishContentProviders(IApplicationThread caller,
9312            List<ContentProviderHolder> providers) {
9313        if (providers == null) {
9314            return;
9315        }
9316
9317        enforceNotIsolatedCaller("publishContentProviders");
9318        synchronized (this) {
9319            final ProcessRecord r = getRecordForAppLocked(caller);
9320            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9321            if (r == null) {
9322                throw new SecurityException(
9323                        "Unable to find app for caller " + caller
9324                      + " (pid=" + Binder.getCallingPid()
9325                      + ") when publishing content providers");
9326            }
9327
9328            final long origId = Binder.clearCallingIdentity();
9329
9330            final int N = providers.size();
9331            for (int i=0; i<N; i++) {
9332                ContentProviderHolder src = providers.get(i);
9333                if (src == null || src.info == null || src.provider == null) {
9334                    continue;
9335                }
9336                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9337                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9338                if (dst != null) {
9339                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9340                    mProviderMap.putProviderByClass(comp, dst);
9341                    String names[] = dst.info.authority.split(";");
9342                    for (int j = 0; j < names.length; j++) {
9343                        mProviderMap.putProviderByName(names[j], dst);
9344                    }
9345
9346                    int NL = mLaunchingProviders.size();
9347                    int j;
9348                    for (j=0; j<NL; j++) {
9349                        if (mLaunchingProviders.get(j) == dst) {
9350                            mLaunchingProviders.remove(j);
9351                            j--;
9352                            NL--;
9353                        }
9354                    }
9355                    synchronized (dst) {
9356                        dst.provider = src.provider;
9357                        dst.proc = r;
9358                        dst.notifyAll();
9359                    }
9360                    updateOomAdjLocked(r);
9361                }
9362            }
9363
9364            Binder.restoreCallingIdentity(origId);
9365        }
9366    }
9367
9368    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9369        ContentProviderConnection conn;
9370        try {
9371            conn = (ContentProviderConnection)connection;
9372        } catch (ClassCastException e) {
9373            String msg ="refContentProvider: " + connection
9374                    + " not a ContentProviderConnection";
9375            Slog.w(TAG, msg);
9376            throw new IllegalArgumentException(msg);
9377        }
9378        if (conn == null) {
9379            throw new NullPointerException("connection is null");
9380        }
9381
9382        synchronized (this) {
9383            if (stable > 0) {
9384                conn.numStableIncs += stable;
9385            }
9386            stable = conn.stableCount + stable;
9387            if (stable < 0) {
9388                throw new IllegalStateException("stableCount < 0: " + stable);
9389            }
9390
9391            if (unstable > 0) {
9392                conn.numUnstableIncs += unstable;
9393            }
9394            unstable = conn.unstableCount + unstable;
9395            if (unstable < 0) {
9396                throw new IllegalStateException("unstableCount < 0: " + unstable);
9397            }
9398
9399            if ((stable+unstable) <= 0) {
9400                throw new IllegalStateException("ref counts can't go to zero here: stable="
9401                        + stable + " unstable=" + unstable);
9402            }
9403            conn.stableCount = stable;
9404            conn.unstableCount = unstable;
9405            return !conn.dead;
9406        }
9407    }
9408
9409    public void unstableProviderDied(IBinder connection) {
9410        ContentProviderConnection conn;
9411        try {
9412            conn = (ContentProviderConnection)connection;
9413        } catch (ClassCastException e) {
9414            String msg ="refContentProvider: " + connection
9415                    + " not a ContentProviderConnection";
9416            Slog.w(TAG, msg);
9417            throw new IllegalArgumentException(msg);
9418        }
9419        if (conn == null) {
9420            throw new NullPointerException("connection is null");
9421        }
9422
9423        // Safely retrieve the content provider associated with the connection.
9424        IContentProvider provider;
9425        synchronized (this) {
9426            provider = conn.provider.provider;
9427        }
9428
9429        if (provider == null) {
9430            // Um, yeah, we're way ahead of you.
9431            return;
9432        }
9433
9434        // Make sure the caller is being honest with us.
9435        if (provider.asBinder().pingBinder()) {
9436            // Er, no, still looks good to us.
9437            synchronized (this) {
9438                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9439                        + " says " + conn + " died, but we don't agree");
9440                return;
9441            }
9442        }
9443
9444        // Well look at that!  It's dead!
9445        synchronized (this) {
9446            if (conn.provider.provider != provider) {
9447                // But something changed...  good enough.
9448                return;
9449            }
9450
9451            ProcessRecord proc = conn.provider.proc;
9452            if (proc == null || proc.thread == null) {
9453                // Seems like the process is already cleaned up.
9454                return;
9455            }
9456
9457            // As far as we're concerned, this is just like receiving a
9458            // death notification...  just a bit prematurely.
9459            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9460                    + ") early provider death");
9461            final long ident = Binder.clearCallingIdentity();
9462            try {
9463                appDiedLocked(proc);
9464            } finally {
9465                Binder.restoreCallingIdentity(ident);
9466            }
9467        }
9468    }
9469
9470    @Override
9471    public void appNotRespondingViaProvider(IBinder connection) {
9472        enforceCallingPermission(
9473                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9474
9475        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9476        if (conn == null) {
9477            Slog.w(TAG, "ContentProviderConnection is null");
9478            return;
9479        }
9480
9481        final ProcessRecord host = conn.provider.proc;
9482        if (host == null) {
9483            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9484            return;
9485        }
9486
9487        final long token = Binder.clearCallingIdentity();
9488        try {
9489            appNotResponding(host, null, null, false, "ContentProvider not responding");
9490        } finally {
9491            Binder.restoreCallingIdentity(token);
9492        }
9493    }
9494
9495    public final void installSystemProviders() {
9496        List<ProviderInfo> providers;
9497        synchronized (this) {
9498            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9499            providers = generateApplicationProvidersLocked(app);
9500            if (providers != null) {
9501                for (int i=providers.size()-1; i>=0; i--) {
9502                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9503                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9504                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9505                                + ": not system .apk");
9506                        providers.remove(i);
9507                    }
9508                }
9509            }
9510        }
9511        if (providers != null) {
9512            mSystemThread.installSystemProviders(providers);
9513        }
9514
9515        mCoreSettingsObserver = new CoreSettingsObserver(this);
9516
9517        //mUsageStatsService.monitorPackages();
9518    }
9519
9520    /**
9521     * Allows apps to retrieve the MIME type of a URI.
9522     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9523     * users, then it does not need permission to access the ContentProvider.
9524     * Either, it needs cross-user uri grants.
9525     *
9526     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9527     *
9528     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9529     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9530     */
9531    public String getProviderMimeType(Uri uri, int userId) {
9532        enforceNotIsolatedCaller("getProviderMimeType");
9533        final String name = uri.getAuthority();
9534        int callingUid = Binder.getCallingUid();
9535        int callingPid = Binder.getCallingPid();
9536        long ident = 0;
9537        boolean clearedIdentity = false;
9538        userId = unsafeConvertIncomingUser(userId);
9539        if (canClearIdentity(callingPid, callingUid, userId)) {
9540            clearedIdentity = true;
9541            ident = Binder.clearCallingIdentity();
9542        }
9543        ContentProviderHolder holder = null;
9544        try {
9545            holder = getContentProviderExternalUnchecked(name, null, userId);
9546            if (holder != null) {
9547                return holder.provider.getType(uri);
9548            }
9549        } catch (RemoteException e) {
9550            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9551            return null;
9552        } finally {
9553            // We need to clear the identity to call removeContentProviderExternalUnchecked
9554            if (!clearedIdentity) {
9555                ident = Binder.clearCallingIdentity();
9556            }
9557            try {
9558                if (holder != null) {
9559                    removeContentProviderExternalUnchecked(name, null, userId);
9560                }
9561            } finally {
9562                Binder.restoreCallingIdentity(ident);
9563            }
9564        }
9565
9566        return null;
9567    }
9568
9569    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9570        if (UserHandle.getUserId(callingUid) == userId) {
9571            return true;
9572        }
9573        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9574                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9575                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9576                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9577                return true;
9578        }
9579        return false;
9580    }
9581
9582    // =========================================================
9583    // GLOBAL MANAGEMENT
9584    // =========================================================
9585
9586    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9587            boolean isolated, int isolatedUid) {
9588        String proc = customProcess != null ? customProcess : info.processName;
9589        BatteryStatsImpl.Uid.Proc ps = null;
9590        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9591        int uid = info.uid;
9592        if (isolated) {
9593            if (isolatedUid == 0) {
9594                int userId = UserHandle.getUserId(uid);
9595                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9596                while (true) {
9597                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9598                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9599                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9600                    }
9601                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9602                    mNextIsolatedProcessUid++;
9603                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9604                        // No process for this uid, use it.
9605                        break;
9606                    }
9607                    stepsLeft--;
9608                    if (stepsLeft <= 0) {
9609                        return null;
9610                    }
9611                }
9612            } else {
9613                // Special case for startIsolatedProcess (internal only), where
9614                // the uid of the isolated process is specified by the caller.
9615                uid = isolatedUid;
9616            }
9617        }
9618        return new ProcessRecord(stats, info, proc, uid);
9619    }
9620
9621    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9622            String abiOverride) {
9623        ProcessRecord app;
9624        if (!isolated) {
9625            app = getProcessRecordLocked(info.processName, info.uid, true);
9626        } else {
9627            app = null;
9628        }
9629
9630        if (app == null) {
9631            app = newProcessRecordLocked(info, null, isolated, 0);
9632            mProcessNames.put(info.processName, app.uid, app);
9633            if (isolated) {
9634                mIsolatedProcesses.put(app.uid, app);
9635            }
9636            updateLruProcessLocked(app, false, null);
9637            updateOomAdjLocked();
9638        }
9639
9640        // This package really, really can not be stopped.
9641        try {
9642            AppGlobals.getPackageManager().setPackageStoppedState(
9643                    info.packageName, false, UserHandle.getUserId(app.uid));
9644        } catch (RemoteException e) {
9645        } catch (IllegalArgumentException e) {
9646            Slog.w(TAG, "Failed trying to unstop package "
9647                    + info.packageName + ": " + e);
9648        }
9649
9650        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9651                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9652            app.persistent = true;
9653            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9654        }
9655        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9656            mPersistentStartingProcesses.add(app);
9657            startProcessLocked(app, "added application", app.processName, abiOverride,
9658                    null /* entryPoint */, null /* entryPointArgs */);
9659        }
9660
9661        return app;
9662    }
9663
9664    public void unhandledBack() {
9665        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9666                "unhandledBack()");
9667
9668        synchronized(this) {
9669            final long origId = Binder.clearCallingIdentity();
9670            try {
9671                getFocusedStack().unhandledBackLocked();
9672            } finally {
9673                Binder.restoreCallingIdentity(origId);
9674            }
9675        }
9676    }
9677
9678    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9679        enforceNotIsolatedCaller("openContentUri");
9680        final int userId = UserHandle.getCallingUserId();
9681        String name = uri.getAuthority();
9682        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9683        ParcelFileDescriptor pfd = null;
9684        if (cph != null) {
9685            // We record the binder invoker's uid in thread-local storage before
9686            // going to the content provider to open the file.  Later, in the code
9687            // that handles all permissions checks, we look for this uid and use
9688            // that rather than the Activity Manager's own uid.  The effect is that
9689            // we do the check against the caller's permissions even though it looks
9690            // to the content provider like the Activity Manager itself is making
9691            // the request.
9692            Binder token = new Binder();
9693            sCallerIdentity.set(new Identity(
9694                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9695            try {
9696                pfd = cph.provider.openFile(null, uri, "r", null, token);
9697            } catch (FileNotFoundException e) {
9698                // do nothing; pfd will be returned null
9699            } finally {
9700                // Ensure that whatever happens, we clean up the identity state
9701                sCallerIdentity.remove();
9702                // Ensure we're done with the provider.
9703                removeContentProviderExternalUnchecked(name, null, userId);
9704            }
9705        } else {
9706            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9707        }
9708        return pfd;
9709    }
9710
9711    // Actually is sleeping or shutting down or whatever else in the future
9712    // is an inactive state.
9713    public boolean isSleepingOrShuttingDown() {
9714        return isSleeping() || mShuttingDown;
9715    }
9716
9717    public boolean isSleeping() {
9718        return mSleeping;
9719    }
9720
9721    void onWakefulnessChanged(int wakefulness) {
9722        synchronized(this) {
9723            mWakefulness = wakefulness;
9724            updateSleepIfNeededLocked();
9725        }
9726    }
9727
9728    void finishRunningVoiceLocked() {
9729        if (mRunningVoice != null) {
9730            mRunningVoice = null;
9731            updateSleepIfNeededLocked();
9732        }
9733    }
9734
9735    void updateSleepIfNeededLocked() {
9736        if (mSleeping && !shouldSleepLocked()) {
9737            mSleeping = false;
9738            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9739        } else if (!mSleeping && shouldSleepLocked()) {
9740            mSleeping = true;
9741            mStackSupervisor.goingToSleepLocked();
9742
9743            // Initialize the wake times of all processes.
9744            checkExcessivePowerUsageLocked(false);
9745            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9746            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9747            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9748        }
9749    }
9750
9751    private boolean shouldSleepLocked() {
9752        // Resume applications while running a voice interactor.
9753        if (mRunningVoice != null) {
9754            return false;
9755        }
9756
9757        switch (mWakefulness) {
9758            case PowerManagerInternal.WAKEFULNESS_AWAKE:
9759            case PowerManagerInternal.WAKEFULNESS_DREAMING:
9760                // If we're interactive but applications are already paused then defer
9761                // resuming them until the lock screen is hidden.
9762                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
9763            case PowerManagerInternal.WAKEFULNESS_DOZING:
9764                // If we're dozing then pause applications whenever the lock screen is shown.
9765                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
9766            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
9767            default:
9768                // If we're asleep then pause applications unconditionally.
9769                return true;
9770        }
9771    }
9772
9773    /** Pokes the task persister. */
9774    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9775        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9776            // Never persist the home stack.
9777            return;
9778        }
9779        mTaskPersister.wakeup(task, flush);
9780    }
9781
9782    /** Notifies all listeners when the task stack has changed. */
9783    void notifyTaskStackChangedLocked() {
9784        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
9785        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
9786        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
9787    }
9788
9789    @Override
9790    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
9791        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
9792    }
9793
9794    @Override
9795    public boolean shutdown(int timeout) {
9796        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9797                != PackageManager.PERMISSION_GRANTED) {
9798            throw new SecurityException("Requires permission "
9799                    + android.Manifest.permission.SHUTDOWN);
9800        }
9801
9802        boolean timedout = false;
9803
9804        synchronized(this) {
9805            mShuttingDown = true;
9806            updateEventDispatchingLocked();
9807            timedout = mStackSupervisor.shutdownLocked(timeout);
9808        }
9809
9810        mAppOpsService.shutdown();
9811        if (mUsageStatsService != null) {
9812            mUsageStatsService.prepareShutdown();
9813        }
9814        mBatteryStatsService.shutdown();
9815        synchronized (this) {
9816            mProcessStats.shutdownLocked();
9817            notifyTaskPersisterLocked(null, true);
9818        }
9819
9820        return timedout;
9821    }
9822
9823    public final void activitySlept(IBinder token) {
9824        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
9825
9826        final long origId = Binder.clearCallingIdentity();
9827
9828        synchronized (this) {
9829            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9830            if (r != null) {
9831                mStackSupervisor.activitySleptLocked(r);
9832            }
9833        }
9834
9835        Binder.restoreCallingIdentity(origId);
9836    }
9837
9838    private String lockScreenShownToString() {
9839        switch (mLockScreenShown) {
9840            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
9841            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
9842            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
9843            default: return "Unknown=" + mLockScreenShown;
9844        }
9845    }
9846
9847    void logLockScreen(String msg) {
9848        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
9849                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
9850                + PowerManagerInternal.wakefulnessToString(mWakefulness)
9851                + " mSleeping=" + mSleeping);
9852    }
9853
9854    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
9855        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
9856        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
9857            if (mRunningVoice == null) {
9858                mVoiceWakeLock.acquire();
9859                updateSleepIfNeededLocked();
9860            }
9861            mRunningVoice = session;
9862        }
9863    }
9864
9865    private void updateEventDispatchingLocked() {
9866        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
9867    }
9868
9869    public void setLockScreenShown(boolean shown) {
9870        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9871                != PackageManager.PERMISSION_GRANTED) {
9872            throw new SecurityException("Requires permission "
9873                    + android.Manifest.permission.DEVICE_POWER);
9874        }
9875
9876        synchronized(this) {
9877            long ident = Binder.clearCallingIdentity();
9878            try {
9879                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9880                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
9881                updateSleepIfNeededLocked();
9882            } finally {
9883                Binder.restoreCallingIdentity(ident);
9884            }
9885        }
9886    }
9887
9888    @Override
9889    public void stopAppSwitches() {
9890        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9891                != PackageManager.PERMISSION_GRANTED) {
9892            throw new SecurityException("Requires permission "
9893                    + android.Manifest.permission.STOP_APP_SWITCHES);
9894        }
9895
9896        synchronized(this) {
9897            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9898                    + APP_SWITCH_DELAY_TIME;
9899            mDidAppSwitch = false;
9900            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9901            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9902            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9903        }
9904    }
9905
9906    public void resumeAppSwitches() {
9907        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9908                != PackageManager.PERMISSION_GRANTED) {
9909            throw new SecurityException("Requires permission "
9910                    + android.Manifest.permission.STOP_APP_SWITCHES);
9911        }
9912
9913        synchronized(this) {
9914            // Note that we don't execute any pending app switches... we will
9915            // let those wait until either the timeout, or the next start
9916            // activity request.
9917            mAppSwitchesAllowedTime = 0;
9918        }
9919    }
9920
9921    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
9922            int callingPid, int callingUid, String name) {
9923        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9924            return true;
9925        }
9926
9927        int perm = checkComponentPermission(
9928                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
9929                sourceUid, -1, true);
9930        if (perm == PackageManager.PERMISSION_GRANTED) {
9931            return true;
9932        }
9933
9934        // If the actual IPC caller is different from the logical source, then
9935        // also see if they are allowed to control app switches.
9936        if (callingUid != -1 && callingUid != sourceUid) {
9937            perm = checkComponentPermission(
9938                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9939                    callingUid, -1, true);
9940            if (perm == PackageManager.PERMISSION_GRANTED) {
9941                return true;
9942            }
9943        }
9944
9945        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
9946        return false;
9947    }
9948
9949    public void setDebugApp(String packageName, boolean waitForDebugger,
9950            boolean persistent) {
9951        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9952                "setDebugApp()");
9953
9954        long ident = Binder.clearCallingIdentity();
9955        try {
9956            // Note that this is not really thread safe if there are multiple
9957            // callers into it at the same time, but that's not a situation we
9958            // care about.
9959            if (persistent) {
9960                final ContentResolver resolver = mContext.getContentResolver();
9961                Settings.Global.putString(
9962                    resolver, Settings.Global.DEBUG_APP,
9963                    packageName);
9964                Settings.Global.putInt(
9965                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9966                    waitForDebugger ? 1 : 0);
9967            }
9968
9969            synchronized (this) {
9970                if (!persistent) {
9971                    mOrigDebugApp = mDebugApp;
9972                    mOrigWaitForDebugger = mWaitForDebugger;
9973                }
9974                mDebugApp = packageName;
9975                mWaitForDebugger = waitForDebugger;
9976                mDebugTransient = !persistent;
9977                if (packageName != null) {
9978                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9979                            false, UserHandle.USER_ALL, "set debug app");
9980                }
9981            }
9982        } finally {
9983            Binder.restoreCallingIdentity(ident);
9984        }
9985    }
9986
9987    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9988        synchronized (this) {
9989            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9990            if (!isDebuggable) {
9991                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9992                    throw new SecurityException("Process not debuggable: " + app.packageName);
9993                }
9994            }
9995
9996            mOpenGlTraceApp = processName;
9997        }
9998    }
9999
10000    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10001        synchronized (this) {
10002            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10003            if (!isDebuggable) {
10004                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10005                    throw new SecurityException("Process not debuggable: " + app.packageName);
10006                }
10007            }
10008            mProfileApp = processName;
10009            mProfileFile = profilerInfo.profileFile;
10010            if (mProfileFd != null) {
10011                try {
10012                    mProfileFd.close();
10013                } catch (IOException e) {
10014                }
10015                mProfileFd = null;
10016            }
10017            mProfileFd = profilerInfo.profileFd;
10018            mSamplingInterval = profilerInfo.samplingInterval;
10019            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10020            mProfileType = 0;
10021        }
10022    }
10023
10024    @Override
10025    public void setAlwaysFinish(boolean enabled) {
10026        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10027                "setAlwaysFinish()");
10028
10029        Settings.Global.putInt(
10030                mContext.getContentResolver(),
10031                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10032
10033        synchronized (this) {
10034            mAlwaysFinishActivities = enabled;
10035        }
10036    }
10037
10038    @Override
10039    public void setActivityController(IActivityController controller) {
10040        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10041                "setActivityController()");
10042        synchronized (this) {
10043            mController = controller;
10044            Watchdog.getInstance().setActivityController(controller);
10045        }
10046    }
10047
10048    @Override
10049    public void setUserIsMonkey(boolean userIsMonkey) {
10050        synchronized (this) {
10051            synchronized (mPidsSelfLocked) {
10052                final int callingPid = Binder.getCallingPid();
10053                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10054                if (precessRecord == null) {
10055                    throw new SecurityException("Unknown process: " + callingPid);
10056                }
10057                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10058                    throw new SecurityException("Only an instrumentation process "
10059                            + "with a UiAutomation can call setUserIsMonkey");
10060                }
10061            }
10062            mUserIsMonkey = userIsMonkey;
10063        }
10064    }
10065
10066    @Override
10067    public boolean isUserAMonkey() {
10068        synchronized (this) {
10069            // If there is a controller also implies the user is a monkey.
10070            return (mUserIsMonkey || mController != null);
10071        }
10072    }
10073
10074    public void requestBugReport() {
10075        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10076        SystemProperties.set("ctl.start", "bugreport");
10077    }
10078
10079    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10080        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10081    }
10082
10083    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10084        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10085            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10086        }
10087        return KEY_DISPATCHING_TIMEOUT;
10088    }
10089
10090    @Override
10091    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10092        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10093                != PackageManager.PERMISSION_GRANTED) {
10094            throw new SecurityException("Requires permission "
10095                    + android.Manifest.permission.FILTER_EVENTS);
10096        }
10097        ProcessRecord proc;
10098        long timeout;
10099        synchronized (this) {
10100            synchronized (mPidsSelfLocked) {
10101                proc = mPidsSelfLocked.get(pid);
10102            }
10103            timeout = getInputDispatchingTimeoutLocked(proc);
10104        }
10105
10106        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10107            return -1;
10108        }
10109
10110        return timeout;
10111    }
10112
10113    /**
10114     * Handle input dispatching timeouts.
10115     * Returns whether input dispatching should be aborted or not.
10116     */
10117    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10118            final ActivityRecord activity, final ActivityRecord parent,
10119            final boolean aboveSystem, String reason) {
10120        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10121                != PackageManager.PERMISSION_GRANTED) {
10122            throw new SecurityException("Requires permission "
10123                    + android.Manifest.permission.FILTER_EVENTS);
10124        }
10125
10126        final String annotation;
10127        if (reason == null) {
10128            annotation = "Input dispatching timed out";
10129        } else {
10130            annotation = "Input dispatching timed out (" + reason + ")";
10131        }
10132
10133        if (proc != null) {
10134            synchronized (this) {
10135                if (proc.debugging) {
10136                    return false;
10137                }
10138
10139                if (mDidDexOpt) {
10140                    // Give more time since we were dexopting.
10141                    mDidDexOpt = false;
10142                    return false;
10143                }
10144
10145                if (proc.instrumentationClass != null) {
10146                    Bundle info = new Bundle();
10147                    info.putString("shortMsg", "keyDispatchingTimedOut");
10148                    info.putString("longMsg", annotation);
10149                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10150                    return true;
10151                }
10152            }
10153            mHandler.post(new Runnable() {
10154                @Override
10155                public void run() {
10156                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10157                }
10158            });
10159        }
10160
10161        return true;
10162    }
10163
10164    @Override
10165    public Bundle getAssistContextExtras(int requestType) {
10166        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10167                UserHandle.getCallingUserId());
10168        if (pae == null) {
10169            return null;
10170        }
10171        synchronized (pae) {
10172            while (!pae.haveResult) {
10173                try {
10174                    pae.wait();
10175                } catch (InterruptedException e) {
10176                }
10177            }
10178        }
10179        synchronized (this) {
10180            buildAssistBundleLocked(pae, pae.result);
10181            mPendingAssistExtras.remove(pae);
10182            mHandler.removeCallbacks(pae);
10183        }
10184        return pae.extras;
10185    }
10186
10187    @Override
10188    public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
10189        enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId());
10190    }
10191
10192    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10193            IResultReceiver receiver, int userHandle) {
10194        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10195                "enqueueAssistContext()");
10196        synchronized (this) {
10197            ActivityRecord activity = getFocusedStack().topActivity();
10198            if (activity == null) {
10199                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10200                return null;
10201            }
10202            if (activity.app == null || activity.app.thread == null) {
10203                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10204                return null;
10205            }
10206            if (activity.app.pid == Binder.getCallingPid()) {
10207                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10208                return null;
10209            }
10210            PendingAssistExtras pae;
10211            Bundle extras = new Bundle();
10212            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10213            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10214            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10215            try {
10216                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10217                        requestType);
10218                mPendingAssistExtras.add(pae);
10219                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10220            } catch (RemoteException e) {
10221                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10222                return null;
10223            }
10224            return pae;
10225        }
10226    }
10227
10228    void pendingAssistExtrasTimedOutLocked(PendingAssistExtras pae) {
10229        mPendingAssistExtras.remove(pae);
10230        if (pae.receiver != null) {
10231            // Caller wants result sent back to them.
10232            try {
10233                pae.receiver.send(0, null);
10234            } catch (RemoteException e) {
10235            }
10236        }
10237    }
10238
10239    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10240        if (result != null) {
10241            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10242        }
10243        if (pae.hint != null) {
10244            pae.extras.putBoolean(pae.hint, true);
10245        }
10246    }
10247
10248    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10249        PendingAssistExtras pae = (PendingAssistExtras)token;
10250        synchronized (pae) {
10251            pae.result = extras;
10252            pae.haveResult = true;
10253            pae.notifyAll();
10254            if (pae.intent == null && pae.receiver == null) {
10255                // Caller is just waiting for the result.
10256                return;
10257            }
10258        }
10259
10260        // We are now ready to launch the assist activity.
10261        synchronized (this) {
10262            buildAssistBundleLocked(pae, extras);
10263            boolean exists = mPendingAssistExtras.remove(pae);
10264            mHandler.removeCallbacks(pae);
10265            if (!exists) {
10266                // Timed out.
10267                return;
10268            }
10269            if (pae.receiver != null) {
10270                // Caller wants result sent back to them.
10271                try {
10272                    pae.receiver.send(0, pae.extras);
10273                } catch (RemoteException e) {
10274                }
10275                return;
10276            }
10277        }
10278        pae.intent.replaceExtras(pae.extras);
10279        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10280                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10281                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10282        closeSystemDialogs("assist");
10283        try {
10284            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10285        } catch (ActivityNotFoundException e) {
10286            Slog.w(TAG, "No activity to handle assist action.", e);
10287        }
10288    }
10289
10290    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10291        return enqueueAssistContext(requestType, intent, hint, null, userHandle) != null;
10292    }
10293
10294    public void registerProcessObserver(IProcessObserver observer) {
10295        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10296                "registerProcessObserver()");
10297        synchronized (this) {
10298            mProcessObservers.register(observer);
10299        }
10300    }
10301
10302    @Override
10303    public void unregisterProcessObserver(IProcessObserver observer) {
10304        synchronized (this) {
10305            mProcessObservers.unregister(observer);
10306        }
10307    }
10308
10309    @Override
10310    public boolean convertFromTranslucent(IBinder token) {
10311        final long origId = Binder.clearCallingIdentity();
10312        try {
10313            synchronized (this) {
10314                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10315                if (r == null) {
10316                    return false;
10317                }
10318                final boolean translucentChanged = r.changeWindowTranslucency(true);
10319                if (translucentChanged) {
10320                    r.task.stack.releaseBackgroundResources(r);
10321                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10322                }
10323                mWindowManager.setAppFullscreen(token, true);
10324                return translucentChanged;
10325            }
10326        } finally {
10327            Binder.restoreCallingIdentity(origId);
10328        }
10329    }
10330
10331    @Override
10332    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10333        final long origId = Binder.clearCallingIdentity();
10334        try {
10335            synchronized (this) {
10336                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10337                if (r == null) {
10338                    return false;
10339                }
10340                int index = r.task.mActivities.lastIndexOf(r);
10341                if (index > 0) {
10342                    ActivityRecord under = r.task.mActivities.get(index - 1);
10343                    under.returningOptions = options;
10344                }
10345                final boolean translucentChanged = r.changeWindowTranslucency(false);
10346                if (translucentChanged) {
10347                    r.task.stack.convertActivityToTranslucent(r);
10348                }
10349                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10350                mWindowManager.setAppFullscreen(token, false);
10351                return translucentChanged;
10352            }
10353        } finally {
10354            Binder.restoreCallingIdentity(origId);
10355        }
10356    }
10357
10358    @Override
10359    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10360        final long origId = Binder.clearCallingIdentity();
10361        try {
10362            synchronized (this) {
10363                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10364                if (r != null) {
10365                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10366                }
10367            }
10368            return false;
10369        } finally {
10370            Binder.restoreCallingIdentity(origId);
10371        }
10372    }
10373
10374    @Override
10375    public boolean isBackgroundVisibleBehind(IBinder token) {
10376        final long origId = Binder.clearCallingIdentity();
10377        try {
10378            synchronized (this) {
10379                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10380                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10381                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10382                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10383                return visible;
10384            }
10385        } finally {
10386            Binder.restoreCallingIdentity(origId);
10387        }
10388    }
10389
10390    @Override
10391    public ActivityOptions getActivityOptions(IBinder token) {
10392        final long origId = Binder.clearCallingIdentity();
10393        try {
10394            synchronized (this) {
10395                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10396                if (r != null) {
10397                    final ActivityOptions activityOptions = r.pendingOptions;
10398                    r.pendingOptions = null;
10399                    return activityOptions;
10400                }
10401                return null;
10402            }
10403        } finally {
10404            Binder.restoreCallingIdentity(origId);
10405        }
10406    }
10407
10408    @Override
10409    public void setImmersive(IBinder token, boolean immersive) {
10410        synchronized(this) {
10411            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10412            if (r == null) {
10413                throw new IllegalArgumentException();
10414            }
10415            r.immersive = immersive;
10416
10417            // update associated state if we're frontmost
10418            if (r == mFocusedActivity) {
10419                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
10420                applyUpdateLockStateLocked(r);
10421            }
10422        }
10423    }
10424
10425    @Override
10426    public boolean isImmersive(IBinder token) {
10427        synchronized (this) {
10428            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10429            if (r == null) {
10430                throw new IllegalArgumentException();
10431            }
10432            return r.immersive;
10433        }
10434    }
10435
10436    public boolean isTopActivityImmersive() {
10437        enforceNotIsolatedCaller("startActivity");
10438        synchronized (this) {
10439            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10440            return (r != null) ? r.immersive : false;
10441        }
10442    }
10443
10444    @Override
10445    public boolean isTopOfTask(IBinder token) {
10446        synchronized (this) {
10447            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10448            if (r == null) {
10449                throw new IllegalArgumentException();
10450            }
10451            return r.task.getTopActivity() == r;
10452        }
10453    }
10454
10455    public final void enterSafeMode() {
10456        synchronized(this) {
10457            // It only makes sense to do this before the system is ready
10458            // and started launching other packages.
10459            if (!mSystemReady) {
10460                try {
10461                    AppGlobals.getPackageManager().enterSafeMode();
10462                } catch (RemoteException e) {
10463                }
10464            }
10465
10466            mSafeMode = true;
10467        }
10468    }
10469
10470    public final void showSafeModeOverlay() {
10471        View v = LayoutInflater.from(mContext).inflate(
10472                com.android.internal.R.layout.safe_mode, null);
10473        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10474        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10475        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10476        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10477        lp.gravity = Gravity.BOTTOM | Gravity.START;
10478        lp.format = v.getBackground().getOpacity();
10479        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10480                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10481        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10482        ((WindowManager)mContext.getSystemService(
10483                Context.WINDOW_SERVICE)).addView(v, lp);
10484    }
10485
10486    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10487        if (!(sender instanceof PendingIntentRecord)) {
10488            return;
10489        }
10490        final PendingIntentRecord rec = (PendingIntentRecord)sender;
10491        final String tag;
10492        synchronized (this) {
10493            tag = getTagForIntentSenderLocked(rec, "*walarm*:");
10494        }
10495        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10496        synchronized (stats) {
10497            if (mBatteryStatsService.isOnBattery()) {
10498                mBatteryStatsService.enforceCallingPermission();
10499                int MY_UID = Binder.getCallingUid();
10500                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10501                BatteryStatsImpl.Uid.Pkg pkg =
10502                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10503                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10504                pkg.noteWakeupAlarmLocked(tag);
10505            }
10506        }
10507    }
10508
10509    public boolean killPids(int[] pids, String pReason, boolean secure) {
10510        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10511            throw new SecurityException("killPids only available to the system");
10512        }
10513        String reason = (pReason == null) ? "Unknown" : pReason;
10514        // XXX Note: don't acquire main activity lock here, because the window
10515        // manager calls in with its locks held.
10516
10517        boolean killed = false;
10518        synchronized (mPidsSelfLocked) {
10519            int[] types = new int[pids.length];
10520            int worstType = 0;
10521            for (int i=0; i<pids.length; i++) {
10522                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10523                if (proc != null) {
10524                    int type = proc.setAdj;
10525                    types[i] = type;
10526                    if (type > worstType) {
10527                        worstType = type;
10528                    }
10529                }
10530            }
10531
10532            // If the worst oom_adj is somewhere in the cached proc LRU range,
10533            // then constrain it so we will kill all cached procs.
10534            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10535                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10536                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10537            }
10538
10539            // If this is not a secure call, don't let it kill processes that
10540            // are important.
10541            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10542                worstType = ProcessList.SERVICE_ADJ;
10543            }
10544
10545            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10546            for (int i=0; i<pids.length; i++) {
10547                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10548                if (proc == null) {
10549                    continue;
10550                }
10551                int adj = proc.setAdj;
10552                if (adj >= worstType && !proc.killedByAm) {
10553                    proc.kill(reason, true);
10554                    killed = true;
10555                }
10556            }
10557        }
10558        return killed;
10559    }
10560
10561    @Override
10562    public void killUid(int uid, String reason) {
10563        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10564            throw new SecurityException("killUid only available to the system");
10565        }
10566        synchronized (this) {
10567            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10568                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10569                    reason != null ? reason : "kill uid");
10570        }
10571    }
10572
10573    @Override
10574    public boolean killProcessesBelowForeground(String reason) {
10575        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10576            throw new SecurityException("killProcessesBelowForeground() only available to system");
10577        }
10578
10579        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10580    }
10581
10582    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10583        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10584            throw new SecurityException("killProcessesBelowAdj() only available to system");
10585        }
10586
10587        boolean killed = false;
10588        synchronized (mPidsSelfLocked) {
10589            final int size = mPidsSelfLocked.size();
10590            for (int i = 0; i < size; i++) {
10591                final int pid = mPidsSelfLocked.keyAt(i);
10592                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10593                if (proc == null) continue;
10594
10595                final int adj = proc.setAdj;
10596                if (adj > belowAdj && !proc.killedByAm) {
10597                    proc.kill(reason, true);
10598                    killed = true;
10599                }
10600            }
10601        }
10602        return killed;
10603    }
10604
10605    @Override
10606    public void hang(final IBinder who, boolean allowRestart) {
10607        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10608                != PackageManager.PERMISSION_GRANTED) {
10609            throw new SecurityException("Requires permission "
10610                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10611        }
10612
10613        final IBinder.DeathRecipient death = new DeathRecipient() {
10614            @Override
10615            public void binderDied() {
10616                synchronized (this) {
10617                    notifyAll();
10618                }
10619            }
10620        };
10621
10622        try {
10623            who.linkToDeath(death, 0);
10624        } catch (RemoteException e) {
10625            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10626            return;
10627        }
10628
10629        synchronized (this) {
10630            Watchdog.getInstance().setAllowRestart(allowRestart);
10631            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10632            synchronized (death) {
10633                while (who.isBinderAlive()) {
10634                    try {
10635                        death.wait();
10636                    } catch (InterruptedException e) {
10637                    }
10638                }
10639            }
10640            Watchdog.getInstance().setAllowRestart(true);
10641        }
10642    }
10643
10644    @Override
10645    public void restart() {
10646        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10647                != PackageManager.PERMISSION_GRANTED) {
10648            throw new SecurityException("Requires permission "
10649                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10650        }
10651
10652        Log.i(TAG, "Sending shutdown broadcast...");
10653
10654        BroadcastReceiver br = new BroadcastReceiver() {
10655            @Override public void onReceive(Context context, Intent intent) {
10656                // Now the broadcast is done, finish up the low-level shutdown.
10657                Log.i(TAG, "Shutting down activity manager...");
10658                shutdown(10000);
10659                Log.i(TAG, "Shutdown complete, restarting!");
10660                Process.killProcess(Process.myPid());
10661                System.exit(10);
10662            }
10663        };
10664
10665        // First send the high-level shut down broadcast.
10666        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10667        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10668        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10669        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10670        mContext.sendOrderedBroadcastAsUser(intent,
10671                UserHandle.ALL, null, br, mHandler, 0, null, null);
10672        */
10673        br.onReceive(mContext, intent);
10674    }
10675
10676    private long getLowRamTimeSinceIdle(long now) {
10677        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10678    }
10679
10680    @Override
10681    public void performIdleMaintenance() {
10682        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10683                != PackageManager.PERMISSION_GRANTED) {
10684            throw new SecurityException("Requires permission "
10685                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10686        }
10687
10688        synchronized (this) {
10689            final long now = SystemClock.uptimeMillis();
10690            final long timeSinceLastIdle = now - mLastIdleTime;
10691            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10692            mLastIdleTime = now;
10693            mLowRamTimeSinceLastIdle = 0;
10694            if (mLowRamStartTime != 0) {
10695                mLowRamStartTime = now;
10696            }
10697
10698            StringBuilder sb = new StringBuilder(128);
10699            sb.append("Idle maintenance over ");
10700            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10701            sb.append(" low RAM for ");
10702            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10703            Slog.i(TAG, sb.toString());
10704
10705            // If at least 1/3 of our time since the last idle period has been spent
10706            // with RAM low, then we want to kill processes.
10707            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10708
10709            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10710                ProcessRecord proc = mLruProcesses.get(i);
10711                if (proc.notCachedSinceIdle) {
10712                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10713                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10714                        if (doKilling && proc.initialIdlePss != 0
10715                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10716                            sb = new StringBuilder(128);
10717                            sb.append("Kill");
10718                            sb.append(proc.processName);
10719                            sb.append(" in idle maint: pss=");
10720                            sb.append(proc.lastPss);
10721                            sb.append(", initialPss=");
10722                            sb.append(proc.initialIdlePss);
10723                            sb.append(", period=");
10724                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10725                            sb.append(", lowRamPeriod=");
10726                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10727                            Slog.wtfQuiet(TAG, sb.toString());
10728                            proc.kill("idle maint (pss " + proc.lastPss
10729                                    + " from " + proc.initialIdlePss + ")", true);
10730                        }
10731                    }
10732                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10733                    proc.notCachedSinceIdle = true;
10734                    proc.initialIdlePss = 0;
10735                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10736                            mTestPssMode, isSleeping(), now);
10737                }
10738            }
10739
10740            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10741            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10742        }
10743    }
10744
10745    private void retrieveSettings() {
10746        final ContentResolver resolver = mContext.getContentResolver();
10747        String debugApp = Settings.Global.getString(
10748            resolver, Settings.Global.DEBUG_APP);
10749        boolean waitForDebugger = Settings.Global.getInt(
10750            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10751        boolean alwaysFinishActivities = Settings.Global.getInt(
10752            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10753        boolean forceRtl = Settings.Global.getInt(
10754                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10755        // Transfer any global setting for forcing RTL layout, into a System Property
10756        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10757
10758        Configuration configuration = new Configuration();
10759        Settings.System.getConfiguration(resolver, configuration);
10760        if (forceRtl) {
10761            // This will take care of setting the correct layout direction flags
10762            configuration.setLayoutDirection(configuration.locale);
10763        }
10764
10765        synchronized (this) {
10766            mDebugApp = mOrigDebugApp = debugApp;
10767            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10768            mAlwaysFinishActivities = alwaysFinishActivities;
10769            // This happens before any activities are started, so we can
10770            // change mConfiguration in-place.
10771            updateConfigurationLocked(configuration, null, false, true);
10772            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
10773                    "Initial config: " + mConfiguration);
10774        }
10775    }
10776
10777    /** Loads resources after the current configuration has been set. */
10778    private void loadResourcesOnSystemReady() {
10779        final Resources res = mContext.getResources();
10780        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10781        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10782        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10783    }
10784
10785    public boolean testIsSystemReady() {
10786        // no need to synchronize(this) just to read & return the value
10787        return mSystemReady;
10788    }
10789
10790    private static File getCalledPreBootReceiversFile() {
10791        File dataDir = Environment.getDataDirectory();
10792        File systemDir = new File(dataDir, "system");
10793        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10794        return fname;
10795    }
10796
10797    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10798        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10799        File file = getCalledPreBootReceiversFile();
10800        FileInputStream fis = null;
10801        try {
10802            fis = new FileInputStream(file);
10803            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10804            int fvers = dis.readInt();
10805            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10806                String vers = dis.readUTF();
10807                String codename = dis.readUTF();
10808                String build = dis.readUTF();
10809                if (android.os.Build.VERSION.RELEASE.equals(vers)
10810                        && android.os.Build.VERSION.CODENAME.equals(codename)
10811                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10812                    int num = dis.readInt();
10813                    while (num > 0) {
10814                        num--;
10815                        String pkg = dis.readUTF();
10816                        String cls = dis.readUTF();
10817                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10818                    }
10819                }
10820            }
10821        } catch (FileNotFoundException e) {
10822        } catch (IOException e) {
10823            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10824        } finally {
10825            if (fis != null) {
10826                try {
10827                    fis.close();
10828                } catch (IOException e) {
10829                }
10830            }
10831        }
10832        return lastDoneReceivers;
10833    }
10834
10835    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10836        File file = getCalledPreBootReceiversFile();
10837        FileOutputStream fos = null;
10838        DataOutputStream dos = null;
10839        try {
10840            fos = new FileOutputStream(file);
10841            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10842            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10843            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10844            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10845            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10846            dos.writeInt(list.size());
10847            for (int i=0; i<list.size(); i++) {
10848                dos.writeUTF(list.get(i).getPackageName());
10849                dos.writeUTF(list.get(i).getClassName());
10850            }
10851        } catch (IOException e) {
10852            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10853            file.delete();
10854        } finally {
10855            FileUtils.sync(fos);
10856            if (dos != null) {
10857                try {
10858                    dos.close();
10859                } catch (IOException e) {
10860                    // TODO Auto-generated catch block
10861                    e.printStackTrace();
10862                }
10863            }
10864        }
10865    }
10866
10867    final class PreBootContinuation extends IIntentReceiver.Stub {
10868        final Intent intent;
10869        final Runnable onFinishCallback;
10870        final ArrayList<ComponentName> doneReceivers;
10871        final List<ResolveInfo> ris;
10872        final int[] users;
10873        int lastRi = -1;
10874        int curRi = 0;
10875        int curUser = 0;
10876
10877        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
10878                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
10879            intent = _intent;
10880            onFinishCallback = _onFinishCallback;
10881            doneReceivers = _doneReceivers;
10882            ris = _ris;
10883            users = _users;
10884        }
10885
10886        void go() {
10887            if (lastRi != curRi) {
10888                ActivityInfo ai = ris.get(curRi).activityInfo;
10889                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10890                intent.setComponent(comp);
10891                doneReceivers.add(comp);
10892                lastRi = curRi;
10893                CharSequence label = ai.loadLabel(mContext.getPackageManager());
10894                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
10895            }
10896            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
10897                    + " for user " + users[curUser]);
10898            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
10899            broadcastIntentLocked(null, null, intent, null, this,
10900                    0, null, null, null, AppOpsManager.OP_NONE,
10901                    true, false, MY_PID, Process.SYSTEM_UID,
10902                    users[curUser]);
10903        }
10904
10905        public void performReceive(Intent intent, int resultCode,
10906                String data, Bundle extras, boolean ordered,
10907                boolean sticky, int sendingUser) {
10908            curUser++;
10909            if (curUser >= users.length) {
10910                curUser = 0;
10911                curRi++;
10912                if (curRi >= ris.size()) {
10913                    // All done sending broadcasts!
10914                    if (onFinishCallback != null) {
10915                        // The raw IIntentReceiver interface is called
10916                        // with the AM lock held, so redispatch to
10917                        // execute our code without the lock.
10918                        mHandler.post(onFinishCallback);
10919                    }
10920                    return;
10921                }
10922            }
10923            go();
10924        }
10925    }
10926
10927    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10928            ArrayList<ComponentName> doneReceivers, int userId) {
10929        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10930        List<ResolveInfo> ris = null;
10931        try {
10932            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10933                    intent, null, 0, userId);
10934        } catch (RemoteException e) {
10935        }
10936        if (ris == null) {
10937            return false;
10938        }
10939        for (int i=ris.size()-1; i>=0; i--) {
10940            if ((ris.get(i).activityInfo.applicationInfo.flags
10941                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
10942                ris.remove(i);
10943            }
10944        }
10945        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10946
10947        // For User 0, load the version number. When delivering to a new user, deliver
10948        // to all receivers.
10949        if (userId == UserHandle.USER_OWNER) {
10950            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10951            for (int i=0; i<ris.size(); i++) {
10952                ActivityInfo ai = ris.get(i).activityInfo;
10953                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10954                if (false && lastDoneReceivers.contains(comp)) {
10955                    // We already did the pre boot receiver for this app with the current
10956                    // platform version, so don't do it again...
10957                    ris.remove(i);
10958                    i--;
10959                    // ...however, do keep it as one that has been done, so we don't
10960                    // forget about it when rewriting the file of last done receivers.
10961                    doneReceivers.add(comp);
10962                }
10963            }
10964        }
10965
10966        if (ris.size() <= 0) {
10967            return false;
10968        }
10969
10970        // If primary user, send broadcast to all available users, else just to userId
10971        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10972                : new int[] { userId };
10973        if (users.length <= 0) {
10974            return false;
10975        }
10976
10977        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
10978                ris, users);
10979        cont.go();
10980        return true;
10981    }
10982
10983    public void systemReady(final Runnable goingCallback) {
10984        synchronized(this) {
10985            if (mSystemReady) {
10986                // If we're done calling all the receivers, run the next "boot phase" passed in
10987                // by the SystemServer
10988                if (goingCallback != null) {
10989                    goingCallback.run();
10990                }
10991                return;
10992            }
10993
10994            // Make sure we have the current profile info, since it is needed for
10995            // security checks.
10996            updateCurrentProfileIdsLocked();
10997
10998            mRecentTasks.clear();
10999            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11000            mTaskPersister.restoreTasksFromOtherDeviceLocked();
11001            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11002            mTaskPersister.startPersisting();
11003
11004            // Check to see if there are any update receivers to run.
11005            if (!mDidUpdate) {
11006                if (mWaitingUpdate) {
11007                    return;
11008                }
11009                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11010                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11011                    public void run() {
11012                        synchronized (ActivityManagerService.this) {
11013                            mDidUpdate = true;
11014                        }
11015                        showBootMessage(mContext.getText(
11016                                R.string.android_upgrading_complete),
11017                                false);
11018                        writeLastDonePreBootReceivers(doneReceivers);
11019                        systemReady(goingCallback);
11020                    }
11021                }, doneReceivers, UserHandle.USER_OWNER);
11022
11023                if (mWaitingUpdate) {
11024                    return;
11025                }
11026                mDidUpdate = true;
11027            }
11028
11029            mAppOpsService.systemReady();
11030            mSystemReady = true;
11031        }
11032
11033        ArrayList<ProcessRecord> procsToKill = null;
11034        synchronized(mPidsSelfLocked) {
11035            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11036                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11037                if (!isAllowedWhileBooting(proc.info)){
11038                    if (procsToKill == null) {
11039                        procsToKill = new ArrayList<ProcessRecord>();
11040                    }
11041                    procsToKill.add(proc);
11042                }
11043            }
11044        }
11045
11046        synchronized(this) {
11047            if (procsToKill != null) {
11048                for (int i=procsToKill.size()-1; i>=0; i--) {
11049                    ProcessRecord proc = procsToKill.get(i);
11050                    Slog.i(TAG, "Removing system update proc: " + proc);
11051                    removeProcessLocked(proc, true, false, "system update done");
11052                }
11053            }
11054
11055            // Now that we have cleaned up any update processes, we
11056            // are ready to start launching real processes and know that
11057            // we won't trample on them any more.
11058            mProcessesReady = true;
11059        }
11060
11061        Slog.i(TAG, "System now ready");
11062        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11063            SystemClock.uptimeMillis());
11064
11065        synchronized(this) {
11066            // Make sure we have no pre-ready processes sitting around.
11067
11068            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11069                ResolveInfo ri = mContext.getPackageManager()
11070                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11071                                STOCK_PM_FLAGS);
11072                CharSequence errorMsg = null;
11073                if (ri != null) {
11074                    ActivityInfo ai = ri.activityInfo;
11075                    ApplicationInfo app = ai.applicationInfo;
11076                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11077                        mTopAction = Intent.ACTION_FACTORY_TEST;
11078                        mTopData = null;
11079                        mTopComponent = new ComponentName(app.packageName,
11080                                ai.name);
11081                    } else {
11082                        errorMsg = mContext.getResources().getText(
11083                                com.android.internal.R.string.factorytest_not_system);
11084                    }
11085                } else {
11086                    errorMsg = mContext.getResources().getText(
11087                            com.android.internal.R.string.factorytest_no_action);
11088                }
11089                if (errorMsg != null) {
11090                    mTopAction = null;
11091                    mTopData = null;
11092                    mTopComponent = null;
11093                    Message msg = Message.obtain();
11094                    msg.what = SHOW_FACTORY_ERROR_MSG;
11095                    msg.getData().putCharSequence("msg", errorMsg);
11096                    mHandler.sendMessage(msg);
11097                }
11098            }
11099        }
11100
11101        retrieveSettings();
11102        loadResourcesOnSystemReady();
11103
11104        synchronized (this) {
11105            readGrantedUriPermissionsLocked();
11106        }
11107
11108        if (goingCallback != null) goingCallback.run();
11109
11110        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11111                Integer.toString(mCurrentUserId), mCurrentUserId);
11112        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11113                Integer.toString(mCurrentUserId), mCurrentUserId);
11114        mSystemServiceManager.startUser(mCurrentUserId);
11115
11116        synchronized (this) {
11117            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11118                try {
11119                    List apps = AppGlobals.getPackageManager().
11120                        getPersistentApplications(STOCK_PM_FLAGS);
11121                    if (apps != null) {
11122                        int N = apps.size();
11123                        int i;
11124                        for (i=0; i<N; i++) {
11125                            ApplicationInfo info
11126                                = (ApplicationInfo)apps.get(i);
11127                            if (info != null &&
11128                                    !info.packageName.equals("android")) {
11129                                addAppLocked(info, false, null /* ABI override */);
11130                            }
11131                        }
11132                    }
11133                } catch (RemoteException ex) {
11134                    // pm is in same process, this will never happen.
11135                }
11136            }
11137
11138            // Start up initial activity.
11139            mBooting = true;
11140            startHomeActivityLocked(mCurrentUserId, "systemReady");
11141
11142            try {
11143                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11144                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11145                            + " data partition or your device will be unstable.");
11146                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11147                }
11148            } catch (RemoteException e) {
11149            }
11150
11151            if (!Build.isBuildConsistent()) {
11152                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11153                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11154            }
11155
11156            long ident = Binder.clearCallingIdentity();
11157            try {
11158                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11159                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11160                        | Intent.FLAG_RECEIVER_FOREGROUND);
11161                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11162                broadcastIntentLocked(null, null, intent,
11163                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11164                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11165                intent = new Intent(Intent.ACTION_USER_STARTING);
11166                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11167                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11168                broadcastIntentLocked(null, null, intent,
11169                        null, new IIntentReceiver.Stub() {
11170                            @Override
11171                            public void performReceive(Intent intent, int resultCode, String data,
11172                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11173                                    throws RemoteException {
11174                            }
11175                        }, 0, null, null,
11176                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11177                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11178            } catch (Throwable t) {
11179                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11180            } finally {
11181                Binder.restoreCallingIdentity(ident);
11182            }
11183            mStackSupervisor.resumeTopActivitiesLocked();
11184            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11185        }
11186    }
11187
11188    private boolean makeAppCrashingLocked(ProcessRecord app,
11189            String shortMsg, String longMsg, String stackTrace) {
11190        app.crashing = true;
11191        app.crashingReport = generateProcessError(app,
11192                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11193        startAppProblemLocked(app);
11194        app.stopFreezingAllLocked();
11195        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11196    }
11197
11198    private void makeAppNotRespondingLocked(ProcessRecord app,
11199            String activity, String shortMsg, String longMsg) {
11200        app.notResponding = true;
11201        app.notRespondingReport = generateProcessError(app,
11202                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11203                activity, shortMsg, longMsg, null);
11204        startAppProblemLocked(app);
11205        app.stopFreezingAllLocked();
11206    }
11207
11208    /**
11209     * Generate a process error record, suitable for attachment to a ProcessRecord.
11210     *
11211     * @param app The ProcessRecord in which the error occurred.
11212     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11213     *                      ActivityManager.AppErrorStateInfo
11214     * @param activity The activity associated with the crash, if known.
11215     * @param shortMsg Short message describing the crash.
11216     * @param longMsg Long message describing the crash.
11217     * @param stackTrace Full crash stack trace, may be null.
11218     *
11219     * @return Returns a fully-formed AppErrorStateInfo record.
11220     */
11221    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11222            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11223        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11224
11225        report.condition = condition;
11226        report.processName = app.processName;
11227        report.pid = app.pid;
11228        report.uid = app.info.uid;
11229        report.tag = activity;
11230        report.shortMsg = shortMsg;
11231        report.longMsg = longMsg;
11232        report.stackTrace = stackTrace;
11233
11234        return report;
11235    }
11236
11237    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11238        synchronized (this) {
11239            app.crashing = false;
11240            app.crashingReport = null;
11241            app.notResponding = false;
11242            app.notRespondingReport = null;
11243            if (app.anrDialog == fromDialog) {
11244                app.anrDialog = null;
11245            }
11246            if (app.waitDialog == fromDialog) {
11247                app.waitDialog = null;
11248            }
11249            if (app.pid > 0 && app.pid != MY_PID) {
11250                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11251                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11252                app.kill("user request after error", true);
11253            }
11254        }
11255    }
11256
11257    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11258            String shortMsg, String longMsg, String stackTrace) {
11259        long now = SystemClock.uptimeMillis();
11260
11261        Long crashTime;
11262        if (!app.isolated) {
11263            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11264        } else {
11265            crashTime = null;
11266        }
11267        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11268            // This process loses!
11269            Slog.w(TAG, "Process " + app.info.processName
11270                    + " has crashed too many times: killing!");
11271            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11272                    app.userId, app.info.processName, app.uid);
11273            mStackSupervisor.handleAppCrashLocked(app);
11274            if (!app.persistent) {
11275                // We don't want to start this process again until the user
11276                // explicitly does so...  but for persistent process, we really
11277                // need to keep it running.  If a persistent process is actually
11278                // repeatedly crashing, then badness for everyone.
11279                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11280                        app.info.processName);
11281                if (!app.isolated) {
11282                    // XXX We don't have a way to mark isolated processes
11283                    // as bad, since they don't have a peristent identity.
11284                    mBadProcesses.put(app.info.processName, app.uid,
11285                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11286                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11287                }
11288                app.bad = true;
11289                app.removed = true;
11290                // Don't let services in this process be restarted and potentially
11291                // annoy the user repeatedly.  Unless it is persistent, since those
11292                // processes run critical code.
11293                removeProcessLocked(app, false, false, "crash");
11294                mStackSupervisor.resumeTopActivitiesLocked();
11295                return false;
11296            }
11297            mStackSupervisor.resumeTopActivitiesLocked();
11298        } else {
11299            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11300        }
11301
11302        // Bump up the crash count of any services currently running in the proc.
11303        for (int i=app.services.size()-1; i>=0; i--) {
11304            // Any services running in the application need to be placed
11305            // back in the pending list.
11306            ServiceRecord sr = app.services.valueAt(i);
11307            sr.crashCount++;
11308        }
11309
11310        // If the crashing process is what we consider to be the "home process" and it has been
11311        // replaced by a third-party app, clear the package preferred activities from packages
11312        // with a home activity running in the process to prevent a repeatedly crashing app
11313        // from blocking the user to manually clear the list.
11314        final ArrayList<ActivityRecord> activities = app.activities;
11315        if (app == mHomeProcess && activities.size() > 0
11316                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11317            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11318                final ActivityRecord r = activities.get(activityNdx);
11319                if (r.isHomeActivity()) {
11320                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11321                    try {
11322                        ActivityThread.getPackageManager()
11323                                .clearPackagePreferredActivities(r.packageName);
11324                    } catch (RemoteException c) {
11325                        // pm is in same process, this will never happen.
11326                    }
11327                }
11328            }
11329        }
11330
11331        if (!app.isolated) {
11332            // XXX Can't keep track of crash times for isolated processes,
11333            // because they don't have a perisistent identity.
11334            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11335        }
11336
11337        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11338        return true;
11339    }
11340
11341    void startAppProblemLocked(ProcessRecord app) {
11342        // If this app is not running under the current user, then we
11343        // can't give it a report button because that would require
11344        // launching the report UI under a different user.
11345        app.errorReportReceiver = null;
11346
11347        for (int userId : mCurrentProfileIds) {
11348            if (app.userId == userId) {
11349                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11350                        mContext, app.info.packageName, app.info.flags);
11351            }
11352        }
11353        skipCurrentReceiverLocked(app);
11354    }
11355
11356    void skipCurrentReceiverLocked(ProcessRecord app) {
11357        for (BroadcastQueue queue : mBroadcastQueues) {
11358            queue.skipCurrentReceiverLocked(app);
11359        }
11360    }
11361
11362    /**
11363     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11364     * The application process will exit immediately after this call returns.
11365     * @param app object of the crashing app, null for the system server
11366     * @param crashInfo describing the exception
11367     */
11368    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11369        ProcessRecord r = findAppProcess(app, "Crash");
11370        final String processName = app == null ? "system_server"
11371                : (r == null ? "unknown" : r.processName);
11372
11373        handleApplicationCrashInner("crash", r, processName, crashInfo);
11374    }
11375
11376    /* Native crash reporting uses this inner version because it needs to be somewhat
11377     * decoupled from the AM-managed cleanup lifecycle
11378     */
11379    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11380            ApplicationErrorReport.CrashInfo crashInfo) {
11381        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11382                UserHandle.getUserId(Binder.getCallingUid()), processName,
11383                r == null ? -1 : r.info.flags,
11384                crashInfo.exceptionClassName,
11385                crashInfo.exceptionMessage,
11386                crashInfo.throwFileName,
11387                crashInfo.throwLineNumber);
11388
11389        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11390
11391        crashApplication(r, crashInfo);
11392    }
11393
11394    public void handleApplicationStrictModeViolation(
11395            IBinder app,
11396            int violationMask,
11397            StrictMode.ViolationInfo info) {
11398        ProcessRecord r = findAppProcess(app, "StrictMode");
11399        if (r == null) {
11400            return;
11401        }
11402
11403        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11404            Integer stackFingerprint = info.hashCode();
11405            boolean logIt = true;
11406            synchronized (mAlreadyLoggedViolatedStacks) {
11407                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11408                    logIt = false;
11409                    // TODO: sub-sample into EventLog for these, with
11410                    // the info.durationMillis?  Then we'd get
11411                    // the relative pain numbers, without logging all
11412                    // the stack traces repeatedly.  We'd want to do
11413                    // likewise in the client code, which also does
11414                    // dup suppression, before the Binder call.
11415                } else {
11416                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11417                        mAlreadyLoggedViolatedStacks.clear();
11418                    }
11419                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11420                }
11421            }
11422            if (logIt) {
11423                logStrictModeViolationToDropBox(r, info);
11424            }
11425        }
11426
11427        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11428            AppErrorResult result = new AppErrorResult();
11429            synchronized (this) {
11430                final long origId = Binder.clearCallingIdentity();
11431
11432                Message msg = Message.obtain();
11433                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11434                HashMap<String, Object> data = new HashMap<String, Object>();
11435                data.put("result", result);
11436                data.put("app", r);
11437                data.put("violationMask", violationMask);
11438                data.put("info", info);
11439                msg.obj = data;
11440                mHandler.sendMessage(msg);
11441
11442                Binder.restoreCallingIdentity(origId);
11443            }
11444            int res = result.get();
11445            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11446        }
11447    }
11448
11449    // Depending on the policy in effect, there could be a bunch of
11450    // these in quick succession so we try to batch these together to
11451    // minimize disk writes, number of dropbox entries, and maximize
11452    // compression, by having more fewer, larger records.
11453    private void logStrictModeViolationToDropBox(
11454            ProcessRecord process,
11455            StrictMode.ViolationInfo info) {
11456        if (info == null) {
11457            return;
11458        }
11459        final boolean isSystemApp = process == null ||
11460                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11461                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11462        final String processName = process == null ? "unknown" : process.processName;
11463        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11464        final DropBoxManager dbox = (DropBoxManager)
11465                mContext.getSystemService(Context.DROPBOX_SERVICE);
11466
11467        // Exit early if the dropbox isn't configured to accept this report type.
11468        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11469
11470        boolean bufferWasEmpty;
11471        boolean needsFlush;
11472        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11473        synchronized (sb) {
11474            bufferWasEmpty = sb.length() == 0;
11475            appendDropBoxProcessHeaders(process, processName, sb);
11476            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11477            sb.append("System-App: ").append(isSystemApp).append("\n");
11478            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11479            if (info.violationNumThisLoop != 0) {
11480                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11481            }
11482            if (info.numAnimationsRunning != 0) {
11483                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11484            }
11485            if (info.broadcastIntentAction != null) {
11486                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11487            }
11488            if (info.durationMillis != -1) {
11489                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11490            }
11491            if (info.numInstances != -1) {
11492                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11493            }
11494            if (info.tags != null) {
11495                for (String tag : info.tags) {
11496                    sb.append("Span-Tag: ").append(tag).append("\n");
11497                }
11498            }
11499            sb.append("\n");
11500            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11501                sb.append(info.crashInfo.stackTrace);
11502                sb.append("\n");
11503            }
11504            if (info.message != null) {
11505                sb.append(info.message);
11506                sb.append("\n");
11507            }
11508
11509            // Only buffer up to ~64k.  Various logging bits truncate
11510            // things at 128k.
11511            needsFlush = (sb.length() > 64 * 1024);
11512        }
11513
11514        // Flush immediately if the buffer's grown too large, or this
11515        // is a non-system app.  Non-system apps are isolated with a
11516        // different tag & policy and not batched.
11517        //
11518        // Batching is useful during internal testing with
11519        // StrictMode settings turned up high.  Without batching,
11520        // thousands of separate files could be created on boot.
11521        if (!isSystemApp || needsFlush) {
11522            new Thread("Error dump: " + dropboxTag) {
11523                @Override
11524                public void run() {
11525                    String report;
11526                    synchronized (sb) {
11527                        report = sb.toString();
11528                        sb.delete(0, sb.length());
11529                        sb.trimToSize();
11530                    }
11531                    if (report.length() != 0) {
11532                        dbox.addText(dropboxTag, report);
11533                    }
11534                }
11535            }.start();
11536            return;
11537        }
11538
11539        // System app batching:
11540        if (!bufferWasEmpty) {
11541            // An existing dropbox-writing thread is outstanding, so
11542            // we don't need to start it up.  The existing thread will
11543            // catch the buffer appends we just did.
11544            return;
11545        }
11546
11547        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11548        // (After this point, we shouldn't access AMS internal data structures.)
11549        new Thread("Error dump: " + dropboxTag) {
11550            @Override
11551            public void run() {
11552                // 5 second sleep to let stacks arrive and be batched together
11553                try {
11554                    Thread.sleep(5000);  // 5 seconds
11555                } catch (InterruptedException e) {}
11556
11557                String errorReport;
11558                synchronized (mStrictModeBuffer) {
11559                    errorReport = mStrictModeBuffer.toString();
11560                    if (errorReport.length() == 0) {
11561                        return;
11562                    }
11563                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11564                    mStrictModeBuffer.trimToSize();
11565                }
11566                dbox.addText(dropboxTag, errorReport);
11567            }
11568        }.start();
11569    }
11570
11571    /**
11572     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11573     * @param app object of the crashing app, null for the system server
11574     * @param tag reported by the caller
11575     * @param system whether this wtf is coming from the system
11576     * @param crashInfo describing the context of the error
11577     * @return true if the process should exit immediately (WTF is fatal)
11578     */
11579    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11580            final ApplicationErrorReport.CrashInfo crashInfo) {
11581        final int callingUid = Binder.getCallingUid();
11582        final int callingPid = Binder.getCallingPid();
11583
11584        if (system) {
11585            // If this is coming from the system, we could very well have low-level
11586            // system locks held, so we want to do this all asynchronously.  And we
11587            // never want this to become fatal, so there is that too.
11588            mHandler.post(new Runnable() {
11589                @Override public void run() {
11590                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11591                }
11592            });
11593            return false;
11594        }
11595
11596        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11597                crashInfo);
11598
11599        if (r != null && r.pid != Process.myPid() &&
11600                Settings.Global.getInt(mContext.getContentResolver(),
11601                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11602            crashApplication(r, crashInfo);
11603            return true;
11604        } else {
11605            return false;
11606        }
11607    }
11608
11609    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11610            final ApplicationErrorReport.CrashInfo crashInfo) {
11611        final ProcessRecord r = findAppProcess(app, "WTF");
11612        final String processName = app == null ? "system_server"
11613                : (r == null ? "unknown" : r.processName);
11614
11615        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11616                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11617
11618        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11619
11620        return r;
11621    }
11622
11623    /**
11624     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11625     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11626     */
11627    private ProcessRecord findAppProcess(IBinder app, String reason) {
11628        if (app == null) {
11629            return null;
11630        }
11631
11632        synchronized (this) {
11633            final int NP = mProcessNames.getMap().size();
11634            for (int ip=0; ip<NP; ip++) {
11635                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11636                final int NA = apps.size();
11637                for (int ia=0; ia<NA; ia++) {
11638                    ProcessRecord p = apps.valueAt(ia);
11639                    if (p.thread != null && p.thread.asBinder() == app) {
11640                        return p;
11641                    }
11642                }
11643            }
11644
11645            Slog.w(TAG, "Can't find mystery application for " + reason
11646                    + " from pid=" + Binder.getCallingPid()
11647                    + " uid=" + Binder.getCallingUid() + ": " + app);
11648            return null;
11649        }
11650    }
11651
11652    /**
11653     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11654     * to append various headers to the dropbox log text.
11655     */
11656    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11657            StringBuilder sb) {
11658        // Watchdog thread ends up invoking this function (with
11659        // a null ProcessRecord) to add the stack file to dropbox.
11660        // Do not acquire a lock on this (am) in such cases, as it
11661        // could cause a potential deadlock, if and when watchdog
11662        // is invoked due to unavailability of lock on am and it
11663        // would prevent watchdog from killing system_server.
11664        if (process == null) {
11665            sb.append("Process: ").append(processName).append("\n");
11666            return;
11667        }
11668        // Note: ProcessRecord 'process' is guarded by the service
11669        // instance.  (notably process.pkgList, which could otherwise change
11670        // concurrently during execution of this method)
11671        synchronized (this) {
11672            sb.append("Process: ").append(processName).append("\n");
11673            int flags = process.info.flags;
11674            IPackageManager pm = AppGlobals.getPackageManager();
11675            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11676            for (int ip=0; ip<process.pkgList.size(); ip++) {
11677                String pkg = process.pkgList.keyAt(ip);
11678                sb.append("Package: ").append(pkg);
11679                try {
11680                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11681                    if (pi != null) {
11682                        sb.append(" v").append(pi.versionCode);
11683                        if (pi.versionName != null) {
11684                            sb.append(" (").append(pi.versionName).append(")");
11685                        }
11686                    }
11687                } catch (RemoteException e) {
11688                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11689                }
11690                sb.append("\n");
11691            }
11692        }
11693    }
11694
11695    private static String processClass(ProcessRecord process) {
11696        if (process == null || process.pid == MY_PID) {
11697            return "system_server";
11698        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11699            return "system_app";
11700        } else {
11701            return "data_app";
11702        }
11703    }
11704
11705    /**
11706     * Write a description of an error (crash, WTF, ANR) to the drop box.
11707     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11708     * @param process which caused the error, null means the system server
11709     * @param activity which triggered the error, null if unknown
11710     * @param parent activity related to the error, null if unknown
11711     * @param subject line related to the error, null if absent
11712     * @param report in long form describing the error, null if absent
11713     * @param logFile to include in the report, null if none
11714     * @param crashInfo giving an application stack trace, null if absent
11715     */
11716    public void addErrorToDropBox(String eventType,
11717            ProcessRecord process, String processName, ActivityRecord activity,
11718            ActivityRecord parent, String subject,
11719            final String report, final File logFile,
11720            final ApplicationErrorReport.CrashInfo crashInfo) {
11721        // NOTE -- this must never acquire the ActivityManagerService lock,
11722        // otherwise the watchdog may be prevented from resetting the system.
11723
11724        final String dropboxTag = processClass(process) + "_" + eventType;
11725        final DropBoxManager dbox = (DropBoxManager)
11726                mContext.getSystemService(Context.DROPBOX_SERVICE);
11727
11728        // Exit early if the dropbox isn't configured to accept this report type.
11729        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11730
11731        final StringBuilder sb = new StringBuilder(1024);
11732        appendDropBoxProcessHeaders(process, processName, sb);
11733        if (activity != null) {
11734            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11735        }
11736        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11737            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11738        }
11739        if (parent != null && parent != activity) {
11740            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11741        }
11742        if (subject != null) {
11743            sb.append("Subject: ").append(subject).append("\n");
11744        }
11745        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11746        if (Debug.isDebuggerConnected()) {
11747            sb.append("Debugger: Connected\n");
11748        }
11749        sb.append("\n");
11750
11751        // Do the rest in a worker thread to avoid blocking the caller on I/O
11752        // (After this point, we shouldn't access AMS internal data structures.)
11753        Thread worker = new Thread("Error dump: " + dropboxTag) {
11754            @Override
11755            public void run() {
11756                if (report != null) {
11757                    sb.append(report);
11758                }
11759                if (logFile != null) {
11760                    try {
11761                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11762                                    "\n\n[[TRUNCATED]]"));
11763                    } catch (IOException e) {
11764                        Slog.e(TAG, "Error reading " + logFile, e);
11765                    }
11766                }
11767                if (crashInfo != null && crashInfo.stackTrace != null) {
11768                    sb.append(crashInfo.stackTrace);
11769                }
11770
11771                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11772                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11773                if (lines > 0) {
11774                    sb.append("\n");
11775
11776                    // Merge several logcat streams, and take the last N lines
11777                    InputStreamReader input = null;
11778                    try {
11779                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11780                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11781                                "-b", "crash",
11782                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11783
11784                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11785                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11786                        input = new InputStreamReader(logcat.getInputStream());
11787
11788                        int num;
11789                        char[] buf = new char[8192];
11790                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11791                    } catch (IOException e) {
11792                        Slog.e(TAG, "Error running logcat", e);
11793                    } finally {
11794                        if (input != null) try { input.close(); } catch (IOException e) {}
11795                    }
11796                }
11797
11798                dbox.addText(dropboxTag, sb.toString());
11799            }
11800        };
11801
11802        if (process == null) {
11803            // If process is null, we are being called from some internal code
11804            // and may be about to die -- run this synchronously.
11805            worker.run();
11806        } else {
11807            worker.start();
11808        }
11809    }
11810
11811    /**
11812     * Bring up the "unexpected error" dialog box for a crashing app.
11813     * Deal with edge cases (intercepts from instrumented applications,
11814     * ActivityController, error intent receivers, that sort of thing).
11815     * @param r the application crashing
11816     * @param crashInfo describing the failure
11817     */
11818    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11819        long timeMillis = System.currentTimeMillis();
11820        String shortMsg = crashInfo.exceptionClassName;
11821        String longMsg = crashInfo.exceptionMessage;
11822        String stackTrace = crashInfo.stackTrace;
11823        if (shortMsg != null && longMsg != null) {
11824            longMsg = shortMsg + ": " + longMsg;
11825        } else if (shortMsg != null) {
11826            longMsg = shortMsg;
11827        }
11828
11829        AppErrorResult result = new AppErrorResult();
11830        synchronized (this) {
11831            if (mController != null) {
11832                try {
11833                    String name = r != null ? r.processName : null;
11834                    int pid = r != null ? r.pid : Binder.getCallingPid();
11835                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11836                    if (!mController.appCrashed(name, pid,
11837                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11838                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11839                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11840                            Slog.w(TAG, "Skip killing native crashed app " + name
11841                                    + "(" + pid + ") during testing");
11842                        } else {
11843                            Slog.w(TAG, "Force-killing crashed app " + name
11844                                    + " at watcher's request");
11845                            if (r != null) {
11846                                r.kill("crash", true);
11847                            } else {
11848                                // Huh.
11849                                Process.killProcess(pid);
11850                                Process.killProcessGroup(uid, pid);
11851                            }
11852                        }
11853                        return;
11854                    }
11855                } catch (RemoteException e) {
11856                    mController = null;
11857                    Watchdog.getInstance().setActivityController(null);
11858                }
11859            }
11860
11861            final long origId = Binder.clearCallingIdentity();
11862
11863            // If this process is running instrumentation, finish it.
11864            if (r != null && r.instrumentationClass != null) {
11865                Slog.w(TAG, "Error in app " + r.processName
11866                      + " running instrumentation " + r.instrumentationClass + ":");
11867                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11868                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11869                Bundle info = new Bundle();
11870                info.putString("shortMsg", shortMsg);
11871                info.putString("longMsg", longMsg);
11872                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11873                Binder.restoreCallingIdentity(origId);
11874                return;
11875            }
11876
11877            // Log crash in battery stats.
11878            if (r != null) {
11879                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
11880            }
11881
11882            // If we can't identify the process or it's already exceeded its crash quota,
11883            // quit right away without showing a crash dialog.
11884            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11885                Binder.restoreCallingIdentity(origId);
11886                return;
11887            }
11888
11889            Message msg = Message.obtain();
11890            msg.what = SHOW_ERROR_MSG;
11891            HashMap data = new HashMap();
11892            data.put("result", result);
11893            data.put("app", r);
11894            msg.obj = data;
11895            mHandler.sendMessage(msg);
11896
11897            Binder.restoreCallingIdentity(origId);
11898        }
11899
11900        int res = result.get();
11901
11902        Intent appErrorIntent = null;
11903        synchronized (this) {
11904            if (r != null && !r.isolated) {
11905                // XXX Can't keep track of crash time for isolated processes,
11906                // since they don't have a persistent identity.
11907                mProcessCrashTimes.put(r.info.processName, r.uid,
11908                        SystemClock.uptimeMillis());
11909            }
11910            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11911                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11912            }
11913        }
11914
11915        if (appErrorIntent != null) {
11916            try {
11917                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11918            } catch (ActivityNotFoundException e) {
11919                Slog.w(TAG, "bug report receiver dissappeared", e);
11920            }
11921        }
11922    }
11923
11924    Intent createAppErrorIntentLocked(ProcessRecord r,
11925            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11926        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11927        if (report == null) {
11928            return null;
11929        }
11930        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11931        result.setComponent(r.errorReportReceiver);
11932        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11933        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11934        return result;
11935    }
11936
11937    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11938            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11939        if (r.errorReportReceiver == null) {
11940            return null;
11941        }
11942
11943        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11944            return null;
11945        }
11946
11947        ApplicationErrorReport report = new ApplicationErrorReport();
11948        report.packageName = r.info.packageName;
11949        report.installerPackageName = r.errorReportReceiver.getPackageName();
11950        report.processName = r.processName;
11951        report.time = timeMillis;
11952        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11953
11954        if (r.crashing || r.forceCrashReport) {
11955            report.type = ApplicationErrorReport.TYPE_CRASH;
11956            report.crashInfo = crashInfo;
11957        } else if (r.notResponding) {
11958            report.type = ApplicationErrorReport.TYPE_ANR;
11959            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11960
11961            report.anrInfo.activity = r.notRespondingReport.tag;
11962            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11963            report.anrInfo.info = r.notRespondingReport.longMsg;
11964        }
11965
11966        return report;
11967    }
11968
11969    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11970        enforceNotIsolatedCaller("getProcessesInErrorState");
11971        // assume our apps are happy - lazy create the list
11972        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11973
11974        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11975                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11976        int userId = UserHandle.getUserId(Binder.getCallingUid());
11977
11978        synchronized (this) {
11979
11980            // iterate across all processes
11981            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11982                ProcessRecord app = mLruProcesses.get(i);
11983                if (!allUsers && app.userId != userId) {
11984                    continue;
11985                }
11986                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11987                    // This one's in trouble, so we'll generate a report for it
11988                    // crashes are higher priority (in case there's a crash *and* an anr)
11989                    ActivityManager.ProcessErrorStateInfo report = null;
11990                    if (app.crashing) {
11991                        report = app.crashingReport;
11992                    } else if (app.notResponding) {
11993                        report = app.notRespondingReport;
11994                    }
11995
11996                    if (report != null) {
11997                        if (errList == null) {
11998                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11999                        }
12000                        errList.add(report);
12001                    } else {
12002                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12003                                " crashing = " + app.crashing +
12004                                " notResponding = " + app.notResponding);
12005                    }
12006                }
12007            }
12008        }
12009
12010        return errList;
12011    }
12012
12013    static int procStateToImportance(int procState, int memAdj,
12014            ActivityManager.RunningAppProcessInfo currApp) {
12015        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12016        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12017            currApp.lru = memAdj;
12018        } else {
12019            currApp.lru = 0;
12020        }
12021        return imp;
12022    }
12023
12024    private void fillInProcMemInfo(ProcessRecord app,
12025            ActivityManager.RunningAppProcessInfo outInfo) {
12026        outInfo.pid = app.pid;
12027        outInfo.uid = app.info.uid;
12028        if (mHeavyWeightProcess == app) {
12029            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12030        }
12031        if (app.persistent) {
12032            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12033        }
12034        if (app.activities.size() > 0) {
12035            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12036        }
12037        outInfo.lastTrimLevel = app.trimMemoryLevel;
12038        int adj = app.curAdj;
12039        int procState = app.curProcState;
12040        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12041        outInfo.importanceReasonCode = app.adjTypeCode;
12042        outInfo.processState = app.curProcState;
12043    }
12044
12045    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12046        enforceNotIsolatedCaller("getRunningAppProcesses");
12047
12048        final int callingUid = Binder.getCallingUid();
12049
12050        // Lazy instantiation of list
12051        List<ActivityManager.RunningAppProcessInfo> runList = null;
12052        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12053                callingUid) == PackageManager.PERMISSION_GRANTED;
12054        final int userId = UserHandle.getUserId(callingUid);
12055        final boolean allUids = isGetTasksAllowed(
12056                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12057
12058        synchronized (this) {
12059            // Iterate across all processes
12060            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12061                ProcessRecord app = mLruProcesses.get(i);
12062                if ((!allUsers && app.userId != userId)
12063                        || (!allUids && app.uid != callingUid)) {
12064                    continue;
12065                }
12066                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12067                    // Generate process state info for running application
12068                    ActivityManager.RunningAppProcessInfo currApp =
12069                        new ActivityManager.RunningAppProcessInfo(app.processName,
12070                                app.pid, app.getPackageList());
12071                    fillInProcMemInfo(app, currApp);
12072                    if (app.adjSource instanceof ProcessRecord) {
12073                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12074                        currApp.importanceReasonImportance =
12075                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12076                                        app.adjSourceProcState);
12077                    } else if (app.adjSource instanceof ActivityRecord) {
12078                        ActivityRecord r = (ActivityRecord)app.adjSource;
12079                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12080                    }
12081                    if (app.adjTarget instanceof ComponentName) {
12082                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12083                    }
12084                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12085                    //        + " lru=" + currApp.lru);
12086                    if (runList == null) {
12087                        runList = new ArrayList<>();
12088                    }
12089                    runList.add(currApp);
12090                }
12091            }
12092        }
12093        return runList;
12094    }
12095
12096    public List<ApplicationInfo> getRunningExternalApplications() {
12097        enforceNotIsolatedCaller("getRunningExternalApplications");
12098        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12099        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12100        if (runningApps != null && runningApps.size() > 0) {
12101            Set<String> extList = new HashSet<String>();
12102            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12103                if (app.pkgList != null) {
12104                    for (String pkg : app.pkgList) {
12105                        extList.add(pkg);
12106                    }
12107                }
12108            }
12109            IPackageManager pm = AppGlobals.getPackageManager();
12110            for (String pkg : extList) {
12111                try {
12112                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12113                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12114                        retList.add(info);
12115                    }
12116                } catch (RemoteException e) {
12117                }
12118            }
12119        }
12120        return retList;
12121    }
12122
12123    @Override
12124    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12125        enforceNotIsolatedCaller("getMyMemoryState");
12126        synchronized (this) {
12127            ProcessRecord proc;
12128            synchronized (mPidsSelfLocked) {
12129                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12130            }
12131            fillInProcMemInfo(proc, outInfo);
12132        }
12133    }
12134
12135    @Override
12136    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12137        if (checkCallingPermission(android.Manifest.permission.DUMP)
12138                != PackageManager.PERMISSION_GRANTED) {
12139            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12140                    + Binder.getCallingPid()
12141                    + ", uid=" + Binder.getCallingUid()
12142                    + " without permission "
12143                    + android.Manifest.permission.DUMP);
12144            return;
12145        }
12146
12147        boolean dumpAll = false;
12148        boolean dumpClient = false;
12149        String dumpPackage = null;
12150
12151        int opti = 0;
12152        while (opti < args.length) {
12153            String opt = args[opti];
12154            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12155                break;
12156            }
12157            opti++;
12158            if ("-a".equals(opt)) {
12159                dumpAll = true;
12160            } else if ("-c".equals(opt)) {
12161                dumpClient = true;
12162            } else if ("-p".equals(opt)) {
12163                if (opti < args.length) {
12164                    dumpPackage = args[opti];
12165                    opti++;
12166                } else {
12167                    pw.println("Error: -p option requires package argument");
12168                    return;
12169                }
12170                dumpClient = true;
12171            } else if ("-h".equals(opt)) {
12172                pw.println("Activity manager dump options:");
12173                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12174                pw.println("  cmd may be one of:");
12175                pw.println("    a[ctivities]: activity stack state");
12176                pw.println("    r[recents]: recent activities state");
12177                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12178                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12179                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12180                pw.println("    o[om]: out of memory management");
12181                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12182                pw.println("    provider [COMP_SPEC]: provider client-side state");
12183                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12184                pw.println("    as[sociations]: tracked app associations");
12185                pw.println("    service [COMP_SPEC]: service client-side state");
12186                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12187                pw.println("    all: dump all activities");
12188                pw.println("    top: dump the top activity");
12189                pw.println("    write: write all pending state to storage");
12190                pw.println("    track-associations: enable association tracking");
12191                pw.println("    untrack-associations: disable and clear association tracking");
12192                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12193                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12194                pw.println("    a partial substring in a component name, a");
12195                pw.println("    hex object identifier.");
12196                pw.println("  -a: include all available server state.");
12197                pw.println("  -c: include client state.");
12198                pw.println("  -p: limit output to given package.");
12199                return;
12200            } else {
12201                pw.println("Unknown argument: " + opt + "; use -h for help");
12202            }
12203        }
12204
12205        long origId = Binder.clearCallingIdentity();
12206        boolean more = false;
12207        // Is the caller requesting to dump a particular piece of data?
12208        if (opti < args.length) {
12209            String cmd = args[opti];
12210            opti++;
12211            if ("activities".equals(cmd) || "a".equals(cmd)) {
12212                synchronized (this) {
12213                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12214                }
12215            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12216                synchronized (this) {
12217                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12218                }
12219            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12220                String[] newArgs;
12221                String name;
12222                if (opti >= args.length) {
12223                    name = null;
12224                    newArgs = EMPTY_STRING_ARRAY;
12225                } else {
12226                    dumpPackage = args[opti];
12227                    opti++;
12228                    newArgs = new String[args.length - opti];
12229                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12230                            args.length - opti);
12231                }
12232                synchronized (this) {
12233                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12234                }
12235            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12236                String[] newArgs;
12237                String name;
12238                if (opti >= args.length) {
12239                    name = null;
12240                    newArgs = EMPTY_STRING_ARRAY;
12241                } else {
12242                    dumpPackage = args[opti];
12243                    opti++;
12244                    newArgs = new String[args.length - opti];
12245                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12246                            args.length - opti);
12247                }
12248                synchronized (this) {
12249                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12250                }
12251            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12252                String[] newArgs;
12253                String name;
12254                if (opti >= args.length) {
12255                    name = null;
12256                    newArgs = EMPTY_STRING_ARRAY;
12257                } else {
12258                    dumpPackage = args[opti];
12259                    opti++;
12260                    newArgs = new String[args.length - opti];
12261                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12262                            args.length - opti);
12263                }
12264                synchronized (this) {
12265                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12266                }
12267            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12268                synchronized (this) {
12269                    dumpOomLocked(fd, pw, args, opti, true);
12270                }
12271            } else if ("provider".equals(cmd)) {
12272                String[] newArgs;
12273                String name;
12274                if (opti >= args.length) {
12275                    name = null;
12276                    newArgs = EMPTY_STRING_ARRAY;
12277                } else {
12278                    name = args[opti];
12279                    opti++;
12280                    newArgs = new String[args.length - opti];
12281                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12282                }
12283                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12284                    pw.println("No providers match: " + name);
12285                    pw.println("Use -h for help.");
12286                }
12287            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12288                synchronized (this) {
12289                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12290                }
12291            } else if ("service".equals(cmd)) {
12292                String[] newArgs;
12293                String name;
12294                if (opti >= args.length) {
12295                    name = null;
12296                    newArgs = EMPTY_STRING_ARRAY;
12297                } else {
12298                    name = args[opti];
12299                    opti++;
12300                    newArgs = new String[args.length - opti];
12301                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12302                            args.length - opti);
12303                }
12304                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12305                    pw.println("No services match: " + name);
12306                    pw.println("Use -h for help.");
12307                }
12308            } else if ("package".equals(cmd)) {
12309                String[] newArgs;
12310                if (opti >= args.length) {
12311                    pw.println("package: no package name specified");
12312                    pw.println("Use -h for help.");
12313                } else {
12314                    dumpPackage = args[opti];
12315                    opti++;
12316                    newArgs = new String[args.length - opti];
12317                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12318                            args.length - opti);
12319                    args = newArgs;
12320                    opti = 0;
12321                    more = true;
12322                }
12323            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12324                synchronized (this) {
12325                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12326                }
12327            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12328                synchronized (this) {
12329                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12330                }
12331            } else if ("write".equals(cmd)) {
12332                mTaskPersister.flush();
12333                pw.println("All tasks persisted.");
12334                return;
12335            } else if ("track-associations".equals(cmd)) {
12336                synchronized (this) {
12337                    if (!mTrackingAssociations) {
12338                        mTrackingAssociations = true;
12339                        pw.println("Association tracking started.");
12340                    } else {
12341                        pw.println("Association tracking already enabled.");
12342                    }
12343                }
12344                return;
12345            } else if ("untrack-associations".equals(cmd)) {
12346                synchronized (this) {
12347                    if (mTrackingAssociations) {
12348                        mTrackingAssociations = false;
12349                        mAssociations.clear();
12350                        pw.println("Association tracking stopped.");
12351                    } else {
12352                        pw.println("Association tracking not running.");
12353                    }
12354                }
12355                return;
12356            } else {
12357                // Dumping a single activity?
12358                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12359                    pw.println("Bad activity command, or no activities match: " + cmd);
12360                    pw.println("Use -h for help.");
12361                }
12362            }
12363            if (!more) {
12364                Binder.restoreCallingIdentity(origId);
12365                return;
12366            }
12367        }
12368
12369        // No piece of data specified, dump everything.
12370        synchronized (this) {
12371            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12372            pw.println();
12373            if (dumpAll) {
12374                pw.println("-------------------------------------------------------------------------------");
12375            }
12376            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12377            pw.println();
12378            if (dumpAll) {
12379                pw.println("-------------------------------------------------------------------------------");
12380            }
12381            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12382            pw.println();
12383            if (dumpAll) {
12384                pw.println("-------------------------------------------------------------------------------");
12385            }
12386            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12387            pw.println();
12388            if (dumpAll) {
12389                pw.println("-------------------------------------------------------------------------------");
12390            }
12391            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12392            pw.println();
12393            if (dumpAll) {
12394                pw.println("-------------------------------------------------------------------------------");
12395            }
12396            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12397            if (mAssociations.size() > 0) {
12398                pw.println();
12399                if (dumpAll) {
12400                    pw.println("-------------------------------------------------------------------------------");
12401                }
12402                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12403            }
12404            pw.println();
12405            if (dumpAll) {
12406                pw.println("-------------------------------------------------------------------------------");
12407            }
12408            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12409        }
12410        Binder.restoreCallingIdentity(origId);
12411    }
12412
12413    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12414            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12415        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12416
12417        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12418                dumpPackage);
12419        boolean needSep = printedAnything;
12420
12421        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12422                dumpPackage, needSep, "  mFocusedActivity: ");
12423        if (printed) {
12424            printedAnything = true;
12425            needSep = false;
12426        }
12427
12428        if (dumpPackage == null) {
12429            if (needSep) {
12430                pw.println();
12431            }
12432            needSep = true;
12433            printedAnything = true;
12434            mStackSupervisor.dump(pw, "  ");
12435        }
12436
12437        if (!printedAnything) {
12438            pw.println("  (nothing)");
12439        }
12440    }
12441
12442    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12443            int opti, boolean dumpAll, String dumpPackage) {
12444        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12445
12446        boolean printedAnything = false;
12447
12448        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12449            boolean printedHeader = false;
12450
12451            final int N = mRecentTasks.size();
12452            for (int i=0; i<N; i++) {
12453                TaskRecord tr = mRecentTasks.get(i);
12454                if (dumpPackage != null) {
12455                    if (tr.realActivity == null ||
12456                            !dumpPackage.equals(tr.realActivity)) {
12457                        continue;
12458                    }
12459                }
12460                if (!printedHeader) {
12461                    pw.println("  Recent tasks:");
12462                    printedHeader = true;
12463                    printedAnything = true;
12464                }
12465                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12466                        pw.println(tr);
12467                if (dumpAll) {
12468                    mRecentTasks.get(i).dump(pw, "    ");
12469                }
12470            }
12471        }
12472
12473        if (!printedAnything) {
12474            pw.println("  (nothing)");
12475        }
12476    }
12477
12478    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12479            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12480        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12481
12482        int dumpUid = 0;
12483        if (dumpPackage != null) {
12484            IPackageManager pm = AppGlobals.getPackageManager();
12485            try {
12486                dumpUid = pm.getPackageUid(dumpPackage, 0);
12487            } catch (RemoteException e) {
12488            }
12489        }
12490
12491        boolean printedAnything = false;
12492
12493        final long now = SystemClock.uptimeMillis();
12494
12495        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12496            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12497                    = mAssociations.valueAt(i1);
12498            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12499                SparseArray<ArrayMap<String, Association>> sourceUids
12500                        = targetComponents.valueAt(i2);
12501                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12502                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12503                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12504                        Association ass = sourceProcesses.valueAt(i4);
12505                        if (dumpPackage != null) {
12506                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12507                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12508                                continue;
12509                            }
12510                        }
12511                        printedAnything = true;
12512                        pw.print("  ");
12513                        pw.print(ass.mTargetProcess);
12514                        pw.print("/");
12515                        UserHandle.formatUid(pw, ass.mTargetUid);
12516                        pw.print(" <- ");
12517                        pw.print(ass.mSourceProcess);
12518                        pw.print("/");
12519                        UserHandle.formatUid(pw, ass.mSourceUid);
12520                        pw.println();
12521                        pw.print("    via ");
12522                        pw.print(ass.mTargetComponent.flattenToShortString());
12523                        pw.println();
12524                        pw.print("    ");
12525                        long dur = ass.mTime;
12526                        if (ass.mNesting > 0) {
12527                            dur += now - ass.mStartTime;
12528                        }
12529                        TimeUtils.formatDuration(dur, pw);
12530                        pw.print(" (");
12531                        pw.print(ass.mCount);
12532                        pw.println(" times)");
12533                        if (ass.mNesting > 0) {
12534                            pw.print("    ");
12535                            pw.print(" Currently active: ");
12536                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
12537                            pw.println();
12538                        }
12539                    }
12540                }
12541            }
12542
12543        }
12544
12545        if (!printedAnything) {
12546            pw.println("  (nothing)");
12547        }
12548    }
12549
12550    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12551            int opti, boolean dumpAll, String dumpPackage) {
12552        boolean needSep = false;
12553        boolean printedAnything = false;
12554        int numPers = 0;
12555
12556        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12557
12558        if (dumpAll) {
12559            final int NP = mProcessNames.getMap().size();
12560            for (int ip=0; ip<NP; ip++) {
12561                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12562                final int NA = procs.size();
12563                for (int ia=0; ia<NA; ia++) {
12564                    ProcessRecord r = procs.valueAt(ia);
12565                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12566                        continue;
12567                    }
12568                    if (!needSep) {
12569                        pw.println("  All known processes:");
12570                        needSep = true;
12571                        printedAnything = true;
12572                    }
12573                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12574                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12575                        pw.print(" "); pw.println(r);
12576                    r.dump(pw, "    ");
12577                    if (r.persistent) {
12578                        numPers++;
12579                    }
12580                }
12581            }
12582        }
12583
12584        if (mIsolatedProcesses.size() > 0) {
12585            boolean printed = false;
12586            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12587                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12588                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12589                    continue;
12590                }
12591                if (!printed) {
12592                    if (needSep) {
12593                        pw.println();
12594                    }
12595                    pw.println("  Isolated process list (sorted by uid):");
12596                    printedAnything = true;
12597                    printed = true;
12598                    needSep = true;
12599                }
12600                pw.println(String.format("%sIsolated #%2d: %s",
12601                        "    ", i, r.toString()));
12602            }
12603        }
12604
12605        if (mLruProcesses.size() > 0) {
12606            if (needSep) {
12607                pw.println();
12608            }
12609            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12610                    pw.print(" total, non-act at ");
12611                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12612                    pw.print(", non-svc at ");
12613                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12614                    pw.println("):");
12615            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12616            needSep = true;
12617            printedAnything = true;
12618        }
12619
12620        if (dumpAll || dumpPackage != null) {
12621            synchronized (mPidsSelfLocked) {
12622                boolean printed = false;
12623                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12624                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12625                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12626                        continue;
12627                    }
12628                    if (!printed) {
12629                        if (needSep) pw.println();
12630                        needSep = true;
12631                        pw.println("  PID mappings:");
12632                        printed = true;
12633                        printedAnything = true;
12634                    }
12635                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12636                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12637                }
12638            }
12639        }
12640
12641        if (mForegroundProcesses.size() > 0) {
12642            synchronized (mPidsSelfLocked) {
12643                boolean printed = false;
12644                for (int i=0; i<mForegroundProcesses.size(); i++) {
12645                    ProcessRecord r = mPidsSelfLocked.get(
12646                            mForegroundProcesses.valueAt(i).pid);
12647                    if (dumpPackage != null && (r == null
12648                            || !r.pkgList.containsKey(dumpPackage))) {
12649                        continue;
12650                    }
12651                    if (!printed) {
12652                        if (needSep) pw.println();
12653                        needSep = true;
12654                        pw.println("  Foreground Processes:");
12655                        printed = true;
12656                        printedAnything = true;
12657                    }
12658                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12659                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12660                }
12661            }
12662        }
12663
12664        if (mPersistentStartingProcesses.size() > 0) {
12665            if (needSep) pw.println();
12666            needSep = true;
12667            printedAnything = true;
12668            pw.println("  Persisent processes that are starting:");
12669            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12670                    "Starting Norm", "Restarting PERS", dumpPackage);
12671        }
12672
12673        if (mRemovedProcesses.size() > 0) {
12674            if (needSep) pw.println();
12675            needSep = true;
12676            printedAnything = true;
12677            pw.println("  Processes that are being removed:");
12678            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12679                    "Removed Norm", "Removed PERS", dumpPackage);
12680        }
12681
12682        if (mProcessesOnHold.size() > 0) {
12683            if (needSep) pw.println();
12684            needSep = true;
12685            printedAnything = true;
12686            pw.println("  Processes that are on old until the system is ready:");
12687            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12688                    "OnHold Norm", "OnHold PERS", dumpPackage);
12689        }
12690
12691        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12692
12693        if (mProcessCrashTimes.getMap().size() > 0) {
12694            boolean printed = false;
12695            long now = SystemClock.uptimeMillis();
12696            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12697            final int NP = pmap.size();
12698            for (int ip=0; ip<NP; ip++) {
12699                String pname = pmap.keyAt(ip);
12700                SparseArray<Long> uids = pmap.valueAt(ip);
12701                final int N = uids.size();
12702                for (int i=0; i<N; i++) {
12703                    int puid = uids.keyAt(i);
12704                    ProcessRecord r = mProcessNames.get(pname, puid);
12705                    if (dumpPackage != null && (r == null
12706                            || !r.pkgList.containsKey(dumpPackage))) {
12707                        continue;
12708                    }
12709                    if (!printed) {
12710                        if (needSep) pw.println();
12711                        needSep = true;
12712                        pw.println("  Time since processes crashed:");
12713                        printed = true;
12714                        printedAnything = true;
12715                    }
12716                    pw.print("    Process "); pw.print(pname);
12717                            pw.print(" uid "); pw.print(puid);
12718                            pw.print(": last crashed ");
12719                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12720                            pw.println(" ago");
12721                }
12722            }
12723        }
12724
12725        if (mBadProcesses.getMap().size() > 0) {
12726            boolean printed = false;
12727            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12728            final int NP = pmap.size();
12729            for (int ip=0; ip<NP; ip++) {
12730                String pname = pmap.keyAt(ip);
12731                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12732                final int N = uids.size();
12733                for (int i=0; i<N; i++) {
12734                    int puid = uids.keyAt(i);
12735                    ProcessRecord r = mProcessNames.get(pname, puid);
12736                    if (dumpPackage != null && (r == null
12737                            || !r.pkgList.containsKey(dumpPackage))) {
12738                        continue;
12739                    }
12740                    if (!printed) {
12741                        if (needSep) pw.println();
12742                        needSep = true;
12743                        pw.println("  Bad processes:");
12744                        printedAnything = true;
12745                    }
12746                    BadProcessInfo info = uids.valueAt(i);
12747                    pw.print("    Bad process "); pw.print(pname);
12748                            pw.print(" uid "); pw.print(puid);
12749                            pw.print(": crashed at time "); pw.println(info.time);
12750                    if (info.shortMsg != null) {
12751                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12752                    }
12753                    if (info.longMsg != null) {
12754                        pw.print("      Long msg: "); pw.println(info.longMsg);
12755                    }
12756                    if (info.stack != null) {
12757                        pw.println("      Stack:");
12758                        int lastPos = 0;
12759                        for (int pos=0; pos<info.stack.length(); pos++) {
12760                            if (info.stack.charAt(pos) == '\n') {
12761                                pw.print("        ");
12762                                pw.write(info.stack, lastPos, pos-lastPos);
12763                                pw.println();
12764                                lastPos = pos+1;
12765                            }
12766                        }
12767                        if (lastPos < info.stack.length()) {
12768                            pw.print("        ");
12769                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12770                            pw.println();
12771                        }
12772                    }
12773                }
12774            }
12775        }
12776
12777        if (dumpPackage == null) {
12778            pw.println();
12779            needSep = false;
12780            pw.println("  mStartedUsers:");
12781            for (int i=0; i<mStartedUsers.size(); i++) {
12782                UserStartedState uss = mStartedUsers.valueAt(i);
12783                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12784                        pw.print(": "); uss.dump("", pw);
12785            }
12786            pw.print("  mStartedUserArray: [");
12787            for (int i=0; i<mStartedUserArray.length; i++) {
12788                if (i > 0) pw.print(", ");
12789                pw.print(mStartedUserArray[i]);
12790            }
12791            pw.println("]");
12792            pw.print("  mUserLru: [");
12793            for (int i=0; i<mUserLru.size(); i++) {
12794                if (i > 0) pw.print(", ");
12795                pw.print(mUserLru.get(i));
12796            }
12797            pw.println("]");
12798            if (dumpAll) {
12799                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12800            }
12801            synchronized (mUserProfileGroupIdsSelfLocked) {
12802                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12803                    pw.println("  mUserProfileGroupIds:");
12804                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12805                        pw.print("    User #");
12806                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12807                        pw.print(" -> profile #");
12808                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12809                    }
12810                }
12811            }
12812        }
12813        if (mHomeProcess != null && (dumpPackage == null
12814                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12815            if (needSep) {
12816                pw.println();
12817                needSep = false;
12818            }
12819            pw.println("  mHomeProcess: " + mHomeProcess);
12820        }
12821        if (mPreviousProcess != null && (dumpPackage == null
12822                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12823            if (needSep) {
12824                pw.println();
12825                needSep = false;
12826            }
12827            pw.println("  mPreviousProcess: " + mPreviousProcess);
12828        }
12829        if (dumpAll) {
12830            StringBuilder sb = new StringBuilder(128);
12831            sb.append("  mPreviousProcessVisibleTime: ");
12832            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12833            pw.println(sb);
12834        }
12835        if (mHeavyWeightProcess != null && (dumpPackage == null
12836                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12837            if (needSep) {
12838                pw.println();
12839                needSep = false;
12840            }
12841            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12842        }
12843        if (dumpPackage == null) {
12844            pw.println("  mConfiguration: " + mConfiguration);
12845        }
12846        if (dumpAll) {
12847            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12848            if (mCompatModePackages.getPackages().size() > 0) {
12849                boolean printed = false;
12850                for (Map.Entry<String, Integer> entry
12851                        : mCompatModePackages.getPackages().entrySet()) {
12852                    String pkg = entry.getKey();
12853                    int mode = entry.getValue();
12854                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12855                        continue;
12856                    }
12857                    if (!printed) {
12858                        pw.println("  mScreenCompatPackages:");
12859                        printed = true;
12860                    }
12861                    pw.print("    "); pw.print(pkg); pw.print(": ");
12862                            pw.print(mode); pw.println();
12863                }
12864            }
12865        }
12866        if (dumpPackage == null) {
12867            pw.println("  mWakefulness="
12868                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12869            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12870                    + lockScreenShownToString());
12871            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
12872            if (mRunningVoice != null) {
12873                pw.println("  mRunningVoice=" + mRunningVoice);
12874                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
12875            }
12876        }
12877        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12878                || mOrigWaitForDebugger) {
12879            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12880                    || dumpPackage.equals(mOrigDebugApp)) {
12881                if (needSep) {
12882                    pw.println();
12883                    needSep = false;
12884                }
12885                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12886                        + " mDebugTransient=" + mDebugTransient
12887                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12888            }
12889        }
12890        if (mMemWatchProcesses.getMap().size() > 0) {
12891            pw.println("  Mem watch processes:");
12892            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
12893                    = mMemWatchProcesses.getMap();
12894            for (int i=0; i<procs.size(); i++) {
12895                final String proc = procs.keyAt(i);
12896                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
12897                for (int j=0; j<uids.size(); j++) {
12898                    if (needSep) {
12899                        pw.println();
12900                        needSep = false;
12901                    }
12902                    StringBuilder sb = new StringBuilder();
12903                    sb.append("    ").append(proc).append('/');
12904                    UserHandle.formatUid(sb, uids.keyAt(j));
12905                    Pair<Long, String> val = uids.valueAt(i);
12906                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
12907                    if (val.second != null) {
12908                        sb.append(", report to ").append(val.second);
12909                    }
12910                    pw.println(sb.toString());
12911                }
12912            }
12913            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
12914            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
12915            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
12916                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
12917        }
12918        if (mOpenGlTraceApp != null) {
12919            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12920                if (needSep) {
12921                    pw.println();
12922                    needSep = false;
12923                }
12924                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12925            }
12926        }
12927        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12928                || mProfileFd != null) {
12929            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12930                if (needSep) {
12931                    pw.println();
12932                    needSep = false;
12933                }
12934                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12935                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12936                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12937                        + mAutoStopProfiler);
12938                pw.println("  mProfileType=" + mProfileType);
12939            }
12940        }
12941        if (dumpPackage == null) {
12942            if (mAlwaysFinishActivities || mController != null) {
12943                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12944                        + " mController=" + mController);
12945            }
12946            if (dumpAll) {
12947                pw.println("  Total persistent processes: " + numPers);
12948                pw.println("  mProcessesReady=" + mProcessesReady
12949                        + " mSystemReady=" + mSystemReady
12950                        + " mBooted=" + mBooted
12951                        + " mFactoryTest=" + mFactoryTest);
12952                pw.println("  mBooting=" + mBooting
12953                        + " mCallFinishBooting=" + mCallFinishBooting
12954                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12955                pw.print("  mLastPowerCheckRealtime=");
12956                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12957                        pw.println("");
12958                pw.print("  mLastPowerCheckUptime=");
12959                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12960                        pw.println("");
12961                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12962                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12963                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12964                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12965                        + " (" + mLruProcesses.size() + " total)"
12966                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12967                        + " mNumServiceProcs=" + mNumServiceProcs
12968                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12969                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12970                        + " mLastMemoryLevel" + mLastMemoryLevel
12971                        + " mLastNumProcesses" + mLastNumProcesses);
12972                long now = SystemClock.uptimeMillis();
12973                pw.print("  mLastIdleTime=");
12974                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12975                        pw.print(" mLowRamSinceLastIdle=");
12976                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12977                        pw.println();
12978            }
12979        }
12980
12981        if (!printedAnything) {
12982            pw.println("  (nothing)");
12983        }
12984    }
12985
12986    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12987            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12988        if (mProcessesToGc.size() > 0) {
12989            boolean printed = false;
12990            long now = SystemClock.uptimeMillis();
12991            for (int i=0; i<mProcessesToGc.size(); i++) {
12992                ProcessRecord proc = mProcessesToGc.get(i);
12993                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12994                    continue;
12995                }
12996                if (!printed) {
12997                    if (needSep) pw.println();
12998                    needSep = true;
12999                    pw.println("  Processes that are waiting to GC:");
13000                    printed = true;
13001                }
13002                pw.print("    Process "); pw.println(proc);
13003                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13004                        pw.print(", last gced=");
13005                        pw.print(now-proc.lastRequestedGc);
13006                        pw.print(" ms ago, last lowMem=");
13007                        pw.print(now-proc.lastLowMemory);
13008                        pw.println(" ms ago");
13009
13010            }
13011        }
13012        return needSep;
13013    }
13014
13015    void printOomLevel(PrintWriter pw, String name, int adj) {
13016        pw.print("    ");
13017        if (adj >= 0) {
13018            pw.print(' ');
13019            if (adj < 10) pw.print(' ');
13020        } else {
13021            if (adj > -10) pw.print(' ');
13022        }
13023        pw.print(adj);
13024        pw.print(": ");
13025        pw.print(name);
13026        pw.print(" (");
13027        pw.print(mProcessList.getMemLevel(adj)/1024);
13028        pw.println(" kB)");
13029    }
13030
13031    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13032            int opti, boolean dumpAll) {
13033        boolean needSep = false;
13034
13035        if (mLruProcesses.size() > 0) {
13036            if (needSep) pw.println();
13037            needSep = true;
13038            pw.println("  OOM levels:");
13039            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13040            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13041            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13042            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13043            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13044            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13045            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13046            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13047            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13048            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13049            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13050            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13051            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13052            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13053
13054            if (needSep) pw.println();
13055            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13056                    pw.print(" total, non-act at ");
13057                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13058                    pw.print(", non-svc at ");
13059                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13060                    pw.println("):");
13061            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13062            needSep = true;
13063        }
13064
13065        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13066
13067        pw.println();
13068        pw.println("  mHomeProcess: " + mHomeProcess);
13069        pw.println("  mPreviousProcess: " + mPreviousProcess);
13070        if (mHeavyWeightProcess != null) {
13071            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13072        }
13073
13074        return true;
13075    }
13076
13077    /**
13078     * There are three ways to call this:
13079     *  - no provider specified: dump all the providers
13080     *  - a flattened component name that matched an existing provider was specified as the
13081     *    first arg: dump that one provider
13082     *  - the first arg isn't the flattened component name of an existing provider:
13083     *    dump all providers whose component contains the first arg as a substring
13084     */
13085    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13086            int opti, boolean dumpAll) {
13087        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13088    }
13089
13090    static class ItemMatcher {
13091        ArrayList<ComponentName> components;
13092        ArrayList<String> strings;
13093        ArrayList<Integer> objects;
13094        boolean all;
13095
13096        ItemMatcher() {
13097            all = true;
13098        }
13099
13100        void build(String name) {
13101            ComponentName componentName = ComponentName.unflattenFromString(name);
13102            if (componentName != null) {
13103                if (components == null) {
13104                    components = new ArrayList<ComponentName>();
13105                }
13106                components.add(componentName);
13107                all = false;
13108            } else {
13109                int objectId = 0;
13110                // Not a '/' separated full component name; maybe an object ID?
13111                try {
13112                    objectId = Integer.parseInt(name, 16);
13113                    if (objects == null) {
13114                        objects = new ArrayList<Integer>();
13115                    }
13116                    objects.add(objectId);
13117                    all = false;
13118                } catch (RuntimeException e) {
13119                    // Not an integer; just do string match.
13120                    if (strings == null) {
13121                        strings = new ArrayList<String>();
13122                    }
13123                    strings.add(name);
13124                    all = false;
13125                }
13126            }
13127        }
13128
13129        int build(String[] args, int opti) {
13130            for (; opti<args.length; opti++) {
13131                String name = args[opti];
13132                if ("--".equals(name)) {
13133                    return opti+1;
13134                }
13135                build(name);
13136            }
13137            return opti;
13138        }
13139
13140        boolean match(Object object, ComponentName comp) {
13141            if (all) {
13142                return true;
13143            }
13144            if (components != null) {
13145                for (int i=0; i<components.size(); i++) {
13146                    if (components.get(i).equals(comp)) {
13147                        return true;
13148                    }
13149                }
13150            }
13151            if (objects != null) {
13152                for (int i=0; i<objects.size(); i++) {
13153                    if (System.identityHashCode(object) == objects.get(i)) {
13154                        return true;
13155                    }
13156                }
13157            }
13158            if (strings != null) {
13159                String flat = comp.flattenToString();
13160                for (int i=0; i<strings.size(); i++) {
13161                    if (flat.contains(strings.get(i))) {
13162                        return true;
13163                    }
13164                }
13165            }
13166            return false;
13167        }
13168    }
13169
13170    /**
13171     * There are three things that cmd can be:
13172     *  - a flattened component name that matches an existing activity
13173     *  - the cmd arg isn't the flattened component name of an existing activity:
13174     *    dump all activity whose component contains the cmd as a substring
13175     *  - A hex number of the ActivityRecord object instance.
13176     */
13177    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13178            int opti, boolean dumpAll) {
13179        ArrayList<ActivityRecord> activities;
13180
13181        synchronized (this) {
13182            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13183        }
13184
13185        if (activities.size() <= 0) {
13186            return false;
13187        }
13188
13189        String[] newArgs = new String[args.length - opti];
13190        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13191
13192        TaskRecord lastTask = null;
13193        boolean needSep = false;
13194        for (int i=activities.size()-1; i>=0; i--) {
13195            ActivityRecord r = activities.get(i);
13196            if (needSep) {
13197                pw.println();
13198            }
13199            needSep = true;
13200            synchronized (this) {
13201                if (lastTask != r.task) {
13202                    lastTask = r.task;
13203                    pw.print("TASK "); pw.print(lastTask.affinity);
13204                            pw.print(" id="); pw.println(lastTask.taskId);
13205                    if (dumpAll) {
13206                        lastTask.dump(pw, "  ");
13207                    }
13208                }
13209            }
13210            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13211        }
13212        return true;
13213    }
13214
13215    /**
13216     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13217     * there is a thread associated with the activity.
13218     */
13219    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13220            final ActivityRecord r, String[] args, boolean dumpAll) {
13221        String innerPrefix = prefix + "  ";
13222        synchronized (this) {
13223            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13224                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13225                    pw.print(" pid=");
13226                    if (r.app != null) pw.println(r.app.pid);
13227                    else pw.println("(not running)");
13228            if (dumpAll) {
13229                r.dump(pw, innerPrefix);
13230            }
13231        }
13232        if (r.app != null && r.app.thread != null) {
13233            // flush anything that is already in the PrintWriter since the thread is going
13234            // to write to the file descriptor directly
13235            pw.flush();
13236            try {
13237                TransferPipe tp = new TransferPipe();
13238                try {
13239                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13240                            r.appToken, innerPrefix, args);
13241                    tp.go(fd);
13242                } finally {
13243                    tp.kill();
13244                }
13245            } catch (IOException e) {
13246                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13247            } catch (RemoteException e) {
13248                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13249            }
13250        }
13251    }
13252
13253    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13254            int opti, boolean dumpAll, String dumpPackage) {
13255        boolean needSep = false;
13256        boolean onlyHistory = false;
13257        boolean printedAnything = false;
13258
13259        if ("history".equals(dumpPackage)) {
13260            if (opti < args.length && "-s".equals(args[opti])) {
13261                dumpAll = false;
13262            }
13263            onlyHistory = true;
13264            dumpPackage = null;
13265        }
13266
13267        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13268        if (!onlyHistory && dumpAll) {
13269            if (mRegisteredReceivers.size() > 0) {
13270                boolean printed = false;
13271                Iterator it = mRegisteredReceivers.values().iterator();
13272                while (it.hasNext()) {
13273                    ReceiverList r = (ReceiverList)it.next();
13274                    if (dumpPackage != null && (r.app == null ||
13275                            !dumpPackage.equals(r.app.info.packageName))) {
13276                        continue;
13277                    }
13278                    if (!printed) {
13279                        pw.println("  Registered Receivers:");
13280                        needSep = true;
13281                        printed = true;
13282                        printedAnything = true;
13283                    }
13284                    pw.print("  * "); pw.println(r);
13285                    r.dump(pw, "    ");
13286                }
13287            }
13288
13289            if (mReceiverResolver.dump(pw, needSep ?
13290                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13291                    "    ", dumpPackage, false, false)) {
13292                needSep = true;
13293                printedAnything = true;
13294            }
13295        }
13296
13297        for (BroadcastQueue q : mBroadcastQueues) {
13298            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13299            printedAnything |= needSep;
13300        }
13301
13302        needSep = true;
13303
13304        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13305            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13306                if (needSep) {
13307                    pw.println();
13308                }
13309                needSep = true;
13310                printedAnything = true;
13311                pw.print("  Sticky broadcasts for user ");
13312                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13313                StringBuilder sb = new StringBuilder(128);
13314                for (Map.Entry<String, ArrayList<Intent>> ent
13315                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13316                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13317                    if (dumpAll) {
13318                        pw.println(":");
13319                        ArrayList<Intent> intents = ent.getValue();
13320                        final int N = intents.size();
13321                        for (int i=0; i<N; i++) {
13322                            sb.setLength(0);
13323                            sb.append("    Intent: ");
13324                            intents.get(i).toShortString(sb, false, true, false, false);
13325                            pw.println(sb.toString());
13326                            Bundle bundle = intents.get(i).getExtras();
13327                            if (bundle != null) {
13328                                pw.print("      ");
13329                                pw.println(bundle.toString());
13330                            }
13331                        }
13332                    } else {
13333                        pw.println("");
13334                    }
13335                }
13336            }
13337        }
13338
13339        if (!onlyHistory && dumpAll) {
13340            pw.println();
13341            for (BroadcastQueue queue : mBroadcastQueues) {
13342                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13343                        + queue.mBroadcastsScheduled);
13344            }
13345            pw.println("  mHandler:");
13346            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13347            needSep = true;
13348            printedAnything = true;
13349        }
13350
13351        if (!printedAnything) {
13352            pw.println("  (nothing)");
13353        }
13354    }
13355
13356    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13357            int opti, boolean dumpAll, String dumpPackage) {
13358        boolean needSep;
13359        boolean printedAnything = false;
13360
13361        ItemMatcher matcher = new ItemMatcher();
13362        matcher.build(args, opti);
13363
13364        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13365
13366        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13367        printedAnything |= needSep;
13368
13369        if (mLaunchingProviders.size() > 0) {
13370            boolean printed = false;
13371            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13372                ContentProviderRecord r = mLaunchingProviders.get(i);
13373                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13374                    continue;
13375                }
13376                if (!printed) {
13377                    if (needSep) pw.println();
13378                    needSep = true;
13379                    pw.println("  Launching content providers:");
13380                    printed = true;
13381                    printedAnything = true;
13382                }
13383                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13384                        pw.println(r);
13385            }
13386        }
13387
13388        if (mGrantedUriPermissions.size() > 0) {
13389            boolean printed = false;
13390            int dumpUid = -2;
13391            if (dumpPackage != null) {
13392                try {
13393                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13394                } catch (NameNotFoundException e) {
13395                    dumpUid = -1;
13396                }
13397            }
13398            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13399                int uid = mGrantedUriPermissions.keyAt(i);
13400                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13401                    continue;
13402                }
13403                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13404                if (!printed) {
13405                    if (needSep) pw.println();
13406                    needSep = true;
13407                    pw.println("  Granted Uri Permissions:");
13408                    printed = true;
13409                    printedAnything = true;
13410                }
13411                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13412                for (UriPermission perm : perms.values()) {
13413                    pw.print("    "); pw.println(perm);
13414                    if (dumpAll) {
13415                        perm.dump(pw, "      ");
13416                    }
13417                }
13418            }
13419        }
13420
13421        if (!printedAnything) {
13422            pw.println("  (nothing)");
13423        }
13424    }
13425
13426    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13427            int opti, boolean dumpAll, String dumpPackage) {
13428        boolean printed = false;
13429
13430        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13431
13432        if (mIntentSenderRecords.size() > 0) {
13433            Iterator<WeakReference<PendingIntentRecord>> it
13434                    = mIntentSenderRecords.values().iterator();
13435            while (it.hasNext()) {
13436                WeakReference<PendingIntentRecord> ref = it.next();
13437                PendingIntentRecord rec = ref != null ? ref.get(): null;
13438                if (dumpPackage != null && (rec == null
13439                        || !dumpPackage.equals(rec.key.packageName))) {
13440                    continue;
13441                }
13442                printed = true;
13443                if (rec != null) {
13444                    pw.print("  * "); pw.println(rec);
13445                    if (dumpAll) {
13446                        rec.dump(pw, "    ");
13447                    }
13448                } else {
13449                    pw.print("  * "); pw.println(ref);
13450                }
13451            }
13452        }
13453
13454        if (!printed) {
13455            pw.println("  (nothing)");
13456        }
13457    }
13458
13459    private static final int dumpProcessList(PrintWriter pw,
13460            ActivityManagerService service, List list,
13461            String prefix, String normalLabel, String persistentLabel,
13462            String dumpPackage) {
13463        int numPers = 0;
13464        final int N = list.size()-1;
13465        for (int i=N; i>=0; i--) {
13466            ProcessRecord r = (ProcessRecord)list.get(i);
13467            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13468                continue;
13469            }
13470            pw.println(String.format("%s%s #%2d: %s",
13471                    prefix, (r.persistent ? persistentLabel : normalLabel),
13472                    i, r.toString()));
13473            if (r.persistent) {
13474                numPers++;
13475            }
13476        }
13477        return numPers;
13478    }
13479
13480    private static final boolean dumpProcessOomList(PrintWriter pw,
13481            ActivityManagerService service, List<ProcessRecord> origList,
13482            String prefix, String normalLabel, String persistentLabel,
13483            boolean inclDetails, String dumpPackage) {
13484
13485        ArrayList<Pair<ProcessRecord, Integer>> list
13486                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13487        for (int i=0; i<origList.size(); i++) {
13488            ProcessRecord r = origList.get(i);
13489            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13490                continue;
13491            }
13492            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13493        }
13494
13495        if (list.size() <= 0) {
13496            return false;
13497        }
13498
13499        Comparator<Pair<ProcessRecord, Integer>> comparator
13500                = new Comparator<Pair<ProcessRecord, Integer>>() {
13501            @Override
13502            public int compare(Pair<ProcessRecord, Integer> object1,
13503                    Pair<ProcessRecord, Integer> object2) {
13504                if (object1.first.setAdj != object2.first.setAdj) {
13505                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13506                }
13507                if (object1.second.intValue() != object2.second.intValue()) {
13508                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13509                }
13510                return 0;
13511            }
13512        };
13513
13514        Collections.sort(list, comparator);
13515
13516        final long curRealtime = SystemClock.elapsedRealtime();
13517        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13518        final long curUptime = SystemClock.uptimeMillis();
13519        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13520
13521        for (int i=list.size()-1; i>=0; i--) {
13522            ProcessRecord r = list.get(i).first;
13523            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13524            char schedGroup;
13525            switch (r.setSchedGroup) {
13526                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13527                    schedGroup = 'B';
13528                    break;
13529                case Process.THREAD_GROUP_DEFAULT:
13530                    schedGroup = 'F';
13531                    break;
13532                default:
13533                    schedGroup = '?';
13534                    break;
13535            }
13536            char foreground;
13537            if (r.foregroundActivities) {
13538                foreground = 'A';
13539            } else if (r.foregroundServices) {
13540                foreground = 'S';
13541            } else {
13542                foreground = ' ';
13543            }
13544            String procState = ProcessList.makeProcStateString(r.curProcState);
13545            pw.print(prefix);
13546            pw.print(r.persistent ? persistentLabel : normalLabel);
13547            pw.print(" #");
13548            int num = (origList.size()-1)-list.get(i).second;
13549            if (num < 10) pw.print(' ');
13550            pw.print(num);
13551            pw.print(": ");
13552            pw.print(oomAdj);
13553            pw.print(' ');
13554            pw.print(schedGroup);
13555            pw.print('/');
13556            pw.print(foreground);
13557            pw.print('/');
13558            pw.print(procState);
13559            pw.print(" trm:");
13560            if (r.trimMemoryLevel < 10) pw.print(' ');
13561            pw.print(r.trimMemoryLevel);
13562            pw.print(' ');
13563            pw.print(r.toShortString());
13564            pw.print(" (");
13565            pw.print(r.adjType);
13566            pw.println(')');
13567            if (r.adjSource != null || r.adjTarget != null) {
13568                pw.print(prefix);
13569                pw.print("    ");
13570                if (r.adjTarget instanceof ComponentName) {
13571                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13572                } else if (r.adjTarget != null) {
13573                    pw.print(r.adjTarget.toString());
13574                } else {
13575                    pw.print("{null}");
13576                }
13577                pw.print("<=");
13578                if (r.adjSource instanceof ProcessRecord) {
13579                    pw.print("Proc{");
13580                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13581                    pw.println("}");
13582                } else if (r.adjSource != null) {
13583                    pw.println(r.adjSource.toString());
13584                } else {
13585                    pw.println("{null}");
13586                }
13587            }
13588            if (inclDetails) {
13589                pw.print(prefix);
13590                pw.print("    ");
13591                pw.print("oom: max="); pw.print(r.maxAdj);
13592                pw.print(" curRaw="); pw.print(r.curRawAdj);
13593                pw.print(" setRaw="); pw.print(r.setRawAdj);
13594                pw.print(" cur="); pw.print(r.curAdj);
13595                pw.print(" set="); pw.println(r.setAdj);
13596                pw.print(prefix);
13597                pw.print("    ");
13598                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13599                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13600                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
13601                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
13602                pw.println();
13603                pw.print(prefix);
13604                pw.print("    ");
13605                pw.print("cached="); pw.print(r.cached);
13606                pw.print(" empty="); pw.print(r.empty);
13607                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13608
13609                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13610                    if (r.lastWakeTime != 0) {
13611                        long wtime;
13612                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13613                        synchronized (stats) {
13614                            wtime = stats.getProcessWakeTime(r.info.uid,
13615                                    r.pid, curRealtime);
13616                        }
13617                        long timeUsed = wtime - r.lastWakeTime;
13618                        pw.print(prefix);
13619                        pw.print("    ");
13620                        pw.print("keep awake over ");
13621                        TimeUtils.formatDuration(realtimeSince, pw);
13622                        pw.print(" used ");
13623                        TimeUtils.formatDuration(timeUsed, pw);
13624                        pw.print(" (");
13625                        pw.print((timeUsed*100)/realtimeSince);
13626                        pw.println("%)");
13627                    }
13628                    if (r.lastCpuTime != 0) {
13629                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13630                        pw.print(prefix);
13631                        pw.print("    ");
13632                        pw.print("run cpu over ");
13633                        TimeUtils.formatDuration(uptimeSince, pw);
13634                        pw.print(" used ");
13635                        TimeUtils.formatDuration(timeUsed, pw);
13636                        pw.print(" (");
13637                        pw.print((timeUsed*100)/uptimeSince);
13638                        pw.println("%)");
13639                    }
13640                }
13641            }
13642        }
13643        return true;
13644    }
13645
13646    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13647            String[] args) {
13648        ArrayList<ProcessRecord> procs;
13649        synchronized (this) {
13650            if (args != null && args.length > start
13651                    && args[start].charAt(0) != '-') {
13652                procs = new ArrayList<ProcessRecord>();
13653                int pid = -1;
13654                try {
13655                    pid = Integer.parseInt(args[start]);
13656                } catch (NumberFormatException e) {
13657                }
13658                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13659                    ProcessRecord proc = mLruProcesses.get(i);
13660                    if (proc.pid == pid) {
13661                        procs.add(proc);
13662                    } else if (allPkgs && proc.pkgList != null
13663                            && proc.pkgList.containsKey(args[start])) {
13664                        procs.add(proc);
13665                    } else if (proc.processName.equals(args[start])) {
13666                        procs.add(proc);
13667                    }
13668                }
13669                if (procs.size() <= 0) {
13670                    return null;
13671                }
13672            } else {
13673                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13674            }
13675        }
13676        return procs;
13677    }
13678
13679    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13680            PrintWriter pw, String[] args) {
13681        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13682        if (procs == null) {
13683            pw.println("No process found for: " + args[0]);
13684            return;
13685        }
13686
13687        long uptime = SystemClock.uptimeMillis();
13688        long realtime = SystemClock.elapsedRealtime();
13689        pw.println("Applications Graphics Acceleration Info:");
13690        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13691
13692        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13693            ProcessRecord r = procs.get(i);
13694            if (r.thread != null) {
13695                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13696                pw.flush();
13697                try {
13698                    TransferPipe tp = new TransferPipe();
13699                    try {
13700                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13701                        tp.go(fd);
13702                    } finally {
13703                        tp.kill();
13704                    }
13705                } catch (IOException e) {
13706                    pw.println("Failure while dumping the app: " + r);
13707                    pw.flush();
13708                } catch (RemoteException e) {
13709                    pw.println("Got a RemoteException while dumping the app " + r);
13710                    pw.flush();
13711                }
13712            }
13713        }
13714    }
13715
13716    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13717        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13718        if (procs == null) {
13719            pw.println("No process found for: " + args[0]);
13720            return;
13721        }
13722
13723        pw.println("Applications Database Info:");
13724
13725        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13726            ProcessRecord r = procs.get(i);
13727            if (r.thread != null) {
13728                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13729                pw.flush();
13730                try {
13731                    TransferPipe tp = new TransferPipe();
13732                    try {
13733                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13734                        tp.go(fd);
13735                    } finally {
13736                        tp.kill();
13737                    }
13738                } catch (IOException e) {
13739                    pw.println("Failure while dumping the app: " + r);
13740                    pw.flush();
13741                } catch (RemoteException e) {
13742                    pw.println("Got a RemoteException while dumping the app " + r);
13743                    pw.flush();
13744                }
13745            }
13746        }
13747    }
13748
13749    final static class MemItem {
13750        final boolean isProc;
13751        final String label;
13752        final String shortLabel;
13753        final long pss;
13754        final int id;
13755        final boolean hasActivities;
13756        ArrayList<MemItem> subitems;
13757
13758        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13759                boolean _hasActivities) {
13760            isProc = true;
13761            label = _label;
13762            shortLabel = _shortLabel;
13763            pss = _pss;
13764            id = _id;
13765            hasActivities = _hasActivities;
13766        }
13767
13768        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13769            isProc = false;
13770            label = _label;
13771            shortLabel = _shortLabel;
13772            pss = _pss;
13773            id = _id;
13774            hasActivities = false;
13775        }
13776    }
13777
13778    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13779            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13780        if (sort && !isCompact) {
13781            Collections.sort(items, new Comparator<MemItem>() {
13782                @Override
13783                public int compare(MemItem lhs, MemItem rhs) {
13784                    if (lhs.pss < rhs.pss) {
13785                        return 1;
13786                    } else if (lhs.pss > rhs.pss) {
13787                        return -1;
13788                    }
13789                    return 0;
13790                }
13791            });
13792        }
13793
13794        for (int i=0; i<items.size(); i++) {
13795            MemItem mi = items.get(i);
13796            if (!isCompact) {
13797                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13798            } else if (mi.isProc) {
13799                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13800                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13801                pw.println(mi.hasActivities ? ",a" : ",e");
13802            } else {
13803                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13804                pw.println(mi.pss);
13805            }
13806            if (mi.subitems != null) {
13807                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13808                        true, isCompact);
13809            }
13810        }
13811    }
13812
13813    // These are in KB.
13814    static final long[] DUMP_MEM_BUCKETS = new long[] {
13815        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13816        120*1024, 160*1024, 200*1024,
13817        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13818        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13819    };
13820
13821    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13822            boolean stackLike) {
13823        int start = label.lastIndexOf('.');
13824        if (start >= 0) start++;
13825        else start = 0;
13826        int end = label.length();
13827        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13828            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13829                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13830                out.append(bucket);
13831                out.append(stackLike ? "MB." : "MB ");
13832                out.append(label, start, end);
13833                return;
13834            }
13835        }
13836        out.append(memKB/1024);
13837        out.append(stackLike ? "MB." : "MB ");
13838        out.append(label, start, end);
13839    }
13840
13841    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13842            ProcessList.NATIVE_ADJ,
13843            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13844            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13845            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13846            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13847            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13848            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13849    };
13850    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13851            "Native",
13852            "System", "Persistent", "Persistent Service", "Foreground",
13853            "Visible", "Perceptible",
13854            "Heavy Weight", "Backup",
13855            "A Services", "Home",
13856            "Previous", "B Services", "Cached"
13857    };
13858    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13859            "native",
13860            "sys", "pers", "persvc", "fore",
13861            "vis", "percept",
13862            "heavy", "backup",
13863            "servicea", "home",
13864            "prev", "serviceb", "cached"
13865    };
13866
13867    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13868            long realtime, boolean isCheckinRequest, boolean isCompact) {
13869        if (isCheckinRequest || isCompact) {
13870            // short checkin version
13871            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13872        } else {
13873            pw.println("Applications Memory Usage (kB):");
13874            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13875        }
13876    }
13877
13878    private static final int KSM_SHARED = 0;
13879    private static final int KSM_SHARING = 1;
13880    private static final int KSM_UNSHARED = 2;
13881    private static final int KSM_VOLATILE = 3;
13882
13883    private final long[] getKsmInfo() {
13884        long[] longOut = new long[4];
13885        final int[] SINGLE_LONG_FORMAT = new int[] {
13886            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13887        };
13888        long[] longTmp = new long[1];
13889        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13890                SINGLE_LONG_FORMAT, null, longTmp, null);
13891        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13892        longTmp[0] = 0;
13893        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13894                SINGLE_LONG_FORMAT, null, longTmp, null);
13895        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13896        longTmp[0] = 0;
13897        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13898                SINGLE_LONG_FORMAT, null, longTmp, null);
13899        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13900        longTmp[0] = 0;
13901        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13902                SINGLE_LONG_FORMAT, null, longTmp, null);
13903        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13904        return longOut;
13905    }
13906
13907    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13908            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13909        boolean dumpDetails = false;
13910        boolean dumpFullDetails = false;
13911        boolean dumpDalvik = false;
13912        boolean oomOnly = false;
13913        boolean isCompact = false;
13914        boolean localOnly = false;
13915        boolean packages = false;
13916
13917        int opti = 0;
13918        while (opti < args.length) {
13919            String opt = args[opti];
13920            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13921                break;
13922            }
13923            opti++;
13924            if ("-a".equals(opt)) {
13925                dumpDetails = true;
13926                dumpFullDetails = true;
13927                dumpDalvik = true;
13928            } else if ("-d".equals(opt)) {
13929                dumpDalvik = true;
13930            } else if ("-c".equals(opt)) {
13931                isCompact = true;
13932            } else if ("--oom".equals(opt)) {
13933                oomOnly = true;
13934            } else if ("--local".equals(opt)) {
13935                localOnly = true;
13936            } else if ("--package".equals(opt)) {
13937                packages = true;
13938            } else if ("-h".equals(opt)) {
13939                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13940                pw.println("  -a: include all available information for each process.");
13941                pw.println("  -d: include dalvik details when dumping process details.");
13942                pw.println("  -c: dump in a compact machine-parseable representation.");
13943                pw.println("  --oom: only show processes organized by oom adj.");
13944                pw.println("  --local: only collect details locally, don't call process.");
13945                pw.println("  --package: interpret process arg as package, dumping all");
13946                pw.println("             processes that have loaded that package.");
13947                pw.println("If [process] is specified it can be the name or ");
13948                pw.println("pid of a specific process to dump.");
13949                return;
13950            } else {
13951                pw.println("Unknown argument: " + opt + "; use -h for help");
13952            }
13953        }
13954
13955        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13956        long uptime = SystemClock.uptimeMillis();
13957        long realtime = SystemClock.elapsedRealtime();
13958        final long[] tmpLong = new long[1];
13959
13960        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13961        if (procs == null) {
13962            // No Java processes.  Maybe they want to print a native process.
13963            if (args != null && args.length > opti
13964                    && args[opti].charAt(0) != '-') {
13965                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13966                        = new ArrayList<ProcessCpuTracker.Stats>();
13967                updateCpuStatsNow();
13968                int findPid = -1;
13969                try {
13970                    findPid = Integer.parseInt(args[opti]);
13971                } catch (NumberFormatException e) {
13972                }
13973                synchronized (mProcessCpuTracker) {
13974                    final int N = mProcessCpuTracker.countStats();
13975                    for (int i=0; i<N; i++) {
13976                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13977                        if (st.pid == findPid || (st.baseName != null
13978                                && st.baseName.equals(args[opti]))) {
13979                            nativeProcs.add(st);
13980                        }
13981                    }
13982                }
13983                if (nativeProcs.size() > 0) {
13984                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13985                            isCompact);
13986                    Debug.MemoryInfo mi = null;
13987                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13988                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13989                        final int pid = r.pid;
13990                        if (!isCheckinRequest && dumpDetails) {
13991                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13992                        }
13993                        if (mi == null) {
13994                            mi = new Debug.MemoryInfo();
13995                        }
13996                        if (dumpDetails || (!brief && !oomOnly)) {
13997                            Debug.getMemoryInfo(pid, mi);
13998                        } else {
13999                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14000                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14001                        }
14002                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14003                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14004                        if (isCheckinRequest) {
14005                            pw.println();
14006                        }
14007                    }
14008                    return;
14009                }
14010            }
14011            pw.println("No process found for: " + args[opti]);
14012            return;
14013        }
14014
14015        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14016            dumpDetails = true;
14017        }
14018
14019        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14020
14021        String[] innerArgs = new String[args.length-opti];
14022        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14023
14024        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14025        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14026        long nativePss = 0;
14027        long dalvikPss = 0;
14028        long otherPss = 0;
14029        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14030
14031        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14032        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14033                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14034
14035        long totalPss = 0;
14036        long cachedPss = 0;
14037
14038        Debug.MemoryInfo mi = null;
14039        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14040            final ProcessRecord r = procs.get(i);
14041            final IApplicationThread thread;
14042            final int pid;
14043            final int oomAdj;
14044            final boolean hasActivities;
14045            synchronized (this) {
14046                thread = r.thread;
14047                pid = r.pid;
14048                oomAdj = r.getSetAdjWithServices();
14049                hasActivities = r.activities.size() > 0;
14050            }
14051            if (thread != null) {
14052                if (!isCheckinRequest && dumpDetails) {
14053                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14054                }
14055                if (mi == null) {
14056                    mi = new Debug.MemoryInfo();
14057                }
14058                if (dumpDetails || (!brief && !oomOnly)) {
14059                    Debug.getMemoryInfo(pid, mi);
14060                } else {
14061                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14062                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14063                }
14064                if (dumpDetails) {
14065                    if (localOnly) {
14066                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14067                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14068                        if (isCheckinRequest) {
14069                            pw.println();
14070                        }
14071                    } else {
14072                        try {
14073                            pw.flush();
14074                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14075                                    dumpDalvik, innerArgs);
14076                        } catch (RemoteException e) {
14077                            if (!isCheckinRequest) {
14078                                pw.println("Got RemoteException!");
14079                                pw.flush();
14080                            }
14081                        }
14082                    }
14083                }
14084
14085                final long myTotalPss = mi.getTotalPss();
14086                final long myTotalUss = mi.getTotalUss();
14087
14088                synchronized (this) {
14089                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14090                        // Record this for posterity if the process has been stable.
14091                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14092                    }
14093                }
14094
14095                if (!isCheckinRequest && mi != null) {
14096                    totalPss += myTotalPss;
14097                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14098                            (hasActivities ? " / activities)" : ")"),
14099                            r.processName, myTotalPss, pid, hasActivities);
14100                    procMems.add(pssItem);
14101                    procMemsMap.put(pid, pssItem);
14102
14103                    nativePss += mi.nativePss;
14104                    dalvikPss += mi.dalvikPss;
14105                    otherPss += mi.otherPss;
14106                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14107                        long mem = mi.getOtherPss(j);
14108                        miscPss[j] += mem;
14109                        otherPss -= mem;
14110                    }
14111
14112                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14113                        cachedPss += myTotalPss;
14114                    }
14115
14116                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14117                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14118                                || oomIndex == (oomPss.length-1)) {
14119                            oomPss[oomIndex] += myTotalPss;
14120                            if (oomProcs[oomIndex] == null) {
14121                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14122                            }
14123                            oomProcs[oomIndex].add(pssItem);
14124                            break;
14125                        }
14126                    }
14127                }
14128            }
14129        }
14130
14131        long nativeProcTotalPss = 0;
14132
14133        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14134            // If we are showing aggregations, also look for native processes to
14135            // include so that our aggregations are more accurate.
14136            updateCpuStatsNow();
14137            mi = null;
14138            synchronized (mProcessCpuTracker) {
14139                final int N = mProcessCpuTracker.countStats();
14140                for (int i=0; i<N; i++) {
14141                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14142                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14143                        if (mi == null) {
14144                            mi = new Debug.MemoryInfo();
14145                        }
14146                        if (!brief && !oomOnly) {
14147                            Debug.getMemoryInfo(st.pid, mi);
14148                        } else {
14149                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14150                            mi.nativePrivateDirty = (int)tmpLong[0];
14151                        }
14152
14153                        final long myTotalPss = mi.getTotalPss();
14154                        totalPss += myTotalPss;
14155                        nativeProcTotalPss += myTotalPss;
14156
14157                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14158                                st.name, myTotalPss, st.pid, false);
14159                        procMems.add(pssItem);
14160
14161                        nativePss += mi.nativePss;
14162                        dalvikPss += mi.dalvikPss;
14163                        otherPss += mi.otherPss;
14164                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14165                            long mem = mi.getOtherPss(j);
14166                            miscPss[j] += mem;
14167                            otherPss -= mem;
14168                        }
14169                        oomPss[0] += myTotalPss;
14170                        if (oomProcs[0] == null) {
14171                            oomProcs[0] = new ArrayList<MemItem>();
14172                        }
14173                        oomProcs[0].add(pssItem);
14174                    }
14175                }
14176            }
14177
14178            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14179
14180            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14181            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14182            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14183            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14184                String label = Debug.MemoryInfo.getOtherLabel(j);
14185                catMems.add(new MemItem(label, label, miscPss[j], j));
14186            }
14187
14188            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14189            for (int j=0; j<oomPss.length; j++) {
14190                if (oomPss[j] != 0) {
14191                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14192                            : DUMP_MEM_OOM_LABEL[j];
14193                    MemItem item = new MemItem(label, label, oomPss[j],
14194                            DUMP_MEM_OOM_ADJ[j]);
14195                    item.subitems = oomProcs[j];
14196                    oomMems.add(item);
14197                }
14198            }
14199
14200            if (!brief && !oomOnly && !isCompact) {
14201                pw.println();
14202                pw.println("Total PSS by process:");
14203                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14204                pw.println();
14205            }
14206            if (!isCompact) {
14207                pw.println("Total PSS by OOM adjustment:");
14208            }
14209            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14210            if (!brief && !oomOnly) {
14211                PrintWriter out = categoryPw != null ? categoryPw : pw;
14212                if (!isCompact) {
14213                    out.println();
14214                    out.println("Total PSS by category:");
14215                }
14216                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14217            }
14218            if (!isCompact) {
14219                pw.println();
14220            }
14221            MemInfoReader memInfo = new MemInfoReader();
14222            memInfo.readMemInfo();
14223            if (nativeProcTotalPss > 0) {
14224                synchronized (this) {
14225                    final long cachedKb = memInfo.getCachedSizeKb();
14226                    final long freeKb = memInfo.getFreeSizeKb();
14227                    final long zramKb = memInfo.getZramTotalSizeKb();
14228                    final long kernelKb = memInfo.getKernelUsedSizeKb();
14229                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14230                            kernelKb*1024, nativeProcTotalPss*1024);
14231                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14232                            nativeProcTotalPss);
14233                }
14234            }
14235            if (!brief) {
14236                if (!isCompact) {
14237                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14238                    pw.print(" kB (status ");
14239                    switch (mLastMemoryLevel) {
14240                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14241                            pw.println("normal)");
14242                            break;
14243                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14244                            pw.println("moderate)");
14245                            break;
14246                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14247                            pw.println("low)");
14248                            break;
14249                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14250                            pw.println("critical)");
14251                            break;
14252                        default:
14253                            pw.print(mLastMemoryLevel);
14254                            pw.println(")");
14255                            break;
14256                    }
14257                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14258                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14259                            pw.print(cachedPss); pw.print(" cached pss + ");
14260                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14261                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14262                } else {
14263                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14264                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14265                            + memInfo.getFreeSizeKb()); pw.print(",");
14266                    pw.println(totalPss - cachedPss);
14267                }
14268            }
14269            if (!isCompact) {
14270                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14271                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14272                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14273                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14274                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14275                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14276                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14277            }
14278            if (!brief) {
14279                if (memInfo.getZramTotalSizeKb() != 0) {
14280                    if (!isCompact) {
14281                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14282                                pw.print(" kB physical used for ");
14283                                pw.print(memInfo.getSwapTotalSizeKb()
14284                                        - memInfo.getSwapFreeSizeKb());
14285                                pw.print(" kB in swap (");
14286                                pw.print(memInfo.getSwapTotalSizeKb());
14287                                pw.println(" kB total swap)");
14288                    } else {
14289                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14290                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14291                                pw.println(memInfo.getSwapFreeSizeKb());
14292                    }
14293                }
14294                final long[] ksm = getKsmInfo();
14295                if (!isCompact) {
14296                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14297                            || ksm[KSM_VOLATILE] != 0) {
14298                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14299                                pw.print(" kB saved from shared ");
14300                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14301                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14302                                pw.print(" kB unshared; ");
14303                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14304                    }
14305                    pw.print("   Tuning: ");
14306                    pw.print(ActivityManager.staticGetMemoryClass());
14307                    pw.print(" (large ");
14308                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14309                    pw.print("), oom ");
14310                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14311                    pw.print(" kB");
14312                    pw.print(", restore limit ");
14313                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14314                    pw.print(" kB");
14315                    if (ActivityManager.isLowRamDeviceStatic()) {
14316                        pw.print(" (low-ram)");
14317                    }
14318                    if (ActivityManager.isHighEndGfx()) {
14319                        pw.print(" (high-end-gfx)");
14320                    }
14321                    pw.println();
14322                } else {
14323                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14324                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14325                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14326                    pw.print("tuning,");
14327                    pw.print(ActivityManager.staticGetMemoryClass());
14328                    pw.print(',');
14329                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14330                    pw.print(',');
14331                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14332                    if (ActivityManager.isLowRamDeviceStatic()) {
14333                        pw.print(",low-ram");
14334                    }
14335                    if (ActivityManager.isHighEndGfx()) {
14336                        pw.print(",high-end-gfx");
14337                    }
14338                    pw.println();
14339                }
14340            }
14341        }
14342    }
14343
14344    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14345            long memtrack, String name) {
14346        sb.append("  ");
14347        sb.append(ProcessList.makeOomAdjString(oomAdj));
14348        sb.append(' ');
14349        sb.append(ProcessList.makeProcStateString(procState));
14350        sb.append(' ');
14351        ProcessList.appendRamKb(sb, pss);
14352        sb.append(" kB: ");
14353        sb.append(name);
14354        if (memtrack > 0) {
14355            sb.append(" (");
14356            sb.append(memtrack);
14357            sb.append(" kB memtrack)");
14358        }
14359    }
14360
14361    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14362        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14363        sb.append(" (pid ");
14364        sb.append(mi.pid);
14365        sb.append(") ");
14366        sb.append(mi.adjType);
14367        sb.append('\n');
14368        if (mi.adjReason != null) {
14369            sb.append("                      ");
14370            sb.append(mi.adjReason);
14371            sb.append('\n');
14372        }
14373    }
14374
14375    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14376        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14377        for (int i=0, N=memInfos.size(); i<N; i++) {
14378            ProcessMemInfo mi = memInfos.get(i);
14379            infoMap.put(mi.pid, mi);
14380        }
14381        updateCpuStatsNow();
14382        long[] memtrackTmp = new long[1];
14383        synchronized (mProcessCpuTracker) {
14384            final int N = mProcessCpuTracker.countStats();
14385            for (int i=0; i<N; i++) {
14386                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14387                if (st.vsize > 0) {
14388                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14389                    if (pss > 0) {
14390                        if (infoMap.indexOfKey(st.pid) < 0) {
14391                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14392                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14393                            mi.pss = pss;
14394                            mi.memtrack = memtrackTmp[0];
14395                            memInfos.add(mi);
14396                        }
14397                    }
14398                }
14399            }
14400        }
14401
14402        long totalPss = 0;
14403        long totalMemtrack = 0;
14404        for (int i=0, N=memInfos.size(); i<N; i++) {
14405            ProcessMemInfo mi = memInfos.get(i);
14406            if (mi.pss == 0) {
14407                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14408                mi.memtrack = memtrackTmp[0];
14409            }
14410            totalPss += mi.pss;
14411            totalMemtrack += mi.memtrack;
14412        }
14413        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14414            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14415                if (lhs.oomAdj != rhs.oomAdj) {
14416                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14417                }
14418                if (lhs.pss != rhs.pss) {
14419                    return lhs.pss < rhs.pss ? 1 : -1;
14420                }
14421                return 0;
14422            }
14423        });
14424
14425        StringBuilder tag = new StringBuilder(128);
14426        StringBuilder stack = new StringBuilder(128);
14427        tag.append("Low on memory -- ");
14428        appendMemBucket(tag, totalPss, "total", false);
14429        appendMemBucket(stack, totalPss, "total", true);
14430
14431        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14432        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14433        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14434
14435        boolean firstLine = true;
14436        int lastOomAdj = Integer.MIN_VALUE;
14437        long extraNativeRam = 0;
14438        long extraNativeMemtrack = 0;
14439        long cachedPss = 0;
14440        for (int i=0, N=memInfos.size(); i<N; i++) {
14441            ProcessMemInfo mi = memInfos.get(i);
14442
14443            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14444                cachedPss += mi.pss;
14445            }
14446
14447            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14448                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14449                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14450                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14451                if (lastOomAdj != mi.oomAdj) {
14452                    lastOomAdj = mi.oomAdj;
14453                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14454                        tag.append(" / ");
14455                    }
14456                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14457                        if (firstLine) {
14458                            stack.append(":");
14459                            firstLine = false;
14460                        }
14461                        stack.append("\n\t at ");
14462                    } else {
14463                        stack.append("$");
14464                    }
14465                } else {
14466                    tag.append(" ");
14467                    stack.append("$");
14468                }
14469                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14470                    appendMemBucket(tag, mi.pss, mi.name, false);
14471                }
14472                appendMemBucket(stack, mi.pss, mi.name, true);
14473                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14474                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14475                    stack.append("(");
14476                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14477                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14478                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14479                            stack.append(":");
14480                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14481                        }
14482                    }
14483                    stack.append(")");
14484                }
14485            }
14486
14487            appendMemInfo(fullNativeBuilder, mi);
14488            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14489                // The short form only has native processes that are >= 512K.
14490                if (mi.pss >= 512) {
14491                    appendMemInfo(shortNativeBuilder, mi);
14492                } else {
14493                    extraNativeRam += mi.pss;
14494                    extraNativeMemtrack += mi.memtrack;
14495                }
14496            } else {
14497                // Short form has all other details, but if we have collected RAM
14498                // from smaller native processes let's dump a summary of that.
14499                if (extraNativeRam > 0) {
14500                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14501                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14502                    shortNativeBuilder.append('\n');
14503                    extraNativeRam = 0;
14504                }
14505                appendMemInfo(fullJavaBuilder, mi);
14506            }
14507        }
14508
14509        fullJavaBuilder.append("           ");
14510        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14511        fullJavaBuilder.append(" kB: TOTAL");
14512        if (totalMemtrack > 0) {
14513            fullJavaBuilder.append(" (");
14514            fullJavaBuilder.append(totalMemtrack);
14515            fullJavaBuilder.append(" kB memtrack)");
14516        } else {
14517        }
14518        fullJavaBuilder.append("\n");
14519
14520        MemInfoReader memInfo = new MemInfoReader();
14521        memInfo.readMemInfo();
14522        final long[] infos = memInfo.getRawInfo();
14523
14524        StringBuilder memInfoBuilder = new StringBuilder(1024);
14525        Debug.getMemInfo(infos);
14526        memInfoBuilder.append("  MemInfo: ");
14527        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14528        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14529        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14530        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14531        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14532        memInfoBuilder.append("           ");
14533        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14534        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14535        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14536        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14537        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14538            memInfoBuilder.append("  ZRAM: ");
14539            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14540            memInfoBuilder.append(" kB RAM, ");
14541            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14542            memInfoBuilder.append(" kB swap total, ");
14543            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14544            memInfoBuilder.append(" kB swap free\n");
14545        }
14546        final long[] ksm = getKsmInfo();
14547        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14548                || ksm[KSM_VOLATILE] != 0) {
14549            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14550            memInfoBuilder.append(" kB saved from shared ");
14551            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14552            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14553            memInfoBuilder.append(" kB unshared; ");
14554            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14555        }
14556        memInfoBuilder.append("  Free RAM: ");
14557        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14558                + memInfo.getFreeSizeKb());
14559        memInfoBuilder.append(" kB\n");
14560        memInfoBuilder.append("  Used RAM: ");
14561        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14562        memInfoBuilder.append(" kB\n");
14563        memInfoBuilder.append("  Lost RAM: ");
14564        memInfoBuilder.append(memInfo.getTotalSizeKb()
14565                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14566                - memInfo.getKernelUsedSizeKb());
14567        memInfoBuilder.append(" kB\n");
14568        Slog.i(TAG, "Low on memory:");
14569        Slog.i(TAG, shortNativeBuilder.toString());
14570        Slog.i(TAG, fullJavaBuilder.toString());
14571        Slog.i(TAG, memInfoBuilder.toString());
14572
14573        StringBuilder dropBuilder = new StringBuilder(1024);
14574        /*
14575        StringWriter oomSw = new StringWriter();
14576        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14577        StringWriter catSw = new StringWriter();
14578        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14579        String[] emptyArgs = new String[] { };
14580        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14581        oomPw.flush();
14582        String oomString = oomSw.toString();
14583        */
14584        dropBuilder.append("Low on memory:");
14585        dropBuilder.append(stack);
14586        dropBuilder.append('\n');
14587        dropBuilder.append(fullNativeBuilder);
14588        dropBuilder.append(fullJavaBuilder);
14589        dropBuilder.append('\n');
14590        dropBuilder.append(memInfoBuilder);
14591        dropBuilder.append('\n');
14592        /*
14593        dropBuilder.append(oomString);
14594        dropBuilder.append('\n');
14595        */
14596        StringWriter catSw = new StringWriter();
14597        synchronized (ActivityManagerService.this) {
14598            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14599            String[] emptyArgs = new String[] { };
14600            catPw.println();
14601            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14602            catPw.println();
14603            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14604                    false, false, null);
14605            catPw.println();
14606            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14607            catPw.flush();
14608        }
14609        dropBuilder.append(catSw.toString());
14610        addErrorToDropBox("lowmem", null, "system_server", null,
14611                null, tag.toString(), dropBuilder.toString(), null, null);
14612        //Slog.i(TAG, "Sent to dropbox:");
14613        //Slog.i(TAG, dropBuilder.toString());
14614        synchronized (ActivityManagerService.this) {
14615            long now = SystemClock.uptimeMillis();
14616            if (mLastMemUsageReportTime < now) {
14617                mLastMemUsageReportTime = now;
14618            }
14619        }
14620    }
14621
14622    /**
14623     * Searches array of arguments for the specified string
14624     * @param args array of argument strings
14625     * @param value value to search for
14626     * @return true if the value is contained in the array
14627     */
14628    private static boolean scanArgs(String[] args, String value) {
14629        if (args != null) {
14630            for (String arg : args) {
14631                if (value.equals(arg)) {
14632                    return true;
14633                }
14634            }
14635        }
14636        return false;
14637    }
14638
14639    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14640            ContentProviderRecord cpr, boolean always) {
14641        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14642
14643        if (!inLaunching || always) {
14644            synchronized (cpr) {
14645                cpr.launchingApp = null;
14646                cpr.notifyAll();
14647            }
14648            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14649            String names[] = cpr.info.authority.split(";");
14650            for (int j = 0; j < names.length; j++) {
14651                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14652            }
14653        }
14654
14655        for (int i=0; i<cpr.connections.size(); i++) {
14656            ContentProviderConnection conn = cpr.connections.get(i);
14657            if (conn.waiting) {
14658                // If this connection is waiting for the provider, then we don't
14659                // need to mess with its process unless we are always removing
14660                // or for some reason the provider is not currently launching.
14661                if (inLaunching && !always) {
14662                    continue;
14663                }
14664            }
14665            ProcessRecord capp = conn.client;
14666            conn.dead = true;
14667            if (conn.stableCount > 0) {
14668                if (!capp.persistent && capp.thread != null
14669                        && capp.pid != 0
14670                        && capp.pid != MY_PID) {
14671                    capp.kill("depends on provider "
14672                            + cpr.name.flattenToShortString()
14673                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14674                }
14675            } else if (capp.thread != null && conn.provider.provider != null) {
14676                try {
14677                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14678                } catch (RemoteException e) {
14679                }
14680                // In the protocol here, we don't expect the client to correctly
14681                // clean up this connection, we'll just remove it.
14682                cpr.connections.remove(i);
14683                if (conn.client.conProviders.remove(conn)) {
14684                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14685                }
14686            }
14687        }
14688
14689        if (inLaunching && always) {
14690            mLaunchingProviders.remove(cpr);
14691        }
14692        return inLaunching;
14693    }
14694
14695    /**
14696     * Main code for cleaning up a process when it has gone away.  This is
14697     * called both as a result of the process dying, or directly when stopping
14698     * a process when running in single process mode.
14699     *
14700     * @return Returns true if the given process has been restarted, so the
14701     * app that was passed in must remain on the process lists.
14702     */
14703    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14704            boolean restarting, boolean allowRestart, int index) {
14705        if (index >= 0) {
14706            removeLruProcessLocked(app);
14707            ProcessList.remove(app.pid);
14708        }
14709
14710        mProcessesToGc.remove(app);
14711        mPendingPssProcesses.remove(app);
14712
14713        // Dismiss any open dialogs.
14714        if (app.crashDialog != null && !app.forceCrashReport) {
14715            app.crashDialog.dismiss();
14716            app.crashDialog = null;
14717        }
14718        if (app.anrDialog != null) {
14719            app.anrDialog.dismiss();
14720            app.anrDialog = null;
14721        }
14722        if (app.waitDialog != null) {
14723            app.waitDialog.dismiss();
14724            app.waitDialog = null;
14725        }
14726
14727        app.crashing = false;
14728        app.notResponding = false;
14729
14730        app.resetPackageList(mProcessStats);
14731        app.unlinkDeathRecipient();
14732        app.makeInactive(mProcessStats);
14733        app.waitingToKill = null;
14734        app.forcingToForeground = null;
14735        updateProcessForegroundLocked(app, false, false);
14736        app.foregroundActivities = false;
14737        app.hasShownUi = false;
14738        app.treatLikeActivity = false;
14739        app.hasAboveClient = false;
14740        app.hasClientActivities = false;
14741
14742        mServices.killServicesLocked(app, allowRestart);
14743
14744        boolean restart = false;
14745
14746        // Remove published content providers.
14747        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14748            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14749            final boolean always = app.bad || !allowRestart;
14750            if (removeDyingProviderLocked(app, cpr, always) || always) {
14751                // We left the provider in the launching list, need to
14752                // restart it.
14753                restart = true;
14754            }
14755
14756            cpr.provider = null;
14757            cpr.proc = null;
14758        }
14759        app.pubProviders.clear();
14760
14761        // Take care of any launching providers waiting for this process.
14762        if (checkAppInLaunchingProvidersLocked(app, false)) {
14763            restart = true;
14764        }
14765
14766        // Unregister from connected content providers.
14767        if (!app.conProviders.isEmpty()) {
14768            for (int i=0; i<app.conProviders.size(); i++) {
14769                ContentProviderConnection conn = app.conProviders.get(i);
14770                conn.provider.connections.remove(conn);
14771                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
14772                        conn.provider.name);
14773            }
14774            app.conProviders.clear();
14775        }
14776
14777        // At this point there may be remaining entries in mLaunchingProviders
14778        // where we were the only one waiting, so they are no longer of use.
14779        // Look for these and clean up if found.
14780        // XXX Commented out for now.  Trying to figure out a way to reproduce
14781        // the actual situation to identify what is actually going on.
14782        if (false) {
14783            for (int i=0; i<mLaunchingProviders.size(); i++) {
14784                ContentProviderRecord cpr = (ContentProviderRecord)
14785                        mLaunchingProviders.get(i);
14786                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14787                    synchronized (cpr) {
14788                        cpr.launchingApp = null;
14789                        cpr.notifyAll();
14790                    }
14791                }
14792            }
14793        }
14794
14795        skipCurrentReceiverLocked(app);
14796
14797        // Unregister any receivers.
14798        for (int i=app.receivers.size()-1; i>=0; i--) {
14799            removeReceiverLocked(app.receivers.valueAt(i));
14800        }
14801        app.receivers.clear();
14802
14803        // If the app is undergoing backup, tell the backup manager about it
14804        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14805            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
14806                    + mBackupTarget.appInfo + " died during backup");
14807            try {
14808                IBackupManager bm = IBackupManager.Stub.asInterface(
14809                        ServiceManager.getService(Context.BACKUP_SERVICE));
14810                bm.agentDisconnected(app.info.packageName);
14811            } catch (RemoteException e) {
14812                // can't happen; backup manager is local
14813            }
14814        }
14815
14816        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14817            ProcessChangeItem item = mPendingProcessChanges.get(i);
14818            if (item.pid == app.pid) {
14819                mPendingProcessChanges.remove(i);
14820                mAvailProcessChanges.add(item);
14821            }
14822        }
14823        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14824
14825        // If the caller is restarting this app, then leave it in its
14826        // current lists and let the caller take care of it.
14827        if (restarting) {
14828            return false;
14829        }
14830
14831        if (!app.persistent || app.isolated) {
14832            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
14833                    "Removing non-persistent process during cleanup: " + app);
14834            mProcessNames.remove(app.processName, app.uid);
14835            mIsolatedProcesses.remove(app.uid);
14836            if (mHeavyWeightProcess == app) {
14837                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14838                        mHeavyWeightProcess.userId, 0));
14839                mHeavyWeightProcess = null;
14840            }
14841        } else if (!app.removed) {
14842            // This app is persistent, so we need to keep its record around.
14843            // If it is not already on the pending app list, add it there
14844            // and start a new process for it.
14845            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14846                mPersistentStartingProcesses.add(app);
14847                restart = true;
14848            }
14849        }
14850        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
14851                TAG_CLEANUP, "Clean-up removing on hold: " + app);
14852        mProcessesOnHold.remove(app);
14853
14854        if (app == mHomeProcess) {
14855            mHomeProcess = null;
14856        }
14857        if (app == mPreviousProcess) {
14858            mPreviousProcess = null;
14859        }
14860
14861        if (restart && !app.isolated) {
14862            // We have components that still need to be running in the
14863            // process, so re-launch it.
14864            if (index < 0) {
14865                ProcessList.remove(app.pid);
14866            }
14867            mProcessNames.put(app.processName, app.uid, app);
14868            startProcessLocked(app, "restart", app.processName);
14869            return true;
14870        } else if (app.pid > 0 && app.pid != MY_PID) {
14871            // Goodbye!
14872            boolean removed;
14873            synchronized (mPidsSelfLocked) {
14874                mPidsSelfLocked.remove(app.pid);
14875                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14876            }
14877            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14878            if (app.isolated) {
14879                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14880            }
14881            app.setPid(0);
14882        }
14883        return false;
14884    }
14885
14886    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14887        // Look through the content providers we are waiting to have launched,
14888        // and if any run in this process then either schedule a restart of
14889        // the process or kill the client waiting for it if this process has
14890        // gone bad.
14891        int NL = mLaunchingProviders.size();
14892        boolean restart = false;
14893        for (int i=0; i<NL; i++) {
14894            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14895            if (cpr.launchingApp == app) {
14896                if (!alwaysBad && !app.bad) {
14897                    restart = true;
14898                } else {
14899                    removeDyingProviderLocked(app, cpr, true);
14900                    // cpr should have been removed from mLaunchingProviders
14901                    NL = mLaunchingProviders.size();
14902                    i--;
14903                }
14904            }
14905        }
14906        return restart;
14907    }
14908
14909    // =========================================================
14910    // SERVICES
14911    // =========================================================
14912
14913    @Override
14914    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14915            int flags) {
14916        enforceNotIsolatedCaller("getServices");
14917        synchronized (this) {
14918            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14919        }
14920    }
14921
14922    @Override
14923    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14924        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14925        synchronized (this) {
14926            return mServices.getRunningServiceControlPanelLocked(name);
14927        }
14928    }
14929
14930    @Override
14931    public ComponentName startService(IApplicationThread caller, Intent service,
14932            String resolvedType, int userId) throws TransactionTooLargeException {
14933        enforceNotIsolatedCaller("startService");
14934        // Refuse possible leaked file descriptors
14935        if (service != null && service.hasFileDescriptors() == true) {
14936            throw new IllegalArgumentException("File descriptors passed in Intent");
14937        }
14938
14939        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
14940                "startService: " + service + " type=" + resolvedType);
14941        synchronized(this) {
14942            final int callingPid = Binder.getCallingPid();
14943            final int callingUid = Binder.getCallingUid();
14944            final long origId = Binder.clearCallingIdentity();
14945            ComponentName res = mServices.startServiceLocked(caller, service,
14946                    resolvedType, callingPid, callingUid, userId);
14947            Binder.restoreCallingIdentity(origId);
14948            return res;
14949        }
14950    }
14951
14952    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, int userId)
14953            throws TransactionTooLargeException {
14954        synchronized(this) {
14955            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
14956                    "startServiceInPackage: " + service + " type=" + resolvedType);
14957            final long origId = Binder.clearCallingIdentity();
14958            ComponentName res = mServices.startServiceLocked(null, service,
14959                    resolvedType, -1, uid, userId);
14960            Binder.restoreCallingIdentity(origId);
14961            return res;
14962        }
14963    }
14964
14965    @Override
14966    public int stopService(IApplicationThread caller, Intent service,
14967            String resolvedType, int userId) {
14968        enforceNotIsolatedCaller("stopService");
14969        // Refuse possible leaked file descriptors
14970        if (service != null && service.hasFileDescriptors() == true) {
14971            throw new IllegalArgumentException("File descriptors passed in Intent");
14972        }
14973
14974        synchronized(this) {
14975            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14976        }
14977    }
14978
14979    @Override
14980    public IBinder peekService(Intent service, String resolvedType) {
14981        enforceNotIsolatedCaller("peekService");
14982        // Refuse possible leaked file descriptors
14983        if (service != null && service.hasFileDescriptors() == true) {
14984            throw new IllegalArgumentException("File descriptors passed in Intent");
14985        }
14986        synchronized(this) {
14987            return mServices.peekServiceLocked(service, resolvedType);
14988        }
14989    }
14990
14991    @Override
14992    public boolean stopServiceToken(ComponentName className, IBinder token,
14993            int startId) {
14994        synchronized(this) {
14995            return mServices.stopServiceTokenLocked(className, token, startId);
14996        }
14997    }
14998
14999    @Override
15000    public void setServiceForeground(ComponentName className, IBinder token,
15001            int id, Notification notification, boolean removeNotification) {
15002        synchronized(this) {
15003            mServices.setServiceForegroundLocked(className, token, id, notification,
15004                    removeNotification);
15005        }
15006    }
15007
15008    @Override
15009    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15010            boolean requireFull, String name, String callerPackage) {
15011        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15012                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15013    }
15014
15015    int unsafeConvertIncomingUser(int userId) {
15016        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15017                ? mCurrentUserId : userId;
15018    }
15019
15020    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15021            int allowMode, String name, String callerPackage) {
15022        final int callingUserId = UserHandle.getUserId(callingUid);
15023        if (callingUserId == userId) {
15024            return userId;
15025        }
15026
15027        // Note that we may be accessing mCurrentUserId outside of a lock...
15028        // shouldn't be a big deal, if this is being called outside
15029        // of a locked context there is intrinsically a race with
15030        // the value the caller will receive and someone else changing it.
15031        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15032        // we will switch to the calling user if access to the current user fails.
15033        int targetUserId = unsafeConvertIncomingUser(userId);
15034
15035        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15036            final boolean allow;
15037            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15038                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15039                // If the caller has this permission, they always pass go.  And collect $200.
15040                allow = true;
15041            } else if (allowMode == ALLOW_FULL_ONLY) {
15042                // We require full access, sucks to be you.
15043                allow = false;
15044            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15045                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15046                // If the caller does not have either permission, they are always doomed.
15047                allow = false;
15048            } else if (allowMode == ALLOW_NON_FULL) {
15049                // We are blanket allowing non-full access, you lucky caller!
15050                allow = true;
15051            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15052                // We may or may not allow this depending on whether the two users are
15053                // in the same profile.
15054                synchronized (mUserProfileGroupIdsSelfLocked) {
15055                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15056                            UserInfo.NO_PROFILE_GROUP_ID);
15057                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15058                            UserInfo.NO_PROFILE_GROUP_ID);
15059                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15060                            && callingProfile == targetProfile;
15061                }
15062            } else {
15063                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15064            }
15065            if (!allow) {
15066                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15067                    // In this case, they would like to just execute as their
15068                    // owner user instead of failing.
15069                    targetUserId = callingUserId;
15070                } else {
15071                    StringBuilder builder = new StringBuilder(128);
15072                    builder.append("Permission Denial: ");
15073                    builder.append(name);
15074                    if (callerPackage != null) {
15075                        builder.append(" from ");
15076                        builder.append(callerPackage);
15077                    }
15078                    builder.append(" asks to run as user ");
15079                    builder.append(userId);
15080                    builder.append(" but is calling from user ");
15081                    builder.append(UserHandle.getUserId(callingUid));
15082                    builder.append("; this requires ");
15083                    builder.append(INTERACT_ACROSS_USERS_FULL);
15084                    if (allowMode != ALLOW_FULL_ONLY) {
15085                        builder.append(" or ");
15086                        builder.append(INTERACT_ACROSS_USERS);
15087                    }
15088                    String msg = builder.toString();
15089                    Slog.w(TAG, msg);
15090                    throw new SecurityException(msg);
15091                }
15092            }
15093        }
15094        if (!allowAll && targetUserId < 0) {
15095            throw new IllegalArgumentException(
15096                    "Call does not support special user #" + targetUserId);
15097        }
15098        // Check shell permission
15099        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15100            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15101                    targetUserId)) {
15102                throw new SecurityException("Shell does not have permission to access user "
15103                        + targetUserId + "\n " + Debug.getCallers(3));
15104            }
15105        }
15106        return targetUserId;
15107    }
15108
15109    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15110            String className, int flags) {
15111        boolean result = false;
15112        // For apps that don't have pre-defined UIDs, check for permission
15113        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15114            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15115                if (ActivityManager.checkUidPermission(
15116                        INTERACT_ACROSS_USERS,
15117                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15118                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15119                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15120                            + " requests FLAG_SINGLE_USER, but app does not hold "
15121                            + INTERACT_ACROSS_USERS;
15122                    Slog.w(TAG, msg);
15123                    throw new SecurityException(msg);
15124                }
15125                // Permission passed
15126                result = true;
15127            }
15128        } else if ("system".equals(componentProcessName)) {
15129            result = true;
15130        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15131            // Phone app and persistent apps are allowed to export singleuser providers.
15132            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15133                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15134        }
15135        if (DEBUG_MU) Slog.v(TAG_MU,
15136                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15137                + Integer.toHexString(flags) + ") = " + result);
15138        return result;
15139    }
15140
15141    /**
15142     * Checks to see if the caller is in the same app as the singleton
15143     * component, or the component is in a special app. It allows special apps
15144     * to export singleton components but prevents exporting singleton
15145     * components for regular apps.
15146     */
15147    boolean isValidSingletonCall(int callingUid, int componentUid) {
15148        int componentAppId = UserHandle.getAppId(componentUid);
15149        return UserHandle.isSameApp(callingUid, componentUid)
15150                || componentAppId == Process.SYSTEM_UID
15151                || componentAppId == Process.PHONE_UID
15152                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15153                        == PackageManager.PERMISSION_GRANTED;
15154    }
15155
15156    public int bindService(IApplicationThread caller, IBinder token, Intent service,
15157            String resolvedType, IServiceConnection connection, int flags, int userId)
15158            throws TransactionTooLargeException {
15159        enforceNotIsolatedCaller("bindService");
15160
15161        // Refuse possible leaked file descriptors
15162        if (service != null && service.hasFileDescriptors() == true) {
15163            throw new IllegalArgumentException("File descriptors passed in Intent");
15164        }
15165
15166        synchronized(this) {
15167            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15168                    connection, flags, userId);
15169        }
15170    }
15171
15172    public boolean unbindService(IServiceConnection connection) {
15173        synchronized (this) {
15174            return mServices.unbindServiceLocked(connection);
15175        }
15176    }
15177
15178    public void publishService(IBinder token, Intent intent, IBinder service) {
15179        // Refuse possible leaked file descriptors
15180        if (intent != null && intent.hasFileDescriptors() == true) {
15181            throw new IllegalArgumentException("File descriptors passed in Intent");
15182        }
15183
15184        synchronized(this) {
15185            if (!(token instanceof ServiceRecord)) {
15186                throw new IllegalArgumentException("Invalid service token");
15187            }
15188            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15189        }
15190    }
15191
15192    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15193        // Refuse possible leaked file descriptors
15194        if (intent != null && intent.hasFileDescriptors() == true) {
15195            throw new IllegalArgumentException("File descriptors passed in Intent");
15196        }
15197
15198        synchronized(this) {
15199            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15200        }
15201    }
15202
15203    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15204        synchronized(this) {
15205            if (!(token instanceof ServiceRecord)) {
15206                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15207                throw new IllegalArgumentException("Invalid service token");
15208            }
15209            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15210        }
15211    }
15212
15213    // =========================================================
15214    // BACKUP AND RESTORE
15215    // =========================================================
15216
15217    // Cause the target app to be launched if necessary and its backup agent
15218    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15219    // activity manager to announce its creation.
15220    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15221        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15222                "bindBackupAgent: app=" + app + " mode=" + backupMode);
15223        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15224
15225        synchronized(this) {
15226            // !!! TODO: currently no check here that we're already bound
15227            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15228            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15229            synchronized (stats) {
15230                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15231            }
15232
15233            // Backup agent is now in use, its package can't be stopped.
15234            try {
15235                AppGlobals.getPackageManager().setPackageStoppedState(
15236                        app.packageName, false, UserHandle.getUserId(app.uid));
15237            } catch (RemoteException e) {
15238            } catch (IllegalArgumentException e) {
15239                Slog.w(TAG, "Failed trying to unstop package "
15240                        + app.packageName + ": " + e);
15241            }
15242
15243            BackupRecord r = new BackupRecord(ss, app, backupMode);
15244            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15245                    ? new ComponentName(app.packageName, app.backupAgentName)
15246                    : new ComponentName("android", "FullBackupAgent");
15247            // startProcessLocked() returns existing proc's record if it's already running
15248            ProcessRecord proc = startProcessLocked(app.processName, app,
15249                    false, 0, "backup", hostingName, false, false, false);
15250            if (proc == null) {
15251                Slog.e(TAG, "Unable to start backup agent process " + r);
15252                return false;
15253            }
15254
15255            r.app = proc;
15256            mBackupTarget = r;
15257            mBackupAppName = app.packageName;
15258
15259            // Try not to kill the process during backup
15260            updateOomAdjLocked(proc);
15261
15262            // If the process is already attached, schedule the creation of the backup agent now.
15263            // If it is not yet live, this will be done when it attaches to the framework.
15264            if (proc.thread != null) {
15265                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
15266                try {
15267                    proc.thread.scheduleCreateBackupAgent(app,
15268                            compatibilityInfoForPackageLocked(app), backupMode);
15269                } catch (RemoteException e) {
15270                    // Will time out on the backup manager side
15271                }
15272            } else {
15273                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
15274            }
15275            // Invariants: at this point, the target app process exists and the application
15276            // is either already running or in the process of coming up.  mBackupTarget and
15277            // mBackupAppName describe the app, so that when it binds back to the AM we
15278            // know that it's scheduled for a backup-agent operation.
15279        }
15280
15281        return true;
15282    }
15283
15284    @Override
15285    public void clearPendingBackup() {
15286        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
15287        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15288
15289        synchronized (this) {
15290            mBackupTarget = null;
15291            mBackupAppName = null;
15292        }
15293    }
15294
15295    // A backup agent has just come up
15296    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15297        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
15298                + " = " + agent);
15299
15300        synchronized(this) {
15301            if (!agentPackageName.equals(mBackupAppName)) {
15302                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15303                return;
15304            }
15305        }
15306
15307        long oldIdent = Binder.clearCallingIdentity();
15308        try {
15309            IBackupManager bm = IBackupManager.Stub.asInterface(
15310                    ServiceManager.getService(Context.BACKUP_SERVICE));
15311            bm.agentConnected(agentPackageName, agent);
15312        } catch (RemoteException e) {
15313            // can't happen; the backup manager service is local
15314        } catch (Exception e) {
15315            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15316            e.printStackTrace();
15317        } finally {
15318            Binder.restoreCallingIdentity(oldIdent);
15319        }
15320    }
15321
15322    // done with this agent
15323    public void unbindBackupAgent(ApplicationInfo appInfo) {
15324        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
15325        if (appInfo == null) {
15326            Slog.w(TAG, "unbind backup agent for null app");
15327            return;
15328        }
15329
15330        synchronized(this) {
15331            try {
15332                if (mBackupAppName == null) {
15333                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15334                    return;
15335                }
15336
15337                if (!mBackupAppName.equals(appInfo.packageName)) {
15338                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15339                    return;
15340                }
15341
15342                // Not backing this app up any more; reset its OOM adjustment
15343                final ProcessRecord proc = mBackupTarget.app;
15344                updateOomAdjLocked(proc);
15345
15346                // If the app crashed during backup, 'thread' will be null here
15347                if (proc.thread != null) {
15348                    try {
15349                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15350                                compatibilityInfoForPackageLocked(appInfo));
15351                    } catch (Exception e) {
15352                        Slog.e(TAG, "Exception when unbinding backup agent:");
15353                        e.printStackTrace();
15354                    }
15355                }
15356            } finally {
15357                mBackupTarget = null;
15358                mBackupAppName = null;
15359            }
15360        }
15361    }
15362    // =========================================================
15363    // BROADCASTS
15364    // =========================================================
15365
15366    boolean isPendingBroadcastProcessLocked(int pid) {
15367        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15368                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15369    }
15370
15371    void skipPendingBroadcastLocked(int pid) {
15372            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15373            for (BroadcastQueue queue : mBroadcastQueues) {
15374                queue.skipPendingBroadcastLocked(pid);
15375            }
15376    }
15377
15378    // The app just attached; send any pending broadcasts that it should receive
15379    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15380        boolean didSomething = false;
15381        for (BroadcastQueue queue : mBroadcastQueues) {
15382            didSomething |= queue.sendPendingBroadcastsLocked(app);
15383        }
15384        return didSomething;
15385    }
15386
15387    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15388            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15389        enforceNotIsolatedCaller("registerReceiver");
15390        ArrayList<Intent> stickyIntents = null;
15391        ProcessRecord callerApp = null;
15392        int callingUid;
15393        int callingPid;
15394        synchronized(this) {
15395            if (caller != null) {
15396                callerApp = getRecordForAppLocked(caller);
15397                if (callerApp == null) {
15398                    throw new SecurityException(
15399                            "Unable to find app for caller " + caller
15400                            + " (pid=" + Binder.getCallingPid()
15401                            + ") when registering receiver " + receiver);
15402                }
15403                if (callerApp.info.uid != Process.SYSTEM_UID &&
15404                        !callerApp.pkgList.containsKey(callerPackage) &&
15405                        !"android".equals(callerPackage)) {
15406                    throw new SecurityException("Given caller package " + callerPackage
15407                            + " is not running in process " + callerApp);
15408                }
15409                callingUid = callerApp.info.uid;
15410                callingPid = callerApp.pid;
15411            } else {
15412                callerPackage = null;
15413                callingUid = Binder.getCallingUid();
15414                callingPid = Binder.getCallingPid();
15415            }
15416
15417            userId = handleIncomingUser(callingPid, callingUid, userId,
15418                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15419
15420            Iterator<String> actions = filter.actionsIterator();
15421            if (actions == null) {
15422                ArrayList<String> noAction = new ArrayList<String>(1);
15423                noAction.add(null);
15424                actions = noAction.iterator();
15425            }
15426
15427            // Collect stickies of users
15428            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
15429            while (actions.hasNext()) {
15430                String action = actions.next();
15431                for (int id : userIds) {
15432                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
15433                    if (stickies != null) {
15434                        ArrayList<Intent> intents = stickies.get(action);
15435                        if (intents != null) {
15436                            if (stickyIntents == null) {
15437                                stickyIntents = new ArrayList<Intent>();
15438                            }
15439                            stickyIntents.addAll(intents);
15440                        }
15441                    }
15442                }
15443            }
15444        }
15445
15446        ArrayList<Intent> allSticky = null;
15447        if (stickyIntents != null) {
15448            final ContentResolver resolver = mContext.getContentResolver();
15449            // Look for any matching sticky broadcasts...
15450            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
15451                Intent intent = stickyIntents.get(i);
15452                // If intent has scheme "content", it will need to acccess
15453                // provider that needs to lock mProviderMap in ActivityThread
15454                // and also it may need to wait application response, so we
15455                // cannot lock ActivityManagerService here.
15456                if (filter.match(resolver, intent, true, TAG) >= 0) {
15457                    if (allSticky == null) {
15458                        allSticky = new ArrayList<Intent>();
15459                    }
15460                    allSticky.add(intent);
15461                }
15462            }
15463        }
15464
15465        // The first sticky in the list is returned directly back to the client.
15466        Intent sticky = allSticky != null ? allSticky.get(0) : null;
15467        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
15468        if (receiver == null) {
15469            return sticky;
15470        }
15471
15472        synchronized (this) {
15473            if (callerApp != null && callerApp.pid == 0) {
15474                // Caller already died
15475                return null;
15476            }
15477            ReceiverList rl
15478                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15479            if (rl == null) {
15480                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15481                        userId, receiver);
15482                if (rl.app != null) {
15483                    rl.app.receivers.add(rl);
15484                } else {
15485                    try {
15486                        receiver.asBinder().linkToDeath(rl, 0);
15487                    } catch (RemoteException e) {
15488                        return sticky;
15489                    }
15490                    rl.linkedToDeath = true;
15491                }
15492                mRegisteredReceivers.put(receiver.asBinder(), rl);
15493            } else if (rl.uid != callingUid) {
15494                throw new IllegalArgumentException(
15495                        "Receiver requested to register for uid " + callingUid
15496                        + " was previously registered for uid " + rl.uid);
15497            } else if (rl.pid != callingPid) {
15498                throw new IllegalArgumentException(
15499                        "Receiver requested to register for pid " + callingPid
15500                        + " was previously registered for pid " + rl.pid);
15501            } else if (rl.userId != userId) {
15502                throw new IllegalArgumentException(
15503                        "Receiver requested to register for user " + userId
15504                        + " was previously registered for user " + rl.userId);
15505            }
15506            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15507                    permission, callingUid, userId);
15508            rl.add(bf);
15509            if (!bf.debugCheck()) {
15510                Slog.w(TAG, "==> For Dynamic broadast");
15511            }
15512            mReceiverResolver.addFilter(bf);
15513
15514            // Enqueue broadcasts for all existing stickies that match
15515            // this filter.
15516            if (allSticky != null) {
15517                ArrayList receivers = new ArrayList();
15518                receivers.add(bf);
15519
15520                int N = allSticky.size();
15521                for (int i=0; i<N; i++) {
15522                    Intent intent = (Intent)allSticky.get(i);
15523                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15524                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15525                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15526                            null, null, false, true, true, -1);
15527                    queue.enqueueParallelBroadcastLocked(r);
15528                    queue.scheduleBroadcastsLocked();
15529                }
15530            }
15531
15532            return sticky;
15533        }
15534    }
15535
15536    public void unregisterReceiver(IIntentReceiver receiver) {
15537        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
15538
15539        final long origId = Binder.clearCallingIdentity();
15540        try {
15541            boolean doTrim = false;
15542
15543            synchronized(this) {
15544                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15545                if (rl != null) {
15546                    final BroadcastRecord r = rl.curBroadcast;
15547                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
15548                        final boolean doNext = r.queue.finishReceiverLocked(
15549                                r, r.resultCode, r.resultData, r.resultExtras,
15550                                r.resultAbort, false);
15551                        if (doNext) {
15552                            doTrim = true;
15553                            r.queue.processNextBroadcast(false);
15554                        }
15555                    }
15556
15557                    if (rl.app != null) {
15558                        rl.app.receivers.remove(rl);
15559                    }
15560                    removeReceiverLocked(rl);
15561                    if (rl.linkedToDeath) {
15562                        rl.linkedToDeath = false;
15563                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15564                    }
15565                }
15566            }
15567
15568            // If we actually concluded any broadcasts, we might now be able
15569            // to trim the recipients' apps from our working set
15570            if (doTrim) {
15571                trimApplications();
15572                return;
15573            }
15574
15575        } finally {
15576            Binder.restoreCallingIdentity(origId);
15577        }
15578    }
15579
15580    void removeReceiverLocked(ReceiverList rl) {
15581        mRegisteredReceivers.remove(rl.receiver.asBinder());
15582        int N = rl.size();
15583        for (int i=0; i<N; i++) {
15584            mReceiverResolver.removeFilter(rl.get(i));
15585        }
15586    }
15587
15588    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15589        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15590            ProcessRecord r = mLruProcesses.get(i);
15591            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15592                try {
15593                    r.thread.dispatchPackageBroadcast(cmd, packages);
15594                } catch (RemoteException ex) {
15595                }
15596            }
15597        }
15598    }
15599
15600    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15601            int callingUid, int[] users) {
15602        List<ResolveInfo> receivers = null;
15603        try {
15604            HashSet<ComponentName> singleUserReceivers = null;
15605            boolean scannedFirstReceivers = false;
15606            for (int user : users) {
15607                // Skip users that have Shell restrictions
15608                if (callingUid == Process.SHELL_UID
15609                        && getUserManagerLocked().hasUserRestriction(
15610                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15611                    continue;
15612                }
15613                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15614                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15615                if (user != UserHandle.USER_OWNER && newReceivers != null) {
15616                    // If this is not the primary user, we need to check for
15617                    // any receivers that should be filtered out.
15618                    for (int i=0; i<newReceivers.size(); i++) {
15619                        ResolveInfo ri = newReceivers.get(i);
15620                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15621                            newReceivers.remove(i);
15622                            i--;
15623                        }
15624                    }
15625                }
15626                if (newReceivers != null && newReceivers.size() == 0) {
15627                    newReceivers = null;
15628                }
15629                if (receivers == null) {
15630                    receivers = newReceivers;
15631                } else if (newReceivers != null) {
15632                    // We need to concatenate the additional receivers
15633                    // found with what we have do far.  This would be easy,
15634                    // but we also need to de-dup any receivers that are
15635                    // singleUser.
15636                    if (!scannedFirstReceivers) {
15637                        // Collect any single user receivers we had already retrieved.
15638                        scannedFirstReceivers = true;
15639                        for (int i=0; i<receivers.size(); i++) {
15640                            ResolveInfo ri = receivers.get(i);
15641                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15642                                ComponentName cn = new ComponentName(
15643                                        ri.activityInfo.packageName, ri.activityInfo.name);
15644                                if (singleUserReceivers == null) {
15645                                    singleUserReceivers = new HashSet<ComponentName>();
15646                                }
15647                                singleUserReceivers.add(cn);
15648                            }
15649                        }
15650                    }
15651                    // Add the new results to the existing results, tracking
15652                    // and de-dupping single user receivers.
15653                    for (int i=0; i<newReceivers.size(); i++) {
15654                        ResolveInfo ri = newReceivers.get(i);
15655                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15656                            ComponentName cn = new ComponentName(
15657                                    ri.activityInfo.packageName, ri.activityInfo.name);
15658                            if (singleUserReceivers == null) {
15659                                singleUserReceivers = new HashSet<ComponentName>();
15660                            }
15661                            if (!singleUserReceivers.contains(cn)) {
15662                                singleUserReceivers.add(cn);
15663                                receivers.add(ri);
15664                            }
15665                        } else {
15666                            receivers.add(ri);
15667                        }
15668                    }
15669                }
15670            }
15671        } catch (RemoteException ex) {
15672            // pm is in same process, this will never happen.
15673        }
15674        return receivers;
15675    }
15676
15677    private final int broadcastIntentLocked(ProcessRecord callerApp,
15678            String callerPackage, Intent intent, String resolvedType,
15679            IIntentReceiver resultTo, int resultCode, String resultData,
15680            Bundle map, String requiredPermission, int appOp,
15681            boolean ordered, boolean sticky, int callingPid, int callingUid,
15682            int userId) {
15683        intent = new Intent(intent);
15684
15685        // By default broadcasts do not go to stopped apps.
15686        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15687
15688        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
15689                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15690                + " ordered=" + ordered + " userid=" + userId);
15691        if ((resultTo != null) && !ordered) {
15692            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15693        }
15694
15695        userId = handleIncomingUser(callingPid, callingUid, userId,
15696                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15697
15698        // Make sure that the user who is receiving this broadcast is running.
15699        // If not, we will just skip it. Make an exception for shutdown broadcasts
15700        // and upgrade steps.
15701
15702        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15703            if ((callingUid != Process.SYSTEM_UID
15704                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15705                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15706                Slog.w(TAG, "Skipping broadcast of " + intent
15707                        + ": user " + userId + " is stopped");
15708                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15709            }
15710        }
15711
15712        /*
15713         * Prevent non-system code (defined here to be non-persistent
15714         * processes) from sending protected broadcasts.
15715         */
15716        int callingAppId = UserHandle.getAppId(callingUid);
15717        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15718            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15719            || callingAppId == Process.NFC_UID || callingUid == 0) {
15720            // Always okay.
15721        } else if (callerApp == null || !callerApp.persistent) {
15722            try {
15723                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15724                        intent.getAction())) {
15725                    String msg = "Permission Denial: not allowed to send broadcast "
15726                            + intent.getAction() + " from pid="
15727                            + callingPid + ", uid=" + callingUid;
15728                    Slog.w(TAG, msg);
15729                    throw new SecurityException(msg);
15730                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15731                    // Special case for compatibility: we don't want apps to send this,
15732                    // but historically it has not been protected and apps may be using it
15733                    // to poke their own app widget.  So, instead of making it protected,
15734                    // just limit it to the caller.
15735                    if (callerApp == null) {
15736                        String msg = "Permission Denial: not allowed to send broadcast "
15737                                + intent.getAction() + " from unknown caller.";
15738                        Slog.w(TAG, msg);
15739                        throw new SecurityException(msg);
15740                    } else if (intent.getComponent() != null) {
15741                        // They are good enough to send to an explicit component...  verify
15742                        // it is being sent to the calling app.
15743                        if (!intent.getComponent().getPackageName().equals(
15744                                callerApp.info.packageName)) {
15745                            String msg = "Permission Denial: not allowed to send broadcast "
15746                                    + intent.getAction() + " to "
15747                                    + intent.getComponent().getPackageName() + " from "
15748                                    + callerApp.info.packageName;
15749                            Slog.w(TAG, msg);
15750                            throw new SecurityException(msg);
15751                        }
15752                    } else {
15753                        // Limit broadcast to their own package.
15754                        intent.setPackage(callerApp.info.packageName);
15755                    }
15756                }
15757            } catch (RemoteException e) {
15758                Slog.w(TAG, "Remote exception", e);
15759                return ActivityManager.BROADCAST_SUCCESS;
15760            }
15761        }
15762
15763        final String action = intent.getAction();
15764        if (action != null) {
15765            switch (action) {
15766                case Intent.ACTION_UID_REMOVED:
15767                case Intent.ACTION_PACKAGE_REMOVED:
15768                case Intent.ACTION_PACKAGE_CHANGED:
15769                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15770                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15771                    // Handle special intents: if this broadcast is from the package
15772                    // manager about a package being removed, we need to remove all of
15773                    // its activities from the history stack.
15774                    if (checkComponentPermission(
15775                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15776                            callingPid, callingUid, -1, true)
15777                            != PackageManager.PERMISSION_GRANTED) {
15778                        String msg = "Permission Denial: " + intent.getAction()
15779                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15780                                + ", uid=" + callingUid + ")"
15781                                + " requires "
15782                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15783                        Slog.w(TAG, msg);
15784                        throw new SecurityException(msg);
15785                    }
15786                    switch (action) {
15787                        case Intent.ACTION_UID_REMOVED:
15788                            final Bundle intentExtras = intent.getExtras();
15789                            final int uid = intentExtras != null
15790                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15791                            if (uid >= 0) {
15792                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15793                                synchronized (bs) {
15794                                    bs.removeUidStatsLocked(uid);
15795                                }
15796                                mAppOpsService.uidRemoved(uid);
15797                            }
15798                            break;
15799                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15800                            // If resources are unavailable just force stop all those packages
15801                            // and flush the attribute cache as well.
15802                            String list[] =
15803                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15804                            if (list != null && list.length > 0) {
15805                                for (int i = 0; i < list.length; i++) {
15806                                    forceStopPackageLocked(list[i], -1, false, true, true,
15807                                            false, false, userId, "storage unmount");
15808                                }
15809                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
15810                                sendPackageBroadcastLocked(
15811                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15812                                        userId);
15813                            }
15814                            break;
15815                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15816                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
15817                            break;
15818                        case Intent.ACTION_PACKAGE_REMOVED:
15819                        case Intent.ACTION_PACKAGE_CHANGED:
15820                            Uri data = intent.getData();
15821                            String ssp;
15822                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15823                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15824                                boolean fullUninstall = removed &&
15825                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15826                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15827                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15828                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15829                                            false, true, true, false, fullUninstall, userId,
15830                                            removed ? "pkg removed" : "pkg changed");
15831                                }
15832                                if (removed) {
15833                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15834                                            new String[] {ssp}, userId);
15835                                    if (fullUninstall) {
15836                                        mAppOpsService.packageRemoved(
15837                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15838
15839                                        // Remove all permissions granted from/to this package
15840                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15841
15842                                        removeTasksByPackageNameLocked(ssp, userId);
15843                                        if (userId == UserHandle.USER_OWNER) {
15844                                            mTaskPersister.removeFromPackageCache(ssp);
15845                                        }
15846                                        mBatteryStatsService.notePackageUninstalled(ssp);
15847                                    }
15848                                } else {
15849                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15850                                    if (userId == UserHandle.USER_OWNER) {
15851                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15852                                    }
15853                                }
15854                            }
15855                            break;
15856                    }
15857                    break;
15858                case Intent.ACTION_PACKAGE_ADDED:
15859                    // Special case for adding a package: by default turn on compatibility mode.
15860                    Uri data = intent.getData();
15861                    String ssp;
15862                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15863                        final boolean replacing =
15864                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15865                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15866
15867                        if (replacing) {
15868                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15869                        }
15870                        if (userId == UserHandle.USER_OWNER) {
15871                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15872                        }
15873                        try {
15874                            ApplicationInfo ai = AppGlobals.getPackageManager().
15875                                    getApplicationInfo(ssp, 0, 0);
15876                            mBatteryStatsService.notePackageInstalled(ssp,
15877                                    ai != null ? ai.versionCode : 0);
15878                        } catch (RemoteException e) {
15879                        }
15880                    }
15881                    break;
15882                case Intent.ACTION_TIMEZONE_CHANGED:
15883                    // If this is the time zone changed action, queue up a message that will reset
15884                    // the timezone of all currently running processes. This message will get
15885                    // queued up before the broadcast happens.
15886                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15887                    break;
15888                case Intent.ACTION_TIME_CHANGED:
15889                    // If the user set the time, let all running processes know.
15890                    final int is24Hour =
15891                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15892                                    : 0;
15893                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15894                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15895                    synchronized (stats) {
15896                        stats.noteCurrentTimeChangedLocked();
15897                    }
15898                    break;
15899                case Intent.ACTION_CLEAR_DNS_CACHE:
15900                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15901                    break;
15902                case Proxy.PROXY_CHANGE_ACTION:
15903                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15904                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15905                    break;
15906            }
15907        }
15908
15909        // Add to the sticky list if requested.
15910        if (sticky) {
15911            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15912                    callingPid, callingUid)
15913                    != PackageManager.PERMISSION_GRANTED) {
15914                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15915                        + callingPid + ", uid=" + callingUid
15916                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15917                Slog.w(TAG, msg);
15918                throw new SecurityException(msg);
15919            }
15920            if (requiredPermission != null) {
15921                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15922                        + " and enforce permission " + requiredPermission);
15923                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15924            }
15925            if (intent.getComponent() != null) {
15926                throw new SecurityException(
15927                        "Sticky broadcasts can't target a specific component");
15928            }
15929            // We use userId directly here, since the "all" target is maintained
15930            // as a separate set of sticky broadcasts.
15931            if (userId != UserHandle.USER_ALL) {
15932                // But first, if this is not a broadcast to all users, then
15933                // make sure it doesn't conflict with an existing broadcast to
15934                // all users.
15935                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15936                        UserHandle.USER_ALL);
15937                if (stickies != null) {
15938                    ArrayList<Intent> list = stickies.get(intent.getAction());
15939                    if (list != null) {
15940                        int N = list.size();
15941                        int i;
15942                        for (i=0; i<N; i++) {
15943                            if (intent.filterEquals(list.get(i))) {
15944                                throw new IllegalArgumentException(
15945                                        "Sticky broadcast " + intent + " for user "
15946                                        + userId + " conflicts with existing global broadcast");
15947                            }
15948                        }
15949                    }
15950                }
15951            }
15952            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15953            if (stickies == null) {
15954                stickies = new ArrayMap<String, ArrayList<Intent>>();
15955                mStickyBroadcasts.put(userId, stickies);
15956            }
15957            ArrayList<Intent> list = stickies.get(intent.getAction());
15958            if (list == null) {
15959                list = new ArrayList<Intent>();
15960                stickies.put(intent.getAction(), list);
15961            }
15962            int N = list.size();
15963            int i;
15964            for (i=0; i<N; i++) {
15965                if (intent.filterEquals(list.get(i))) {
15966                    // This sticky already exists, replace it.
15967                    list.set(i, new Intent(intent));
15968                    break;
15969                }
15970            }
15971            if (i >= N) {
15972                list.add(new Intent(intent));
15973            }
15974        }
15975
15976        int[] users;
15977        if (userId == UserHandle.USER_ALL) {
15978            // Caller wants broadcast to go to all started users.
15979            users = mStartedUserArray;
15980        } else {
15981            // Caller wants broadcast to go to one specific user.
15982            users = new int[] {userId};
15983        }
15984
15985        // Figure out who all will receive this broadcast.
15986        List receivers = null;
15987        List<BroadcastFilter> registeredReceivers = null;
15988        // Need to resolve the intent to interested receivers...
15989        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15990                 == 0) {
15991            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15992        }
15993        if (intent.getComponent() == null) {
15994            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15995                // Query one target user at a time, excluding shell-restricted users
15996                UserManagerService ums = getUserManagerLocked();
15997                for (int i = 0; i < users.length; i++) {
15998                    if (ums.hasUserRestriction(
15999                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16000                        continue;
16001                    }
16002                    List<BroadcastFilter> registeredReceiversForUser =
16003                            mReceiverResolver.queryIntent(intent,
16004                                    resolvedType, false, users[i]);
16005                    if (registeredReceivers == null) {
16006                        registeredReceivers = registeredReceiversForUser;
16007                    } else if (registeredReceiversForUser != null) {
16008                        registeredReceivers.addAll(registeredReceiversForUser);
16009                    }
16010                }
16011            } else {
16012                registeredReceivers = mReceiverResolver.queryIntent(intent,
16013                        resolvedType, false, userId);
16014            }
16015        }
16016
16017        final boolean replacePending =
16018                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16019
16020        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16021                + " replacePending=" + replacePending);
16022
16023        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16024        if (!ordered && NR > 0) {
16025            // If we are not serializing this broadcast, then send the
16026            // registered receivers separately so they don't wait for the
16027            // components to be launched.
16028            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16029            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16030                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16031                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16032                    ordered, sticky, false, userId);
16033            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16034            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16035            if (!replaced) {
16036                queue.enqueueParallelBroadcastLocked(r);
16037                queue.scheduleBroadcastsLocked();
16038            }
16039            registeredReceivers = null;
16040            NR = 0;
16041        }
16042
16043        // Merge into one list.
16044        int ir = 0;
16045        if (receivers != null) {
16046            // A special case for PACKAGE_ADDED: do not allow the package
16047            // being added to see this broadcast.  This prevents them from
16048            // using this as a back door to get run as soon as they are
16049            // installed.  Maybe in the future we want to have a special install
16050            // broadcast or such for apps, but we'd like to deliberately make
16051            // this decision.
16052            String skipPackages[] = null;
16053            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16054                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16055                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16056                Uri data = intent.getData();
16057                if (data != null) {
16058                    String pkgName = data.getSchemeSpecificPart();
16059                    if (pkgName != null) {
16060                        skipPackages = new String[] { pkgName };
16061                    }
16062                }
16063            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16064                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16065            }
16066            if (skipPackages != null && (skipPackages.length > 0)) {
16067                for (String skipPackage : skipPackages) {
16068                    if (skipPackage != null) {
16069                        int NT = receivers.size();
16070                        for (int it=0; it<NT; it++) {
16071                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16072                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16073                                receivers.remove(it);
16074                                it--;
16075                                NT--;
16076                            }
16077                        }
16078                    }
16079                }
16080            }
16081
16082            int NT = receivers != null ? receivers.size() : 0;
16083            int it = 0;
16084            ResolveInfo curt = null;
16085            BroadcastFilter curr = null;
16086            while (it < NT && ir < NR) {
16087                if (curt == null) {
16088                    curt = (ResolveInfo)receivers.get(it);
16089                }
16090                if (curr == null) {
16091                    curr = registeredReceivers.get(ir);
16092                }
16093                if (curr.getPriority() >= curt.priority) {
16094                    // Insert this broadcast record into the final list.
16095                    receivers.add(it, curr);
16096                    ir++;
16097                    curr = null;
16098                    it++;
16099                    NT++;
16100                } else {
16101                    // Skip to the next ResolveInfo in the final list.
16102                    it++;
16103                    curt = null;
16104                }
16105            }
16106        }
16107        while (ir < NR) {
16108            if (receivers == null) {
16109                receivers = new ArrayList();
16110            }
16111            receivers.add(registeredReceivers.get(ir));
16112            ir++;
16113        }
16114
16115        if ((receivers != null && receivers.size() > 0)
16116                || resultTo != null) {
16117            BroadcastQueue queue = broadcastQueueForIntent(intent);
16118            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16119                    callerPackage, callingPid, callingUid, resolvedType,
16120                    requiredPermission, appOp, receivers, resultTo, resultCode,
16121                    resultData, map, ordered, sticky, false, userId);
16122
16123            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16124                    + ": prev had " + queue.mOrderedBroadcasts.size());
16125            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16126                    "Enqueueing broadcast " + r.intent.getAction());
16127
16128            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16129            if (!replaced) {
16130                queue.enqueueOrderedBroadcastLocked(r);
16131                queue.scheduleBroadcastsLocked();
16132            }
16133        }
16134
16135        return ActivityManager.BROADCAST_SUCCESS;
16136    }
16137
16138    final Intent verifyBroadcastLocked(Intent intent) {
16139        // Refuse possible leaked file descriptors
16140        if (intent != null && intent.hasFileDescriptors() == true) {
16141            throw new IllegalArgumentException("File descriptors passed in Intent");
16142        }
16143
16144        int flags = intent.getFlags();
16145
16146        if (!mProcessesReady) {
16147            // if the caller really truly claims to know what they're doing, go
16148            // ahead and allow the broadcast without launching any receivers
16149            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16150                intent = new Intent(intent);
16151                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16152            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16153                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16154                        + " before boot completion");
16155                throw new IllegalStateException("Cannot broadcast before boot completed");
16156            }
16157        }
16158
16159        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16160            throw new IllegalArgumentException(
16161                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16162        }
16163
16164        return intent;
16165    }
16166
16167    public final int broadcastIntent(IApplicationThread caller,
16168            Intent intent, String resolvedType, IIntentReceiver resultTo,
16169            int resultCode, String resultData, Bundle map,
16170            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16171        enforceNotIsolatedCaller("broadcastIntent");
16172        synchronized(this) {
16173            intent = verifyBroadcastLocked(intent);
16174
16175            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16176            final int callingPid = Binder.getCallingPid();
16177            final int callingUid = Binder.getCallingUid();
16178            final long origId = Binder.clearCallingIdentity();
16179            int res = broadcastIntentLocked(callerApp,
16180                    callerApp != null ? callerApp.info.packageName : null,
16181                    intent, resolvedType, resultTo,
16182                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16183                    callingPid, callingUid, userId);
16184            Binder.restoreCallingIdentity(origId);
16185            return res;
16186        }
16187    }
16188
16189    int broadcastIntentInPackage(String packageName, int uid,
16190            Intent intent, String resolvedType, IIntentReceiver resultTo,
16191            int resultCode, String resultData, Bundle map,
16192            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16193        synchronized(this) {
16194            intent = verifyBroadcastLocked(intent);
16195
16196            final long origId = Binder.clearCallingIdentity();
16197            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16198                    resultTo, resultCode, resultData, map, requiredPermission,
16199                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16200            Binder.restoreCallingIdentity(origId);
16201            return res;
16202        }
16203    }
16204
16205    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16206        // Refuse possible leaked file descriptors
16207        if (intent != null && intent.hasFileDescriptors() == true) {
16208            throw new IllegalArgumentException("File descriptors passed in Intent");
16209        }
16210
16211        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16212                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16213
16214        synchronized(this) {
16215            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16216                    != PackageManager.PERMISSION_GRANTED) {
16217                String msg = "Permission Denial: unbroadcastIntent() from pid="
16218                        + Binder.getCallingPid()
16219                        + ", uid=" + Binder.getCallingUid()
16220                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16221                Slog.w(TAG, msg);
16222                throw new SecurityException(msg);
16223            }
16224            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16225            if (stickies != null) {
16226                ArrayList<Intent> list = stickies.get(intent.getAction());
16227                if (list != null) {
16228                    int N = list.size();
16229                    int i;
16230                    for (i=0; i<N; i++) {
16231                        if (intent.filterEquals(list.get(i))) {
16232                            list.remove(i);
16233                            break;
16234                        }
16235                    }
16236                    if (list.size() <= 0) {
16237                        stickies.remove(intent.getAction());
16238                    }
16239                }
16240                if (stickies.size() <= 0) {
16241                    mStickyBroadcasts.remove(userId);
16242                }
16243            }
16244        }
16245    }
16246
16247    void backgroundServicesFinishedLocked(int userId) {
16248        for (BroadcastQueue queue : mBroadcastQueues) {
16249            queue.backgroundServicesFinishedLocked(userId);
16250        }
16251    }
16252
16253    public void finishReceiver(IBinder who, int resultCode, String resultData,
16254            Bundle resultExtras, boolean resultAbort, int flags) {
16255        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
16256
16257        // Refuse possible leaked file descriptors
16258        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16259            throw new IllegalArgumentException("File descriptors passed in Bundle");
16260        }
16261
16262        final long origId = Binder.clearCallingIdentity();
16263        try {
16264            boolean doNext = false;
16265            BroadcastRecord r;
16266
16267            synchronized(this) {
16268                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16269                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16270                r = queue.getMatchingOrderedReceiver(who);
16271                if (r != null) {
16272                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16273                        resultData, resultExtras, resultAbort, true);
16274                }
16275            }
16276
16277            if (doNext) {
16278                r.queue.processNextBroadcast(false);
16279            }
16280            trimApplications();
16281        } finally {
16282            Binder.restoreCallingIdentity(origId);
16283        }
16284    }
16285
16286    // =========================================================
16287    // INSTRUMENTATION
16288    // =========================================================
16289
16290    public boolean startInstrumentation(ComponentName className,
16291            String profileFile, int flags, Bundle arguments,
16292            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16293            int userId, String abiOverride) {
16294        enforceNotIsolatedCaller("startInstrumentation");
16295        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16296                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16297        // Refuse possible leaked file descriptors
16298        if (arguments != null && arguments.hasFileDescriptors()) {
16299            throw new IllegalArgumentException("File descriptors passed in Bundle");
16300        }
16301
16302        synchronized(this) {
16303            InstrumentationInfo ii = null;
16304            ApplicationInfo ai = null;
16305            try {
16306                ii = mContext.getPackageManager().getInstrumentationInfo(
16307                    className, STOCK_PM_FLAGS);
16308                ai = AppGlobals.getPackageManager().getApplicationInfo(
16309                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16310            } catch (PackageManager.NameNotFoundException e) {
16311            } catch (RemoteException e) {
16312            }
16313            if (ii == null) {
16314                reportStartInstrumentationFailure(watcher, className,
16315                        "Unable to find instrumentation info for: " + className);
16316                return false;
16317            }
16318            if (ai == null) {
16319                reportStartInstrumentationFailure(watcher, className,
16320                        "Unable to find instrumentation target package: " + ii.targetPackage);
16321                return false;
16322            }
16323
16324            int match = mContext.getPackageManager().checkSignatures(
16325                    ii.targetPackage, ii.packageName);
16326            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16327                String msg = "Permission Denial: starting instrumentation "
16328                        + className + " from pid="
16329                        + Binder.getCallingPid()
16330                        + ", uid=" + Binder.getCallingPid()
16331                        + " not allowed because package " + ii.packageName
16332                        + " does not have a signature matching the target "
16333                        + ii.targetPackage;
16334                reportStartInstrumentationFailure(watcher, className, msg);
16335                throw new SecurityException(msg);
16336            }
16337
16338            final long origId = Binder.clearCallingIdentity();
16339            // Instrumentation can kill and relaunch even persistent processes
16340            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16341                    "start instr");
16342            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16343            app.instrumentationClass = className;
16344            app.instrumentationInfo = ai;
16345            app.instrumentationProfileFile = profileFile;
16346            app.instrumentationArguments = arguments;
16347            app.instrumentationWatcher = watcher;
16348            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16349            app.instrumentationResultClass = className;
16350            Binder.restoreCallingIdentity(origId);
16351        }
16352
16353        return true;
16354    }
16355
16356    /**
16357     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16358     * error to the logs, but if somebody is watching, send the report there too.  This enables
16359     * the "am" command to report errors with more information.
16360     *
16361     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16362     * @param cn The component name of the instrumentation.
16363     * @param report The error report.
16364     */
16365    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16366            ComponentName cn, String report) {
16367        Slog.w(TAG, report);
16368        try {
16369            if (watcher != null) {
16370                Bundle results = new Bundle();
16371                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16372                results.putString("Error", report);
16373                watcher.instrumentationStatus(cn, -1, results);
16374            }
16375        } catch (RemoteException e) {
16376            Slog.w(TAG, e);
16377        }
16378    }
16379
16380    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16381        if (app.instrumentationWatcher != null) {
16382            try {
16383                // NOTE:  IInstrumentationWatcher *must* be oneway here
16384                app.instrumentationWatcher.instrumentationFinished(
16385                    app.instrumentationClass,
16386                    resultCode,
16387                    results);
16388            } catch (RemoteException e) {
16389            }
16390        }
16391        if (app.instrumentationUiAutomationConnection != null) {
16392            try {
16393                app.instrumentationUiAutomationConnection.shutdown();
16394            } catch (RemoteException re) {
16395                /* ignore */
16396            }
16397            // Only a UiAutomation can set this flag and now that
16398            // it is finished we make sure it is reset to its default.
16399            mUserIsMonkey = false;
16400        }
16401        app.instrumentationWatcher = null;
16402        app.instrumentationUiAutomationConnection = null;
16403        app.instrumentationClass = null;
16404        app.instrumentationInfo = null;
16405        app.instrumentationProfileFile = null;
16406        app.instrumentationArguments = null;
16407
16408        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16409                "finished inst");
16410    }
16411
16412    public void finishInstrumentation(IApplicationThread target,
16413            int resultCode, Bundle results) {
16414        int userId = UserHandle.getCallingUserId();
16415        // Refuse possible leaked file descriptors
16416        if (results != null && results.hasFileDescriptors()) {
16417            throw new IllegalArgumentException("File descriptors passed in Intent");
16418        }
16419
16420        synchronized(this) {
16421            ProcessRecord app = getRecordForAppLocked(target);
16422            if (app == null) {
16423                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16424                return;
16425            }
16426            final long origId = Binder.clearCallingIdentity();
16427            finishInstrumentationLocked(app, resultCode, results);
16428            Binder.restoreCallingIdentity(origId);
16429        }
16430    }
16431
16432    // =========================================================
16433    // CONFIGURATION
16434    // =========================================================
16435
16436    public ConfigurationInfo getDeviceConfigurationInfo() {
16437        ConfigurationInfo config = new ConfigurationInfo();
16438        synchronized (this) {
16439            config.reqTouchScreen = mConfiguration.touchscreen;
16440            config.reqKeyboardType = mConfiguration.keyboard;
16441            config.reqNavigation = mConfiguration.navigation;
16442            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16443                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16444                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16445            }
16446            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16447                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16448                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16449            }
16450            config.reqGlEsVersion = GL_ES_VERSION;
16451        }
16452        return config;
16453    }
16454
16455    ActivityStack getFocusedStack() {
16456        return mStackSupervisor.getFocusedStack();
16457    }
16458
16459    @Override
16460    public int getFocusedStackId() throws RemoteException {
16461        ActivityStack focusedStack = getFocusedStack();
16462        if (focusedStack != null) {
16463            return focusedStack.getStackId();
16464        }
16465        return -1;
16466    }
16467
16468    public Configuration getConfiguration() {
16469        Configuration ci;
16470        synchronized(this) {
16471            ci = new Configuration(mConfiguration);
16472            ci.userSetLocale = false;
16473        }
16474        return ci;
16475    }
16476
16477    public void updatePersistentConfiguration(Configuration values) {
16478        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16479                "updateConfiguration()");
16480        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16481                "updateConfiguration()");
16482        if (values == null) {
16483            throw new NullPointerException("Configuration must not be null");
16484        }
16485
16486        synchronized(this) {
16487            final long origId = Binder.clearCallingIdentity();
16488            updateConfigurationLocked(values, null, true, false);
16489            Binder.restoreCallingIdentity(origId);
16490        }
16491    }
16492
16493    public void updateConfiguration(Configuration values) {
16494        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16495                "updateConfiguration()");
16496
16497        synchronized(this) {
16498            if (values == null && mWindowManager != null) {
16499                // sentinel: fetch the current configuration from the window manager
16500                values = mWindowManager.computeNewConfiguration();
16501            }
16502
16503            if (mWindowManager != null) {
16504                mProcessList.applyDisplaySize(mWindowManager);
16505            }
16506
16507            final long origId = Binder.clearCallingIdentity();
16508            if (values != null) {
16509                Settings.System.clearConfiguration(values);
16510            }
16511            updateConfigurationLocked(values, null, false, false);
16512            Binder.restoreCallingIdentity(origId);
16513        }
16514    }
16515
16516    /**
16517     * Do either or both things: (1) change the current configuration, and (2)
16518     * make sure the given activity is running with the (now) current
16519     * configuration.  Returns true if the activity has been left running, or
16520     * false if <var>starting</var> is being destroyed to match the new
16521     * configuration.
16522     * @param persistent TODO
16523     */
16524    boolean updateConfigurationLocked(Configuration values,
16525            ActivityRecord starting, boolean persistent, boolean initLocale) {
16526        int changes = 0;
16527
16528        if (values != null) {
16529            Configuration newConfig = new Configuration(mConfiguration);
16530            changes = newConfig.updateFrom(values);
16531            if (changes != 0) {
16532                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
16533                        "Updating configuration to: " + values);
16534
16535                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16536
16537                if (!initLocale && values.locale != null && values.userSetLocale) {
16538                    final String languageTag = values.locale.toLanguageTag();
16539                    SystemProperties.set("persist.sys.locale", languageTag);
16540                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
16541                            values.locale));
16542                }
16543
16544                mConfigurationSeq++;
16545                if (mConfigurationSeq <= 0) {
16546                    mConfigurationSeq = 1;
16547                }
16548                newConfig.seq = mConfigurationSeq;
16549                mConfiguration = newConfig;
16550                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16551                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16552                //mUsageStatsService.noteStartConfig(newConfig);
16553
16554                final Configuration configCopy = new Configuration(mConfiguration);
16555
16556                // TODO: If our config changes, should we auto dismiss any currently
16557                // showing dialogs?
16558                mShowDialogs = shouldShowDialogs(newConfig);
16559
16560                AttributeCache ac = AttributeCache.instance();
16561                if (ac != null) {
16562                    ac.updateConfiguration(configCopy);
16563                }
16564
16565                // Make sure all resources in our process are updated
16566                // right now, so that anyone who is going to retrieve
16567                // resource values after we return will be sure to get
16568                // the new ones.  This is especially important during
16569                // boot, where the first config change needs to guarantee
16570                // all resources have that config before following boot
16571                // code is executed.
16572                mSystemThread.applyConfigurationToResources(configCopy);
16573
16574                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16575                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16576                    msg.obj = new Configuration(configCopy);
16577                    mHandler.sendMessage(msg);
16578                }
16579
16580                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16581                    ProcessRecord app = mLruProcesses.get(i);
16582                    try {
16583                        if (app.thread != null) {
16584                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
16585                                    + app.processName + " new config " + mConfiguration);
16586                            app.thread.scheduleConfigurationChanged(configCopy);
16587                        }
16588                    } catch (Exception e) {
16589                    }
16590                }
16591                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16592                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16593                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16594                        | Intent.FLAG_RECEIVER_FOREGROUND);
16595                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16596                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16597                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16598                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16599                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16600                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16601                    broadcastIntentLocked(null, null, intent,
16602                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16603                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16604                }
16605            }
16606        }
16607
16608        boolean kept = true;
16609        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16610        // mainStack is null during startup.
16611        if (mainStack != null) {
16612            if (changes != 0 && starting == null) {
16613                // If the configuration changed, and the caller is not already
16614                // in the process of starting an activity, then find the top
16615                // activity to check if its configuration needs to change.
16616                starting = mainStack.topRunningActivityLocked(null);
16617            }
16618
16619            if (starting != null) {
16620                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16621                // And we need to make sure at this point that all other activities
16622                // are made visible with the correct configuration.
16623                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16624            }
16625        }
16626
16627        if (values != null && mWindowManager != null) {
16628            mWindowManager.setNewConfiguration(mConfiguration);
16629        }
16630
16631        return kept;
16632    }
16633
16634    /**
16635     * Decide based on the configuration whether we should shouw the ANR,
16636     * crash, etc dialogs.  The idea is that if there is no affordnace to
16637     * press the on-screen buttons, we shouldn't show the dialog.
16638     *
16639     * A thought: SystemUI might also want to get told about this, the Power
16640     * dialog / global actions also might want different behaviors.
16641     */
16642    private static final boolean shouldShowDialogs(Configuration config) {
16643        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16644                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
16645                && config.navigation == Configuration.NAVIGATION_NONAV);
16646    }
16647
16648    @Override
16649    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16650        synchronized (this) {
16651            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
16652            if (srec != null) {
16653                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16654            }
16655        }
16656        return false;
16657    }
16658
16659    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16660            Intent resultData) {
16661
16662        synchronized (this) {
16663            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
16664            if (r != null) {
16665                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
16666            }
16667            return false;
16668        }
16669    }
16670
16671    public int getLaunchedFromUid(IBinder activityToken) {
16672        ActivityRecord srec;
16673        synchronized (this) {
16674            srec = ActivityRecord.forTokenLocked(activityToken);
16675        }
16676        if (srec == null) {
16677            return -1;
16678        }
16679        return srec.launchedFromUid;
16680    }
16681
16682    public String getLaunchedFromPackage(IBinder activityToken) {
16683        ActivityRecord srec;
16684        synchronized (this) {
16685            srec = ActivityRecord.forTokenLocked(activityToken);
16686        }
16687        if (srec == null) {
16688            return null;
16689        }
16690        return srec.launchedFromPackage;
16691    }
16692
16693    // =========================================================
16694    // LIFETIME MANAGEMENT
16695    // =========================================================
16696
16697    // Returns which broadcast queue the app is the current [or imminent] receiver
16698    // on, or 'null' if the app is not an active broadcast recipient.
16699    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16700        BroadcastRecord r = app.curReceiver;
16701        if (r != null) {
16702            return r.queue;
16703        }
16704
16705        // It's not the current receiver, but it might be starting up to become one
16706        synchronized (this) {
16707            for (BroadcastQueue queue : mBroadcastQueues) {
16708                r = queue.mPendingBroadcast;
16709                if (r != null && r.curApp == app) {
16710                    // found it; report which queue it's in
16711                    return queue;
16712                }
16713            }
16714        }
16715
16716        return null;
16717    }
16718
16719    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16720            ComponentName targetComponent, String targetProcess) {
16721        if (!mTrackingAssociations) {
16722            return null;
16723        }
16724        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16725                = mAssociations.get(targetUid);
16726        if (components == null) {
16727            components = new ArrayMap<>();
16728            mAssociations.put(targetUid, components);
16729        }
16730        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16731        if (sourceUids == null) {
16732            sourceUids = new SparseArray<>();
16733            components.put(targetComponent, sourceUids);
16734        }
16735        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16736        if (sourceProcesses == null) {
16737            sourceProcesses = new ArrayMap<>();
16738            sourceUids.put(sourceUid, sourceProcesses);
16739        }
16740        Association ass = sourceProcesses.get(sourceProcess);
16741        if (ass == null) {
16742            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
16743                    targetProcess);
16744            sourceProcesses.put(sourceProcess, ass);
16745        }
16746        ass.mCount++;
16747        ass.mNesting++;
16748        if (ass.mNesting == 1) {
16749            ass.mStartTime = SystemClock.uptimeMillis();
16750        }
16751        return ass;
16752    }
16753
16754    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16755            ComponentName targetComponent) {
16756        if (!mTrackingAssociations) {
16757            return;
16758        }
16759        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16760                = mAssociations.get(targetUid);
16761        if (components == null) {
16762            return;
16763        }
16764        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16765        if (sourceUids == null) {
16766            return;
16767        }
16768        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16769        if (sourceProcesses == null) {
16770            return;
16771        }
16772        Association ass = sourceProcesses.get(sourceProcess);
16773        if (ass == null || ass.mNesting <= 0) {
16774            return;
16775        }
16776        ass.mNesting--;
16777        if (ass.mNesting == 0) {
16778            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
16779        }
16780    }
16781
16782    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16783            boolean doingAll, long now) {
16784        if (mAdjSeq == app.adjSeq) {
16785            // This adjustment has already been computed.
16786            return app.curRawAdj;
16787        }
16788
16789        if (app.thread == null) {
16790            app.adjSeq = mAdjSeq;
16791            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16792            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16793            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16794        }
16795
16796        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16797        app.adjSource = null;
16798        app.adjTarget = null;
16799        app.empty = false;
16800        app.cached = false;
16801
16802        final int activitiesSize = app.activities.size();
16803
16804        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16805            // The max adjustment doesn't allow this app to be anything
16806            // below foreground, so it is not worth doing work for it.
16807            app.adjType = "fixed";
16808            app.adjSeq = mAdjSeq;
16809            app.curRawAdj = app.maxAdj;
16810            app.foregroundActivities = false;
16811            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16812            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16813            // System processes can do UI, and when they do we want to have
16814            // them trim their memory after the user leaves the UI.  To
16815            // facilitate this, here we need to determine whether or not it
16816            // is currently showing UI.
16817            app.systemNoUi = true;
16818            if (app == TOP_APP) {
16819                app.systemNoUi = false;
16820            } else if (activitiesSize > 0) {
16821                for (int j = 0; j < activitiesSize; j++) {
16822                    final ActivityRecord r = app.activities.get(j);
16823                    if (r.visible) {
16824                        app.systemNoUi = false;
16825                    }
16826                }
16827            }
16828            if (!app.systemNoUi) {
16829                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16830            }
16831            return (app.curAdj=app.maxAdj);
16832        }
16833
16834        app.systemNoUi = false;
16835
16836        // Determine the importance of the process, starting with most
16837        // important to least, and assign an appropriate OOM adjustment.
16838        int adj;
16839        int schedGroup;
16840        int procState;
16841        boolean foregroundActivities = false;
16842        BroadcastQueue queue;
16843        if (app == TOP_APP) {
16844            // The last app on the list is the foreground app.
16845            adj = ProcessList.FOREGROUND_APP_ADJ;
16846            schedGroup = Process.THREAD_GROUP_DEFAULT;
16847            app.adjType = "top-activity";
16848            foregroundActivities = true;
16849            procState = ActivityManager.PROCESS_STATE_TOP;
16850        } else if (app.instrumentationClass != null) {
16851            // Don't want to kill running instrumentation.
16852            adj = ProcessList.FOREGROUND_APP_ADJ;
16853            schedGroup = Process.THREAD_GROUP_DEFAULT;
16854            app.adjType = "instrumentation";
16855            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16856        } else if ((queue = isReceivingBroadcast(app)) != null) {
16857            // An app that is currently receiving a broadcast also
16858            // counts as being in the foreground for OOM killer purposes.
16859            // It's placed in a sched group based on the nature of the
16860            // broadcast as reflected by which queue it's active in.
16861            adj = ProcessList.FOREGROUND_APP_ADJ;
16862            schedGroup = (queue == mFgBroadcastQueue)
16863                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16864            app.adjType = "broadcast";
16865            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16866        } else if (app.executingServices.size() > 0) {
16867            // An app that is currently executing a service callback also
16868            // counts as being in the foreground.
16869            adj = ProcessList.FOREGROUND_APP_ADJ;
16870            schedGroup = app.execServicesFg ?
16871                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16872            app.adjType = "exec-service";
16873            procState = ActivityManager.PROCESS_STATE_SERVICE;
16874            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16875        } else {
16876            // As far as we know the process is empty.  We may change our mind later.
16877            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16878            // At this point we don't actually know the adjustment.  Use the cached adj
16879            // value that the caller wants us to.
16880            adj = cachedAdj;
16881            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16882            app.cached = true;
16883            app.empty = true;
16884            app.adjType = "cch-empty";
16885        }
16886
16887        // Examine all activities if not already foreground.
16888        if (!foregroundActivities && activitiesSize > 0) {
16889            for (int j = 0; j < activitiesSize; j++) {
16890                final ActivityRecord r = app.activities.get(j);
16891                if (r.app != app) {
16892                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16893                            + app + "?!?");
16894                    continue;
16895                }
16896                if (r.visible) {
16897                    // App has a visible activity; only upgrade adjustment.
16898                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16899                        adj = ProcessList.VISIBLE_APP_ADJ;
16900                        app.adjType = "visible";
16901                    }
16902                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16903                        procState = ActivityManager.PROCESS_STATE_TOP;
16904                    }
16905                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16906                    app.cached = false;
16907                    app.empty = false;
16908                    foregroundActivities = true;
16909                    break;
16910                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16911                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16912                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16913                        app.adjType = "pausing";
16914                    }
16915                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16916                        procState = ActivityManager.PROCESS_STATE_TOP;
16917                    }
16918                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16919                    app.cached = false;
16920                    app.empty = false;
16921                    foregroundActivities = true;
16922                } else if (r.state == ActivityState.STOPPING) {
16923                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16924                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16925                        app.adjType = "stopping";
16926                    }
16927                    // For the process state, we will at this point consider the
16928                    // process to be cached.  It will be cached either as an activity
16929                    // or empty depending on whether the activity is finishing.  We do
16930                    // this so that we can treat the process as cached for purposes of
16931                    // memory trimming (determing current memory level, trim command to
16932                    // send to process) since there can be an arbitrary number of stopping
16933                    // processes and they should soon all go into the cached state.
16934                    if (!r.finishing) {
16935                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16936                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16937                        }
16938                    }
16939                    app.cached = false;
16940                    app.empty = false;
16941                    foregroundActivities = true;
16942                } else {
16943                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16944                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16945                        app.adjType = "cch-act";
16946                    }
16947                }
16948            }
16949        }
16950
16951        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16952            if (app.foregroundServices) {
16953                // The user is aware of this app, so make it visible.
16954                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16955                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16956                app.cached = false;
16957                app.adjType = "fg-service";
16958                schedGroup = Process.THREAD_GROUP_DEFAULT;
16959            } else if (app.forcingToForeground != null) {
16960                // The user is aware of this app, so make it visible.
16961                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16962                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16963                app.cached = false;
16964                app.adjType = "force-fg";
16965                app.adjSource = app.forcingToForeground;
16966                schedGroup = Process.THREAD_GROUP_DEFAULT;
16967            }
16968        }
16969
16970        if (app == mHeavyWeightProcess) {
16971            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16972                // We don't want to kill the current heavy-weight process.
16973                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16974                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16975                app.cached = false;
16976                app.adjType = "heavy";
16977            }
16978            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16979                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16980            }
16981        }
16982
16983        if (app == mHomeProcess) {
16984            if (adj > ProcessList.HOME_APP_ADJ) {
16985                // This process is hosting what we currently consider to be the
16986                // home app, so we don't want to let it go into the background.
16987                adj = ProcessList.HOME_APP_ADJ;
16988                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16989                app.cached = false;
16990                app.adjType = "home";
16991            }
16992            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16993                procState = ActivityManager.PROCESS_STATE_HOME;
16994            }
16995        }
16996
16997        if (app == mPreviousProcess && app.activities.size() > 0) {
16998            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16999                // This was the previous process that showed UI to the user.
17000                // We want to try to keep it around more aggressively, to give
17001                // a good experience around switching between two apps.
17002                adj = ProcessList.PREVIOUS_APP_ADJ;
17003                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17004                app.cached = false;
17005                app.adjType = "previous";
17006            }
17007            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17008                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17009            }
17010        }
17011
17012        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17013                + " reason=" + app.adjType);
17014
17015        // By default, we use the computed adjustment.  It may be changed if
17016        // there are applications dependent on our services or providers, but
17017        // this gives us a baseline and makes sure we don't get into an
17018        // infinite recursion.
17019        app.adjSeq = mAdjSeq;
17020        app.curRawAdj = adj;
17021        app.hasStartedServices = false;
17022
17023        if (mBackupTarget != null && app == mBackupTarget.app) {
17024            // If possible we want to avoid killing apps while they're being backed up
17025            if (adj > ProcessList.BACKUP_APP_ADJ) {
17026                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17027                adj = ProcessList.BACKUP_APP_ADJ;
17028                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17029                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17030                }
17031                app.adjType = "backup";
17032                app.cached = false;
17033            }
17034            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17035                procState = ActivityManager.PROCESS_STATE_BACKUP;
17036            }
17037        }
17038
17039        boolean mayBeTop = false;
17040
17041        for (int is = app.services.size()-1;
17042                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17043                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17044                        || procState > ActivityManager.PROCESS_STATE_TOP);
17045                is--) {
17046            ServiceRecord s = app.services.valueAt(is);
17047            if (s.startRequested) {
17048                app.hasStartedServices = true;
17049                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17050                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17051                }
17052                if (app.hasShownUi && app != mHomeProcess) {
17053                    // If this process has shown some UI, let it immediately
17054                    // go to the LRU list because it may be pretty heavy with
17055                    // UI stuff.  We'll tag it with a label just to help
17056                    // debug and understand what is going on.
17057                    if (adj > ProcessList.SERVICE_ADJ) {
17058                        app.adjType = "cch-started-ui-services";
17059                    }
17060                } else {
17061                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17062                        // This service has seen some activity within
17063                        // recent memory, so we will keep its process ahead
17064                        // of the background processes.
17065                        if (adj > ProcessList.SERVICE_ADJ) {
17066                            adj = ProcessList.SERVICE_ADJ;
17067                            app.adjType = "started-services";
17068                            app.cached = false;
17069                        }
17070                    }
17071                    // If we have let the service slide into the background
17072                    // state, still have some text describing what it is doing
17073                    // even though the service no longer has an impact.
17074                    if (adj > ProcessList.SERVICE_ADJ) {
17075                        app.adjType = "cch-started-services";
17076                    }
17077                }
17078            }
17079            for (int conni = s.connections.size()-1;
17080                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17081                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17082                            || procState > ActivityManager.PROCESS_STATE_TOP);
17083                    conni--) {
17084                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17085                for (int i = 0;
17086                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17087                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17088                                || procState > ActivityManager.PROCESS_STATE_TOP);
17089                        i++) {
17090                    // XXX should compute this based on the max of
17091                    // all connected clients.
17092                    ConnectionRecord cr = clist.get(i);
17093                    if (cr.binding.client == app) {
17094                        // Binding to ourself is not interesting.
17095                        continue;
17096                    }
17097                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17098                        ProcessRecord client = cr.binding.client;
17099                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17100                                TOP_APP, doingAll, now);
17101                        int clientProcState = client.curProcState;
17102                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17103                            // If the other app is cached for any reason, for purposes here
17104                            // we are going to consider it empty.  The specific cached state
17105                            // doesn't propagate except under certain conditions.
17106                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17107                        }
17108                        String adjType = null;
17109                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17110                            // Not doing bind OOM management, so treat
17111                            // this guy more like a started service.
17112                            if (app.hasShownUi && app != mHomeProcess) {
17113                                // If this process has shown some UI, let it immediately
17114                                // go to the LRU list because it may be pretty heavy with
17115                                // UI stuff.  We'll tag it with a label just to help
17116                                // debug and understand what is going on.
17117                                if (adj > clientAdj) {
17118                                    adjType = "cch-bound-ui-services";
17119                                }
17120                                app.cached = false;
17121                                clientAdj = adj;
17122                                clientProcState = procState;
17123                            } else {
17124                                if (now >= (s.lastActivity
17125                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17126                                    // This service has not seen activity within
17127                                    // recent memory, so allow it to drop to the
17128                                    // LRU list if there is no other reason to keep
17129                                    // it around.  We'll also tag it with a label just
17130                                    // to help debug and undertand what is going on.
17131                                    if (adj > clientAdj) {
17132                                        adjType = "cch-bound-services";
17133                                    }
17134                                    clientAdj = adj;
17135                                }
17136                            }
17137                        }
17138                        if (adj > clientAdj) {
17139                            // If this process has recently shown UI, and
17140                            // the process that is binding to it is less
17141                            // important than being visible, then we don't
17142                            // care about the binding as much as we care
17143                            // about letting this process get into the LRU
17144                            // list to be killed and restarted if needed for
17145                            // memory.
17146                            if (app.hasShownUi && app != mHomeProcess
17147                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17148                                adjType = "cch-bound-ui-services";
17149                            } else {
17150                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17151                                        |Context.BIND_IMPORTANT)) != 0) {
17152                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17153                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17154                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17155                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17156                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17157                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17158                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17159                                    adj = clientAdj;
17160                                } else {
17161                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17162                                        adj = ProcessList.VISIBLE_APP_ADJ;
17163                                    }
17164                                }
17165                                if (!client.cached) {
17166                                    app.cached = false;
17167                                }
17168                                adjType = "service";
17169                            }
17170                        }
17171                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17172                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17173                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17174                            }
17175                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17176                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17177                                    // Special handling of clients who are in the top state.
17178                                    // We *may* want to consider this process to be in the
17179                                    // top state as well, but only if there is not another
17180                                    // reason for it to be running.  Being on the top is a
17181                                    // special state, meaning you are specifically running
17182                                    // for the current top app.  If the process is already
17183                                    // running in the background for some other reason, it
17184                                    // is more important to continue considering it to be
17185                                    // in the background state.
17186                                    mayBeTop = true;
17187                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17188                                } else {
17189                                    // Special handling for above-top states (persistent
17190                                    // processes).  These should not bring the current process
17191                                    // into the top state, since they are not on top.  Instead
17192                                    // give them the best state after that.
17193                                    clientProcState =
17194                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17195                                }
17196                            }
17197                        } else {
17198                            if (clientProcState <
17199                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17200                                clientProcState =
17201                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17202                            }
17203                        }
17204                        if (procState > clientProcState) {
17205                            procState = clientProcState;
17206                        }
17207                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17208                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17209                            app.pendingUiClean = true;
17210                        }
17211                        if (adjType != null) {
17212                            app.adjType = adjType;
17213                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17214                                    .REASON_SERVICE_IN_USE;
17215                            app.adjSource = cr.binding.client;
17216                            app.adjSourceProcState = clientProcState;
17217                            app.adjTarget = s.name;
17218                        }
17219                    }
17220                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17221                        app.treatLikeActivity = true;
17222                    }
17223                    final ActivityRecord a = cr.activity;
17224                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17225                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17226                                (a.visible || a.state == ActivityState.RESUMED
17227                                 || a.state == ActivityState.PAUSING)) {
17228                            adj = ProcessList.FOREGROUND_APP_ADJ;
17229                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17230                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17231                            }
17232                            app.cached = false;
17233                            app.adjType = "service";
17234                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17235                                    .REASON_SERVICE_IN_USE;
17236                            app.adjSource = a;
17237                            app.adjSourceProcState = procState;
17238                            app.adjTarget = s.name;
17239                        }
17240                    }
17241                }
17242            }
17243        }
17244
17245        for (int provi = app.pubProviders.size()-1;
17246                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17247                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17248                        || procState > ActivityManager.PROCESS_STATE_TOP);
17249                provi--) {
17250            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17251            for (int i = cpr.connections.size()-1;
17252                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17253                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17254                            || procState > ActivityManager.PROCESS_STATE_TOP);
17255                    i--) {
17256                ContentProviderConnection conn = cpr.connections.get(i);
17257                ProcessRecord client = conn.client;
17258                if (client == app) {
17259                    // Being our own client is not interesting.
17260                    continue;
17261                }
17262                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17263                int clientProcState = client.curProcState;
17264                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17265                    // If the other app is cached for any reason, for purposes here
17266                    // we are going to consider it empty.
17267                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17268                }
17269                if (adj > clientAdj) {
17270                    if (app.hasShownUi && app != mHomeProcess
17271                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17272                        app.adjType = "cch-ui-provider";
17273                    } else {
17274                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17275                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17276                        app.adjType = "provider";
17277                    }
17278                    app.cached &= client.cached;
17279                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17280                            .REASON_PROVIDER_IN_USE;
17281                    app.adjSource = client;
17282                    app.adjSourceProcState = clientProcState;
17283                    app.adjTarget = cpr.name;
17284                }
17285                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17286                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17287                        // Special handling of clients who are in the top state.
17288                        // We *may* want to consider this process to be in the
17289                        // top state as well, but only if there is not another
17290                        // reason for it to be running.  Being on the top is a
17291                        // special state, meaning you are specifically running
17292                        // for the current top app.  If the process is already
17293                        // running in the background for some other reason, it
17294                        // is more important to continue considering it to be
17295                        // in the background state.
17296                        mayBeTop = true;
17297                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17298                    } else {
17299                        // Special handling for above-top states (persistent
17300                        // processes).  These should not bring the current process
17301                        // into the top state, since they are not on top.  Instead
17302                        // give them the best state after that.
17303                        clientProcState =
17304                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17305                    }
17306                }
17307                if (procState > clientProcState) {
17308                    procState = clientProcState;
17309                }
17310                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17311                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17312                }
17313            }
17314            // If the provider has external (non-framework) process
17315            // dependencies, ensure that its adjustment is at least
17316            // FOREGROUND_APP_ADJ.
17317            if (cpr.hasExternalProcessHandles()) {
17318                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17319                    adj = ProcessList.FOREGROUND_APP_ADJ;
17320                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17321                    app.cached = false;
17322                    app.adjType = "provider";
17323                    app.adjTarget = cpr.name;
17324                }
17325                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17326                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17327                }
17328            }
17329        }
17330
17331        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17332            // A client of one of our services or providers is in the top state.  We
17333            // *may* want to be in the top state, but not if we are already running in
17334            // the background for some other reason.  For the decision here, we are going
17335            // to pick out a few specific states that we want to remain in when a client
17336            // is top (states that tend to be longer-term) and otherwise allow it to go
17337            // to the top state.
17338            switch (procState) {
17339                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17340                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17341                case ActivityManager.PROCESS_STATE_SERVICE:
17342                    // These all are longer-term states, so pull them up to the top
17343                    // of the background states, but not all the way to the top state.
17344                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17345                    break;
17346                default:
17347                    // Otherwise, top is a better choice, so take it.
17348                    procState = ActivityManager.PROCESS_STATE_TOP;
17349                    break;
17350            }
17351        }
17352
17353        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17354            if (app.hasClientActivities) {
17355                // This is a cached process, but with client activities.  Mark it so.
17356                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17357                app.adjType = "cch-client-act";
17358            } else if (app.treatLikeActivity) {
17359                // This is a cached process, but somebody wants us to treat it like it has
17360                // an activity, okay!
17361                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17362                app.adjType = "cch-as-act";
17363            }
17364        }
17365
17366        if (adj == ProcessList.SERVICE_ADJ) {
17367            if (doingAll) {
17368                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17369                mNewNumServiceProcs++;
17370                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17371                if (!app.serviceb) {
17372                    // This service isn't far enough down on the LRU list to
17373                    // normally be a B service, but if we are low on RAM and it
17374                    // is large we want to force it down since we would prefer to
17375                    // keep launcher over it.
17376                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17377                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17378                        app.serviceHighRam = true;
17379                        app.serviceb = true;
17380                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17381                    } else {
17382                        mNewNumAServiceProcs++;
17383                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17384                    }
17385                } else {
17386                    app.serviceHighRam = false;
17387                }
17388            }
17389            if (app.serviceb) {
17390                adj = ProcessList.SERVICE_B_ADJ;
17391            }
17392        }
17393
17394        app.curRawAdj = adj;
17395
17396        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17397        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17398        if (adj > app.maxAdj) {
17399            adj = app.maxAdj;
17400            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17401                schedGroup = Process.THREAD_GROUP_DEFAULT;
17402            }
17403        }
17404
17405        // Do final modification to adj.  Everything we do between here and applying
17406        // the final setAdj must be done in this function, because we will also use
17407        // it when computing the final cached adj later.  Note that we don't need to
17408        // worry about this for max adj above, since max adj will always be used to
17409        // keep it out of the cached vaues.
17410        app.curAdj = app.modifyRawOomAdj(adj);
17411        app.curSchedGroup = schedGroup;
17412        app.curProcState = procState;
17413        app.foregroundActivities = foregroundActivities;
17414
17415        return app.curRawAdj;
17416    }
17417
17418    /**
17419     * Record new PSS sample for a process.
17420     */
17421    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
17422        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
17423        proc.lastPssTime = now;
17424        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17425        if (DEBUG_PSS) Slog.d(TAG_PSS,
17426                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
17427                + " state=" + ProcessList.makeProcStateString(procState));
17428        if (proc.initialIdlePss == 0) {
17429            proc.initialIdlePss = pss;
17430        }
17431        proc.lastPss = pss;
17432        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17433            proc.lastCachedPss = pss;
17434        }
17435
17436        final SparseArray<Pair<Long, String>> watchUids
17437                = mMemWatchProcesses.getMap().get(proc.processName);
17438        Long check = null;
17439        if (watchUids != null) {
17440            Pair<Long, String> val = watchUids.get(proc.uid);
17441            if (val == null) {
17442                val = watchUids.get(0);
17443            }
17444            if (val != null) {
17445                check = val.first;
17446            }
17447        }
17448        if (check != null) {
17449            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
17450                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17451                if (!isDebuggable) {
17452                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
17453                        isDebuggable = true;
17454                    }
17455                }
17456                if (isDebuggable) {
17457                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
17458                    final ProcessRecord myProc = proc;
17459                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
17460                    mMemWatchDumpProcName = proc.processName;
17461                    mMemWatchDumpFile = heapdumpFile.toString();
17462                    mMemWatchDumpPid = proc.pid;
17463                    mMemWatchDumpUid = proc.uid;
17464                    BackgroundThread.getHandler().post(new Runnable() {
17465                        @Override
17466                        public void run() {
17467                            revokeUriPermission(ActivityThread.currentActivityThread()
17468                                            .getApplicationThread(),
17469                                    DumpHeapActivity.JAVA_URI,
17470                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
17471                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
17472                                    UserHandle.myUserId());
17473                            ParcelFileDescriptor fd = null;
17474                            try {
17475                                heapdumpFile.delete();
17476                                fd = ParcelFileDescriptor.open(heapdumpFile,
17477                                        ParcelFileDescriptor.MODE_CREATE |
17478                                                ParcelFileDescriptor.MODE_TRUNCATE |
17479                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
17480                                                ParcelFileDescriptor.MODE_APPEND);
17481                                IApplicationThread thread = myProc.thread;
17482                                if (thread != null) {
17483                                    try {
17484                                        if (true || DEBUG_PSS) Slog.d(TAG_PSS,
17485                                                "Requesting dump heap from "
17486                                                + myProc + " to " + heapdumpFile);
17487                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
17488                                    } catch (RemoteException e) {
17489                                    }
17490                                }
17491                            } catch (FileNotFoundException e) {
17492                                e.printStackTrace();
17493                            } finally {
17494                                if (fd != null) {
17495                                    try {
17496                                        fd.close();
17497                                    } catch (IOException e) {
17498                                    }
17499                                }
17500                            }
17501                        }
17502                    });
17503                } else {
17504                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
17505                            + ", but debugging not enabled");
17506                }
17507            }
17508        }
17509    }
17510
17511    /**
17512     * Schedule PSS collection of a process.
17513     */
17514    void requestPssLocked(ProcessRecord proc, int procState) {
17515        if (mPendingPssProcesses.contains(proc)) {
17516            return;
17517        }
17518        if (mPendingPssProcesses.size() == 0) {
17519            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17520        }
17521        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
17522        proc.pssProcState = procState;
17523        mPendingPssProcesses.add(proc);
17524    }
17525
17526    /**
17527     * Schedule PSS collection of all processes.
17528     */
17529    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17530        if (!always) {
17531            if (now < (mLastFullPssTime +
17532                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17533                return;
17534            }
17535        }
17536        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
17537        mLastFullPssTime = now;
17538        mFullPssPending = true;
17539        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17540        mPendingPssProcesses.clear();
17541        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17542            ProcessRecord app = mLruProcesses.get(i);
17543            if (app.thread == null
17544                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
17545                continue;
17546            }
17547            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17548                app.pssProcState = app.setProcState;
17549                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17550                        mTestPssMode, isSleeping(), now);
17551                mPendingPssProcesses.add(app);
17552            }
17553        }
17554        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17555    }
17556
17557    public void setTestPssMode(boolean enabled) {
17558        synchronized (this) {
17559            mTestPssMode = enabled;
17560            if (enabled) {
17561                // Whenever we enable the mode, we want to take a snapshot all of current
17562                // process mem use.
17563                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17564            }
17565        }
17566    }
17567
17568    /**
17569     * Ask a given process to GC right now.
17570     */
17571    final void performAppGcLocked(ProcessRecord app) {
17572        try {
17573            app.lastRequestedGc = SystemClock.uptimeMillis();
17574            if (app.thread != null) {
17575                if (app.reportLowMemory) {
17576                    app.reportLowMemory = false;
17577                    app.thread.scheduleLowMemory();
17578                } else {
17579                    app.thread.processInBackground();
17580                }
17581            }
17582        } catch (Exception e) {
17583            // whatever.
17584        }
17585    }
17586
17587    /**
17588     * Returns true if things are idle enough to perform GCs.
17589     */
17590    private final boolean canGcNowLocked() {
17591        boolean processingBroadcasts = false;
17592        for (BroadcastQueue q : mBroadcastQueues) {
17593            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17594                processingBroadcasts = true;
17595            }
17596        }
17597        return !processingBroadcasts
17598                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17599    }
17600
17601    /**
17602     * Perform GCs on all processes that are waiting for it, but only
17603     * if things are idle.
17604     */
17605    final void performAppGcsLocked() {
17606        final int N = mProcessesToGc.size();
17607        if (N <= 0) {
17608            return;
17609        }
17610        if (canGcNowLocked()) {
17611            while (mProcessesToGc.size() > 0) {
17612                ProcessRecord proc = mProcessesToGc.remove(0);
17613                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17614                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17615                            <= SystemClock.uptimeMillis()) {
17616                        // To avoid spamming the system, we will GC processes one
17617                        // at a time, waiting a few seconds between each.
17618                        performAppGcLocked(proc);
17619                        scheduleAppGcsLocked();
17620                        return;
17621                    } else {
17622                        // It hasn't been long enough since we last GCed this
17623                        // process...  put it in the list to wait for its time.
17624                        addProcessToGcListLocked(proc);
17625                        break;
17626                    }
17627                }
17628            }
17629
17630            scheduleAppGcsLocked();
17631        }
17632    }
17633
17634    /**
17635     * If all looks good, perform GCs on all processes waiting for them.
17636     */
17637    final void performAppGcsIfAppropriateLocked() {
17638        if (canGcNowLocked()) {
17639            performAppGcsLocked();
17640            return;
17641        }
17642        // Still not idle, wait some more.
17643        scheduleAppGcsLocked();
17644    }
17645
17646    /**
17647     * Schedule the execution of all pending app GCs.
17648     */
17649    final void scheduleAppGcsLocked() {
17650        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17651
17652        if (mProcessesToGc.size() > 0) {
17653            // Schedule a GC for the time to the next process.
17654            ProcessRecord proc = mProcessesToGc.get(0);
17655            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17656
17657            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17658            long now = SystemClock.uptimeMillis();
17659            if (when < (now+GC_TIMEOUT)) {
17660                when = now + GC_TIMEOUT;
17661            }
17662            mHandler.sendMessageAtTime(msg, when);
17663        }
17664    }
17665
17666    /**
17667     * Add a process to the array of processes waiting to be GCed.  Keeps the
17668     * list in sorted order by the last GC time.  The process can't already be
17669     * on the list.
17670     */
17671    final void addProcessToGcListLocked(ProcessRecord proc) {
17672        boolean added = false;
17673        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17674            if (mProcessesToGc.get(i).lastRequestedGc <
17675                    proc.lastRequestedGc) {
17676                added = true;
17677                mProcessesToGc.add(i+1, proc);
17678                break;
17679            }
17680        }
17681        if (!added) {
17682            mProcessesToGc.add(0, proc);
17683        }
17684    }
17685
17686    /**
17687     * Set up to ask a process to GC itself.  This will either do it
17688     * immediately, or put it on the list of processes to gc the next
17689     * time things are idle.
17690     */
17691    final void scheduleAppGcLocked(ProcessRecord app) {
17692        long now = SystemClock.uptimeMillis();
17693        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17694            return;
17695        }
17696        if (!mProcessesToGc.contains(app)) {
17697            addProcessToGcListLocked(app);
17698            scheduleAppGcsLocked();
17699        }
17700    }
17701
17702    final void checkExcessivePowerUsageLocked(boolean doKills) {
17703        updateCpuStatsNow();
17704
17705        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17706        boolean doWakeKills = doKills;
17707        boolean doCpuKills = doKills;
17708        if (mLastPowerCheckRealtime == 0) {
17709            doWakeKills = false;
17710        }
17711        if (mLastPowerCheckUptime == 0) {
17712            doCpuKills = false;
17713        }
17714        if (stats.isScreenOn()) {
17715            doWakeKills = false;
17716        }
17717        final long curRealtime = SystemClock.elapsedRealtime();
17718        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17719        final long curUptime = SystemClock.uptimeMillis();
17720        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17721        mLastPowerCheckRealtime = curRealtime;
17722        mLastPowerCheckUptime = curUptime;
17723        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17724            doWakeKills = false;
17725        }
17726        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17727            doCpuKills = false;
17728        }
17729        int i = mLruProcesses.size();
17730        while (i > 0) {
17731            i--;
17732            ProcessRecord app = mLruProcesses.get(i);
17733            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17734                long wtime;
17735                synchronized (stats) {
17736                    wtime = stats.getProcessWakeTime(app.info.uid,
17737                            app.pid, curRealtime);
17738                }
17739                long wtimeUsed = wtime - app.lastWakeTime;
17740                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17741                if (DEBUG_POWER) {
17742                    StringBuilder sb = new StringBuilder(128);
17743                    sb.append("Wake for ");
17744                    app.toShortString(sb);
17745                    sb.append(": over ");
17746                    TimeUtils.formatDuration(realtimeSince, sb);
17747                    sb.append(" used ");
17748                    TimeUtils.formatDuration(wtimeUsed, sb);
17749                    sb.append(" (");
17750                    sb.append((wtimeUsed*100)/realtimeSince);
17751                    sb.append("%)");
17752                    Slog.i(TAG_POWER, sb.toString());
17753                    sb.setLength(0);
17754                    sb.append("CPU for ");
17755                    app.toShortString(sb);
17756                    sb.append(": over ");
17757                    TimeUtils.formatDuration(uptimeSince, sb);
17758                    sb.append(" used ");
17759                    TimeUtils.formatDuration(cputimeUsed, sb);
17760                    sb.append(" (");
17761                    sb.append((cputimeUsed*100)/uptimeSince);
17762                    sb.append("%)");
17763                    Slog.i(TAG_POWER, sb.toString());
17764                }
17765                // If a process has held a wake lock for more
17766                // than 50% of the time during this period,
17767                // that sounds bad.  Kill!
17768                if (doWakeKills && realtimeSince > 0
17769                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17770                    synchronized (stats) {
17771                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17772                                realtimeSince, wtimeUsed);
17773                    }
17774                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17775                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17776                } else if (doCpuKills && uptimeSince > 0
17777                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17778                    synchronized (stats) {
17779                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17780                                uptimeSince, cputimeUsed);
17781                    }
17782                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17783                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17784                } else {
17785                    app.lastWakeTime = wtime;
17786                    app.lastCpuTime = app.curCpuTime;
17787                }
17788            }
17789        }
17790    }
17791
17792    private final boolean applyOomAdjLocked(ProcessRecord app,
17793            ProcessRecord TOP_APP, boolean doingAll, long now) {
17794        boolean success = true;
17795
17796        if (app.curRawAdj != app.setRawAdj) {
17797            app.setRawAdj = app.curRawAdj;
17798        }
17799
17800        int changes = 0;
17801
17802        if (app.curAdj != app.setAdj) {
17803            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17804            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
17805                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
17806                    + app.adjType);
17807            app.setAdj = app.curAdj;
17808        }
17809
17810        if (app.setSchedGroup != app.curSchedGroup) {
17811            app.setSchedGroup = app.curSchedGroup;
17812            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
17813                    "Setting process group of " + app.processName
17814                    + " to " + app.curSchedGroup);
17815            if (app.waitingToKill != null &&
17816                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17817                app.kill(app.waitingToKill, true);
17818                success = false;
17819            } else {
17820                if (true) {
17821                    long oldId = Binder.clearCallingIdentity();
17822                    try {
17823                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17824                    } catch (Exception e) {
17825                        Slog.w(TAG, "Failed setting process group of " + app.pid
17826                                + " to " + app.curSchedGroup);
17827                        e.printStackTrace();
17828                    } finally {
17829                        Binder.restoreCallingIdentity(oldId);
17830                    }
17831                } else {
17832                    if (app.thread != null) {
17833                        try {
17834                            app.thread.setSchedulingGroup(app.curSchedGroup);
17835                        } catch (RemoteException e) {
17836                        }
17837                    }
17838                }
17839                Process.setSwappiness(app.pid,
17840                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17841            }
17842        }
17843        if (app.repForegroundActivities != app.foregroundActivities) {
17844            app.repForegroundActivities = app.foregroundActivities;
17845            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17846        }
17847        if (app.repProcState != app.curProcState) {
17848            app.repProcState = app.curProcState;
17849            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17850            if (app.thread != null) {
17851                try {
17852                    if (false) {
17853                        //RuntimeException h = new RuntimeException("here");
17854                        Slog.i(TAG, "Sending new process state " + app.repProcState
17855                                + " to " + app /*, h*/);
17856                    }
17857                    app.thread.setProcessState(app.repProcState);
17858                } catch (RemoteException e) {
17859                }
17860            }
17861        }
17862        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
17863                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
17864            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17865                // Experimental code to more aggressively collect pss while
17866                // running test...  the problem is that this tends to collect
17867                // the data right when a process is transitioning between process
17868                // states, which well tend to give noisy data.
17869                long start = SystemClock.uptimeMillis();
17870                long pss = Debug.getPss(app.pid, mTmpLong, null);
17871                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
17872                mPendingPssProcesses.remove(app);
17873                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17874                        + " to " + app.curProcState + ": "
17875                        + (SystemClock.uptimeMillis()-start) + "ms");
17876            }
17877            app.lastStateTime = now;
17878            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17879                    mTestPssMode, isSleeping(), now);
17880            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
17881                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17882                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17883                    + (app.nextPssTime-now) + ": " + app);
17884        } else {
17885            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17886                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
17887                    mTestPssMode)))) {
17888                requestPssLocked(app, app.setProcState);
17889                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17890                        mTestPssMode, isSleeping(), now);
17891            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
17892                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17893        }
17894        if (app.setProcState != app.curProcState) {
17895            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
17896                    "Proc state change of " + app.processName
17897                    + " to " + app.curProcState);
17898            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17899            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17900            if (setImportant && !curImportant) {
17901                // This app is no longer something we consider important enough to allow to
17902                // use arbitrary amounts of battery power.  Note
17903                // its current wake lock time to later know to kill it if
17904                // it is not behaving well.
17905                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17906                synchronized (stats) {
17907                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17908                            app.pid, SystemClock.elapsedRealtime());
17909                }
17910                app.lastCpuTime = app.curCpuTime;
17911
17912            }
17913            // Inform UsageStats of important process state change
17914            // Must be called before updating setProcState
17915            maybeUpdateUsageStats(app);
17916
17917            app.setProcState = app.curProcState;
17918            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17919                app.notCachedSinceIdle = false;
17920            }
17921            if (!doingAll) {
17922                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17923            } else {
17924                app.procStateChanged = true;
17925            }
17926        }
17927
17928        if (changes != 0) {
17929            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
17930                    "Changes in " + app + ": " + changes);
17931            int i = mPendingProcessChanges.size()-1;
17932            ProcessChangeItem item = null;
17933            while (i >= 0) {
17934                item = mPendingProcessChanges.get(i);
17935                if (item.pid == app.pid) {
17936                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
17937                            "Re-using existing item: " + item);
17938                    break;
17939                }
17940                i--;
17941            }
17942            if (i < 0) {
17943                // No existing item in pending changes; need a new one.
17944                final int NA = mAvailProcessChanges.size();
17945                if (NA > 0) {
17946                    item = mAvailProcessChanges.remove(NA-1);
17947                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
17948                            "Retreiving available item: " + item);
17949                } else {
17950                    item = new ProcessChangeItem();
17951                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
17952                            "Allocating new item: " + item);
17953                }
17954                item.changes = 0;
17955                item.pid = app.pid;
17956                item.uid = app.info.uid;
17957                if (mPendingProcessChanges.size() == 0) {
17958                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
17959                            "*** Enqueueing dispatch processes changed!");
17960                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17961                }
17962                mPendingProcessChanges.add(item);
17963            }
17964            item.changes |= changes;
17965            item.processState = app.repProcState;
17966            item.foregroundActivities = app.repForegroundActivities;
17967            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
17968                    "Item " + Integer.toHexString(System.identityHashCode(item))
17969                    + " " + app.toShortString() + ": changes=" + item.changes
17970                    + " procState=" + item.processState
17971                    + " foreground=" + item.foregroundActivities
17972                    + " type=" + app.adjType + " source=" + app.adjSource
17973                    + " target=" + app.adjTarget);
17974        }
17975
17976        return success;
17977    }
17978
17979    private void maybeUpdateUsageStats(ProcessRecord app) {
17980        if (DEBUG_USAGE_STATS) {
17981            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
17982                    + "] state changes: old = " + app.setProcState + ", new = "
17983                    + app.curProcState);
17984        }
17985        if (mUsageStatsService == null) {
17986            return;
17987        }
17988        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
17989                && (app.setProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
17990                        || app.setProcState < 0)) {
17991            String[] packages = app.getPackageList();
17992            if (packages != null) {
17993                for (int i = 0; i < packages.length; i++) {
17994                    mUsageStatsService.reportEvent(packages[i], app.userId,
17995                            UsageEvents.Event.INTERACTION);
17996                }
17997            }
17998        }
17999    }
18000
18001    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18002        if (proc.thread != null) {
18003            if (proc.baseProcessTracker != null) {
18004                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18005            }
18006            if (proc.repProcState >= 0) {
18007                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18008                        proc.repProcState);
18009            }
18010        }
18011    }
18012
18013    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18014            ProcessRecord TOP_APP, boolean doingAll, long now) {
18015        if (app.thread == null) {
18016            return false;
18017        }
18018
18019        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18020
18021        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
18022    }
18023
18024    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18025            boolean oomAdj) {
18026        if (isForeground != proc.foregroundServices) {
18027            proc.foregroundServices = isForeground;
18028            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18029                    proc.info.uid);
18030            if (isForeground) {
18031                if (curProcs == null) {
18032                    curProcs = new ArrayList<ProcessRecord>();
18033                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18034                }
18035                if (!curProcs.contains(proc)) {
18036                    curProcs.add(proc);
18037                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18038                            proc.info.packageName, proc.info.uid);
18039                }
18040            } else {
18041                if (curProcs != null) {
18042                    if (curProcs.remove(proc)) {
18043                        mBatteryStatsService.noteEvent(
18044                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18045                                proc.info.packageName, proc.info.uid);
18046                        if (curProcs.size() <= 0) {
18047                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18048                        }
18049                    }
18050                }
18051            }
18052            if (oomAdj) {
18053                updateOomAdjLocked();
18054            }
18055        }
18056    }
18057
18058    private final ActivityRecord resumedAppLocked() {
18059        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18060        String pkg;
18061        int uid;
18062        if (act != null) {
18063            pkg = act.packageName;
18064            uid = act.info.applicationInfo.uid;
18065        } else {
18066            pkg = null;
18067            uid = -1;
18068        }
18069        // Has the UID or resumed package name changed?
18070        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18071                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18072            if (mCurResumedPackage != null) {
18073                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18074                        mCurResumedPackage, mCurResumedUid);
18075            }
18076            mCurResumedPackage = pkg;
18077            mCurResumedUid = uid;
18078            if (mCurResumedPackage != null) {
18079                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18080                        mCurResumedPackage, mCurResumedUid);
18081            }
18082        }
18083        return act;
18084    }
18085
18086    final boolean updateOomAdjLocked(ProcessRecord app) {
18087        final ActivityRecord TOP_ACT = resumedAppLocked();
18088        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18089        final boolean wasCached = app.cached;
18090
18091        mAdjSeq++;
18092
18093        // This is the desired cached adjusment we want to tell it to use.
18094        // If our app is currently cached, we know it, and that is it.  Otherwise,
18095        // we don't know it yet, and it needs to now be cached we will then
18096        // need to do a complete oom adj.
18097        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18098                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18099        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18100                SystemClock.uptimeMillis());
18101        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18102            // Changed to/from cached state, so apps after it in the LRU
18103            // list may also be changed.
18104            updateOomAdjLocked();
18105        }
18106        return success;
18107    }
18108
18109    final void updateOomAdjLocked() {
18110        final ActivityRecord TOP_ACT = resumedAppLocked();
18111        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18112        final long now = SystemClock.uptimeMillis();
18113        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18114        final int N = mLruProcesses.size();
18115
18116        if (false) {
18117            RuntimeException e = new RuntimeException();
18118            e.fillInStackTrace();
18119            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18120        }
18121
18122        mAdjSeq++;
18123        mNewNumServiceProcs = 0;
18124        mNewNumAServiceProcs = 0;
18125
18126        final int emptyProcessLimit;
18127        final int cachedProcessLimit;
18128        if (mProcessLimit <= 0) {
18129            emptyProcessLimit = cachedProcessLimit = 0;
18130        } else if (mProcessLimit == 1) {
18131            emptyProcessLimit = 1;
18132            cachedProcessLimit = 0;
18133        } else {
18134            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18135            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18136        }
18137
18138        // Let's determine how many processes we have running vs.
18139        // how many slots we have for background processes; we may want
18140        // to put multiple processes in a slot of there are enough of
18141        // them.
18142        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18143                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18144        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18145        if (numEmptyProcs > cachedProcessLimit) {
18146            // If there are more empty processes than our limit on cached
18147            // processes, then use the cached process limit for the factor.
18148            // This ensures that the really old empty processes get pushed
18149            // down to the bottom, so if we are running low on memory we will
18150            // have a better chance at keeping around more cached processes
18151            // instead of a gazillion empty processes.
18152            numEmptyProcs = cachedProcessLimit;
18153        }
18154        int emptyFactor = numEmptyProcs/numSlots;
18155        if (emptyFactor < 1) emptyFactor = 1;
18156        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18157        if (cachedFactor < 1) cachedFactor = 1;
18158        int stepCached = 0;
18159        int stepEmpty = 0;
18160        int numCached = 0;
18161        int numEmpty = 0;
18162        int numTrimming = 0;
18163
18164        mNumNonCachedProcs = 0;
18165        mNumCachedHiddenProcs = 0;
18166
18167        // First update the OOM adjustment for each of the
18168        // application processes based on their current state.
18169        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18170        int nextCachedAdj = curCachedAdj+1;
18171        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18172        int nextEmptyAdj = curEmptyAdj+2;
18173        for (int i=N-1; i>=0; i--) {
18174            ProcessRecord app = mLruProcesses.get(i);
18175            if (!app.killedByAm && app.thread != null) {
18176                app.procStateChanged = false;
18177                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18178
18179                // If we haven't yet assigned the final cached adj
18180                // to the process, do that now.
18181                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18182                    switch (app.curProcState) {
18183                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18184                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18185                            // This process is a cached process holding activities...
18186                            // assign it the next cached value for that type, and then
18187                            // step that cached level.
18188                            app.curRawAdj = curCachedAdj;
18189                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18190                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
18191                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18192                                    + ")");
18193                            if (curCachedAdj != nextCachedAdj) {
18194                                stepCached++;
18195                                if (stepCached >= cachedFactor) {
18196                                    stepCached = 0;
18197                                    curCachedAdj = nextCachedAdj;
18198                                    nextCachedAdj += 2;
18199                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18200                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18201                                    }
18202                                }
18203                            }
18204                            break;
18205                        default:
18206                            // For everything else, assign next empty cached process
18207                            // level and bump that up.  Note that this means that
18208                            // long-running services that have dropped down to the
18209                            // cached level will be treated as empty (since their process
18210                            // state is still as a service), which is what we want.
18211                            app.curRawAdj = curEmptyAdj;
18212                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18213                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
18214                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18215                                    + ")");
18216                            if (curEmptyAdj != nextEmptyAdj) {
18217                                stepEmpty++;
18218                                if (stepEmpty >= emptyFactor) {
18219                                    stepEmpty = 0;
18220                                    curEmptyAdj = nextEmptyAdj;
18221                                    nextEmptyAdj += 2;
18222                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18223                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18224                                    }
18225                                }
18226                            }
18227                            break;
18228                    }
18229                }
18230
18231                applyOomAdjLocked(app, TOP_APP, true, now);
18232
18233                // Count the number of process types.
18234                switch (app.curProcState) {
18235                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18236                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18237                        mNumCachedHiddenProcs++;
18238                        numCached++;
18239                        if (numCached > cachedProcessLimit) {
18240                            app.kill("cached #" + numCached, true);
18241                        }
18242                        break;
18243                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18244                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18245                                && app.lastActivityTime < oldTime) {
18246                            app.kill("empty for "
18247                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18248                                    / 1000) + "s", true);
18249                        } else {
18250                            numEmpty++;
18251                            if (numEmpty > emptyProcessLimit) {
18252                                app.kill("empty #" + numEmpty, true);
18253                            }
18254                        }
18255                        break;
18256                    default:
18257                        mNumNonCachedProcs++;
18258                        break;
18259                }
18260
18261                if (app.isolated && app.services.size() <= 0) {
18262                    // If this is an isolated process, and there are no
18263                    // services running in it, then the process is no longer
18264                    // needed.  We agressively kill these because we can by
18265                    // definition not re-use the same process again, and it is
18266                    // good to avoid having whatever code was running in them
18267                    // left sitting around after no longer needed.
18268                    app.kill("isolated not needed", true);
18269                }
18270
18271                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18272                        && !app.killedByAm) {
18273                    numTrimming++;
18274                }
18275            }
18276        }
18277
18278        mNumServiceProcs = mNewNumServiceProcs;
18279
18280        // Now determine the memory trimming level of background processes.
18281        // Unfortunately we need to start at the back of the list to do this
18282        // properly.  We only do this if the number of background apps we
18283        // are managing to keep around is less than half the maximum we desire;
18284        // if we are keeping a good number around, we'll let them use whatever
18285        // memory they want.
18286        final int numCachedAndEmpty = numCached + numEmpty;
18287        int memFactor;
18288        if (numCached <= ProcessList.TRIM_CACHED_APPS
18289                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18290            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18291                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18292            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18293                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18294            } else {
18295                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18296            }
18297        } else {
18298            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18299        }
18300        // We always allow the memory level to go up (better).  We only allow it to go
18301        // down if we are in a state where that is allowed, *and* the total number of processes
18302        // has gone down since last time.
18303        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
18304                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
18305                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
18306        if (memFactor > mLastMemoryLevel) {
18307            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18308                memFactor = mLastMemoryLevel;
18309                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
18310            }
18311        }
18312        mLastMemoryLevel = memFactor;
18313        mLastNumProcesses = mLruProcesses.size();
18314        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18315        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18316        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18317            if (mLowRamStartTime == 0) {
18318                mLowRamStartTime = now;
18319            }
18320            int step = 0;
18321            int fgTrimLevel;
18322            switch (memFactor) {
18323                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18324                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18325                    break;
18326                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18327                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18328                    break;
18329                default:
18330                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18331                    break;
18332            }
18333            int factor = numTrimming/3;
18334            int minFactor = 2;
18335            if (mHomeProcess != null) minFactor++;
18336            if (mPreviousProcess != null) minFactor++;
18337            if (factor < minFactor) factor = minFactor;
18338            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18339            for (int i=N-1; i>=0; i--) {
18340                ProcessRecord app = mLruProcesses.get(i);
18341                if (allChanged || app.procStateChanged) {
18342                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18343                    app.procStateChanged = false;
18344                }
18345                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18346                        && !app.killedByAm) {
18347                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18348                        try {
18349                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18350                                    "Trimming memory of " + app.processName + " to " + curLevel);
18351                            app.thread.scheduleTrimMemory(curLevel);
18352                        } catch (RemoteException e) {
18353                        }
18354                        if (false) {
18355                            // For now we won't do this; our memory trimming seems
18356                            // to be good enough at this point that destroying
18357                            // activities causes more harm than good.
18358                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18359                                    && app != mHomeProcess && app != mPreviousProcess) {
18360                                // Need to do this on its own message because the stack may not
18361                                // be in a consistent state at this point.
18362                                // For these apps we will also finish their activities
18363                                // to help them free memory.
18364                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18365                            }
18366                        }
18367                    }
18368                    app.trimMemoryLevel = curLevel;
18369                    step++;
18370                    if (step >= factor) {
18371                        step = 0;
18372                        switch (curLevel) {
18373                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18374                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18375                                break;
18376                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18377                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18378                                break;
18379                        }
18380                    }
18381                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18382                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18383                            && app.thread != null) {
18384                        try {
18385                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18386                                    "Trimming memory of heavy-weight " + app.processName
18387                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18388                            app.thread.scheduleTrimMemory(
18389                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18390                        } catch (RemoteException e) {
18391                        }
18392                    }
18393                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18394                } else {
18395                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18396                            || app.systemNoUi) && app.pendingUiClean) {
18397                        // If this application is now in the background and it
18398                        // had done UI, then give it the special trim level to
18399                        // have it free UI resources.
18400                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18401                        if (app.trimMemoryLevel < level && app.thread != null) {
18402                            try {
18403                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18404                                        "Trimming memory of bg-ui " + app.processName
18405                                        + " to " + level);
18406                                app.thread.scheduleTrimMemory(level);
18407                            } catch (RemoteException e) {
18408                            }
18409                        }
18410                        app.pendingUiClean = false;
18411                    }
18412                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18413                        try {
18414                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18415                                    "Trimming memory of fg " + app.processName
18416                                    + " to " + fgTrimLevel);
18417                            app.thread.scheduleTrimMemory(fgTrimLevel);
18418                        } catch (RemoteException e) {
18419                        }
18420                    }
18421                    app.trimMemoryLevel = fgTrimLevel;
18422                }
18423            }
18424        } else {
18425            if (mLowRamStartTime != 0) {
18426                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18427                mLowRamStartTime = 0;
18428            }
18429            for (int i=N-1; i>=0; i--) {
18430                ProcessRecord app = mLruProcesses.get(i);
18431                if (allChanged || app.procStateChanged) {
18432                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18433                    app.procStateChanged = false;
18434                }
18435                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18436                        || app.systemNoUi) && app.pendingUiClean) {
18437                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18438                            && app.thread != null) {
18439                        try {
18440                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18441                                    "Trimming memory of ui hidden " + app.processName
18442                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18443                            app.thread.scheduleTrimMemory(
18444                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18445                        } catch (RemoteException e) {
18446                        }
18447                    }
18448                    app.pendingUiClean = false;
18449                }
18450                app.trimMemoryLevel = 0;
18451            }
18452        }
18453
18454        if (mAlwaysFinishActivities) {
18455            // Need to do this on its own message because the stack may not
18456            // be in a consistent state at this point.
18457            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18458        }
18459
18460        if (allChanged) {
18461            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18462        }
18463
18464        if (mProcessStats.shouldWriteNowLocked(now)) {
18465            mHandler.post(new Runnable() {
18466                @Override public void run() {
18467                    synchronized (ActivityManagerService.this) {
18468                        mProcessStats.writeStateAsyncLocked();
18469                    }
18470                }
18471            });
18472        }
18473
18474        if (DEBUG_OOM_ADJ) {
18475            final long duration = SystemClock.uptimeMillis() - now;
18476            if (false) {
18477                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
18478                        new RuntimeException("here").fillInStackTrace());
18479            } else {
18480                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
18481            }
18482        }
18483    }
18484
18485    final void trimApplications() {
18486        synchronized (this) {
18487            int i;
18488
18489            // First remove any unused application processes whose package
18490            // has been removed.
18491            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18492                final ProcessRecord app = mRemovedProcesses.get(i);
18493                if (app.activities.size() == 0
18494                        && app.curReceiver == null && app.services.size() == 0) {
18495                    Slog.i(
18496                        TAG, "Exiting empty application process "
18497                        + app.processName + " ("
18498                        + (app.thread != null ? app.thread.asBinder() : null)
18499                        + ")\n");
18500                    if (app.pid > 0 && app.pid != MY_PID) {
18501                        app.kill("empty", false);
18502                    } else {
18503                        try {
18504                            app.thread.scheduleExit();
18505                        } catch (Exception e) {
18506                            // Ignore exceptions.
18507                        }
18508                    }
18509                    cleanUpApplicationRecordLocked(app, false, true, -1);
18510                    mRemovedProcesses.remove(i);
18511
18512                    if (app.persistent) {
18513                        addAppLocked(app.info, false, null /* ABI override */);
18514                    }
18515                }
18516            }
18517
18518            // Now update the oom adj for all processes.
18519            updateOomAdjLocked();
18520        }
18521    }
18522
18523    /** This method sends the specified signal to each of the persistent apps */
18524    public void signalPersistentProcesses(int sig) throws RemoteException {
18525        if (sig != Process.SIGNAL_USR1) {
18526            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18527        }
18528
18529        synchronized (this) {
18530            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18531                    != PackageManager.PERMISSION_GRANTED) {
18532                throw new SecurityException("Requires permission "
18533                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18534            }
18535
18536            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18537                ProcessRecord r = mLruProcesses.get(i);
18538                if (r.thread != null && r.persistent) {
18539                    Process.sendSignal(r.pid, sig);
18540                }
18541            }
18542        }
18543    }
18544
18545    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18546        if (proc == null || proc == mProfileProc) {
18547            proc = mProfileProc;
18548            profileType = mProfileType;
18549            clearProfilerLocked();
18550        }
18551        if (proc == null) {
18552            return;
18553        }
18554        try {
18555            proc.thread.profilerControl(false, null, profileType);
18556        } catch (RemoteException e) {
18557            throw new IllegalStateException("Process disappeared");
18558        }
18559    }
18560
18561    private void clearProfilerLocked() {
18562        if (mProfileFd != null) {
18563            try {
18564                mProfileFd.close();
18565            } catch (IOException e) {
18566            }
18567        }
18568        mProfileApp = null;
18569        mProfileProc = null;
18570        mProfileFile = null;
18571        mProfileType = 0;
18572        mAutoStopProfiler = false;
18573        mSamplingInterval = 0;
18574    }
18575
18576    public boolean profileControl(String process, int userId, boolean start,
18577            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18578
18579        try {
18580            synchronized (this) {
18581                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18582                // its own permission.
18583                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18584                        != PackageManager.PERMISSION_GRANTED) {
18585                    throw new SecurityException("Requires permission "
18586                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18587                }
18588
18589                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18590                    throw new IllegalArgumentException("null profile info or fd");
18591                }
18592
18593                ProcessRecord proc = null;
18594                if (process != null) {
18595                    proc = findProcessLocked(process, userId, "profileControl");
18596                }
18597
18598                if (start && (proc == null || proc.thread == null)) {
18599                    throw new IllegalArgumentException("Unknown process: " + process);
18600                }
18601
18602                if (start) {
18603                    stopProfilerLocked(null, 0);
18604                    setProfileApp(proc.info, proc.processName, profilerInfo);
18605                    mProfileProc = proc;
18606                    mProfileType = profileType;
18607                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18608                    try {
18609                        fd = fd.dup();
18610                    } catch (IOException e) {
18611                        fd = null;
18612                    }
18613                    profilerInfo.profileFd = fd;
18614                    proc.thread.profilerControl(start, profilerInfo, profileType);
18615                    fd = null;
18616                    mProfileFd = null;
18617                } else {
18618                    stopProfilerLocked(proc, profileType);
18619                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18620                        try {
18621                            profilerInfo.profileFd.close();
18622                        } catch (IOException e) {
18623                        }
18624                    }
18625                }
18626
18627                return true;
18628            }
18629        } catch (RemoteException e) {
18630            throw new IllegalStateException("Process disappeared");
18631        } finally {
18632            if (profilerInfo != null && profilerInfo.profileFd != null) {
18633                try {
18634                    profilerInfo.profileFd.close();
18635                } catch (IOException e) {
18636                }
18637            }
18638        }
18639    }
18640
18641    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18642        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18643                userId, true, ALLOW_FULL_ONLY, callName, null);
18644        ProcessRecord proc = null;
18645        try {
18646            int pid = Integer.parseInt(process);
18647            synchronized (mPidsSelfLocked) {
18648                proc = mPidsSelfLocked.get(pid);
18649            }
18650        } catch (NumberFormatException e) {
18651        }
18652
18653        if (proc == null) {
18654            ArrayMap<String, SparseArray<ProcessRecord>> all
18655                    = mProcessNames.getMap();
18656            SparseArray<ProcessRecord> procs = all.get(process);
18657            if (procs != null && procs.size() > 0) {
18658                proc = procs.valueAt(0);
18659                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18660                    for (int i=1; i<procs.size(); i++) {
18661                        ProcessRecord thisProc = procs.valueAt(i);
18662                        if (thisProc.userId == userId) {
18663                            proc = thisProc;
18664                            break;
18665                        }
18666                    }
18667                }
18668            }
18669        }
18670
18671        return proc;
18672    }
18673
18674    public boolean dumpHeap(String process, int userId, boolean managed,
18675            String path, ParcelFileDescriptor fd) throws RemoteException {
18676
18677        try {
18678            synchronized (this) {
18679                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18680                // its own permission (same as profileControl).
18681                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18682                        != PackageManager.PERMISSION_GRANTED) {
18683                    throw new SecurityException("Requires permission "
18684                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18685                }
18686
18687                if (fd == null) {
18688                    throw new IllegalArgumentException("null fd");
18689                }
18690
18691                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18692                if (proc == null || proc.thread == null) {
18693                    throw new IllegalArgumentException("Unknown process: " + process);
18694                }
18695
18696                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18697                if (!isDebuggable) {
18698                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18699                        throw new SecurityException("Process not debuggable: " + proc);
18700                    }
18701                }
18702
18703                proc.thread.dumpHeap(managed, path, fd);
18704                fd = null;
18705                return true;
18706            }
18707        } catch (RemoteException e) {
18708            throw new IllegalStateException("Process disappeared");
18709        } finally {
18710            if (fd != null) {
18711                try {
18712                    fd.close();
18713                } catch (IOException e) {
18714                }
18715            }
18716        }
18717    }
18718
18719    @Override
18720    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
18721            String reportPackage) {
18722        if (processName != null) {
18723            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
18724                    "setDumpHeapDebugLimit()");
18725        } else {
18726            if (!Build.IS_DEBUGGABLE) {
18727                throw new SecurityException("Not running a debuggable build");
18728            }
18729            synchronized (mPidsSelfLocked) {
18730                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
18731                if (proc == null) {
18732                    throw new SecurityException("No process found for calling pid "
18733                            + Binder.getCallingPid());
18734                }
18735                processName = proc.processName;
18736                uid = proc.uid;
18737                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
18738                    throw new SecurityException("Package " + reportPackage + " is not running in "
18739                            + proc);
18740                }
18741            }
18742        }
18743        synchronized (this) {
18744            if (maxMemSize > 0) {
18745                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
18746            } else {
18747                if (uid != 0) {
18748                    mMemWatchProcesses.remove(processName, uid);
18749                } else {
18750                    mMemWatchProcesses.getMap().remove(processName);
18751                }
18752            }
18753        }
18754    }
18755
18756    @Override
18757    public void dumpHeapFinished(String path) {
18758        synchronized (this) {
18759            if (Binder.getCallingPid() != mMemWatchDumpPid) {
18760                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
18761                        + " does not match last pid " + mMemWatchDumpPid);
18762                return;
18763            }
18764            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
18765                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
18766                        + " does not match last path " + mMemWatchDumpFile);
18767                return;
18768            }
18769            if (true || DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
18770            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
18771        }
18772    }
18773
18774    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18775    public void monitor() {
18776        synchronized (this) { }
18777    }
18778
18779    void onCoreSettingsChange(Bundle settings) {
18780        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18781            ProcessRecord processRecord = mLruProcesses.get(i);
18782            try {
18783                if (processRecord.thread != null) {
18784                    processRecord.thread.setCoreSettings(settings);
18785                }
18786            } catch (RemoteException re) {
18787                /* ignore */
18788            }
18789        }
18790    }
18791
18792    // Multi-user methods
18793
18794    /**
18795     * Start user, if its not already running, but don't bring it to foreground.
18796     */
18797    @Override
18798    public boolean startUserInBackground(final int userId) {
18799        return startUser(userId, /* foreground */ false);
18800    }
18801
18802    /**
18803     * Start user, if its not already running, and bring it to foreground.
18804     */
18805    boolean startUserInForeground(final int userId, Dialog dlg) {
18806        boolean result = startUser(userId, /* foreground */ true);
18807        dlg.dismiss();
18808        return result;
18809    }
18810
18811    /**
18812     * Refreshes the list of users related to the current user when either a
18813     * user switch happens or when a new related user is started in the
18814     * background.
18815     */
18816    private void updateCurrentProfileIdsLocked() {
18817        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18818                mCurrentUserId, false /* enabledOnly */);
18819        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18820        for (int i = 0; i < currentProfileIds.length; i++) {
18821            currentProfileIds[i] = profiles.get(i).id;
18822        }
18823        mCurrentProfileIds = currentProfileIds;
18824
18825        synchronized (mUserProfileGroupIdsSelfLocked) {
18826            mUserProfileGroupIdsSelfLocked.clear();
18827            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18828            for (int i = 0; i < users.size(); i++) {
18829                UserInfo user = users.get(i);
18830                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18831                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18832                }
18833            }
18834        }
18835    }
18836
18837    private Set<Integer> getProfileIdsLocked(int userId) {
18838        Set<Integer> userIds = new HashSet<Integer>();
18839        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18840                userId, false /* enabledOnly */);
18841        for (UserInfo user : profiles) {
18842            userIds.add(Integer.valueOf(user.id));
18843        }
18844        return userIds;
18845    }
18846
18847    @Override
18848    public boolean switchUser(final int userId) {
18849        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18850        String userName;
18851        synchronized (this) {
18852            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18853            if (userInfo == null) {
18854                Slog.w(TAG, "No user info for user #" + userId);
18855                return false;
18856            }
18857            if (userInfo.isManagedProfile()) {
18858                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18859                return false;
18860            }
18861            userName = userInfo.name;
18862            mTargetUserId = userId;
18863        }
18864        mHandler.removeMessages(START_USER_SWITCH_MSG);
18865        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18866        return true;
18867    }
18868
18869    private void showUserSwitchDialog(int userId, String userName) {
18870        // The dialog will show and then initiate the user switch by calling startUserInForeground
18871        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18872                true /* above system */);
18873        d.show();
18874    }
18875
18876    private boolean startUser(final int userId, final boolean foreground) {
18877        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18878                != PackageManager.PERMISSION_GRANTED) {
18879            String msg = "Permission Denial: switchUser() from pid="
18880                    + Binder.getCallingPid()
18881                    + ", uid=" + Binder.getCallingUid()
18882                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18883            Slog.w(TAG, msg);
18884            throw new SecurityException(msg);
18885        }
18886
18887        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18888
18889        final long ident = Binder.clearCallingIdentity();
18890        try {
18891            synchronized (this) {
18892                final int oldUserId = mCurrentUserId;
18893                if (oldUserId == userId) {
18894                    return true;
18895                }
18896
18897                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
18898                        "startUser");
18899
18900                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18901                if (userInfo == null) {
18902                    Slog.w(TAG, "No user info for user #" + userId);
18903                    return false;
18904                }
18905                if (foreground && userInfo.isManagedProfile()) {
18906                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18907                    return false;
18908                }
18909
18910                if (foreground) {
18911                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18912                            R.anim.screen_user_enter);
18913                }
18914
18915                boolean needStart = false;
18916
18917                // If the user we are switching to is not currently started, then
18918                // we need to start it now.
18919                if (mStartedUsers.get(userId) == null) {
18920                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18921                    updateStartedUserArrayLocked();
18922                    needStart = true;
18923                }
18924
18925                final Integer userIdInt = Integer.valueOf(userId);
18926                mUserLru.remove(userIdInt);
18927                mUserLru.add(userIdInt);
18928
18929                if (foreground) {
18930                    mCurrentUserId = userId;
18931                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18932                    updateCurrentProfileIdsLocked();
18933                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18934                    // Once the internal notion of the active user has switched, we lock the device
18935                    // with the option to show the user switcher on the keyguard.
18936                    mWindowManager.lockNow(null);
18937                } else {
18938                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18939                    updateCurrentProfileIdsLocked();
18940                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18941                    mUserLru.remove(currentUserIdInt);
18942                    mUserLru.add(currentUserIdInt);
18943                }
18944
18945                final UserStartedState uss = mStartedUsers.get(userId);
18946
18947                // Make sure user is in the started state.  If it is currently
18948                // stopping, we need to knock that off.
18949                if (uss.mState == UserStartedState.STATE_STOPPING) {
18950                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18951                    // so we can just fairly silently bring the user back from
18952                    // the almost-dead.
18953                    uss.mState = UserStartedState.STATE_RUNNING;
18954                    updateStartedUserArrayLocked();
18955                    needStart = true;
18956                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18957                    // This means ACTION_SHUTDOWN has been sent, so we will
18958                    // need to treat this as a new boot of the user.
18959                    uss.mState = UserStartedState.STATE_BOOTING;
18960                    updateStartedUserArrayLocked();
18961                    needStart = true;
18962                }
18963
18964                if (uss.mState == UserStartedState.STATE_BOOTING) {
18965                    // Booting up a new user, need to tell system services about it.
18966                    // Note that this is on the same handler as scheduling of broadcasts,
18967                    // which is important because it needs to go first.
18968                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18969                }
18970
18971                if (foreground) {
18972                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18973                            oldUserId));
18974                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18975                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18976                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18977                            oldUserId, userId, uss));
18978                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18979                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18980                }
18981
18982                if (needStart) {
18983                    // Send USER_STARTED broadcast
18984                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18985                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18986                            | Intent.FLAG_RECEIVER_FOREGROUND);
18987                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18988                    broadcastIntentLocked(null, null, intent,
18989                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18990                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18991                }
18992
18993                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18994                    if (userId != UserHandle.USER_OWNER) {
18995                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18996                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18997                        broadcastIntentLocked(null, null, intent, null,
18998                                new IIntentReceiver.Stub() {
18999                                    public void performReceive(Intent intent, int resultCode,
19000                                            String data, Bundle extras, boolean ordered,
19001                                            boolean sticky, int sendingUser) {
19002                                        onUserInitialized(uss, foreground, oldUserId, userId);
19003                                    }
19004                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19005                                true, false, MY_PID, Process.SYSTEM_UID,
19006                                userId);
19007                        uss.initializing = true;
19008                    } else {
19009                        getUserManagerLocked().makeInitialized(userInfo.id);
19010                    }
19011                }
19012
19013                if (foreground) {
19014                    if (!uss.initializing) {
19015                        moveUserToForeground(uss, oldUserId, userId);
19016                    }
19017                } else {
19018                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19019                }
19020
19021                if (needStart) {
19022                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19023                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19024                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19025                    broadcastIntentLocked(null, null, intent,
19026                            null, new IIntentReceiver.Stub() {
19027                                @Override
19028                                public void performReceive(Intent intent, int resultCode, String data,
19029                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
19030                                        throws RemoteException {
19031                                }
19032                            }, 0, null, null,
19033                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19034                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19035                }
19036            }
19037        } finally {
19038            Binder.restoreCallingIdentity(ident);
19039        }
19040
19041        return true;
19042    }
19043
19044    void dispatchForegroundProfileChanged(int userId) {
19045        final int N = mUserSwitchObservers.beginBroadcast();
19046        for (int i = 0; i < N; i++) {
19047            try {
19048                mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19049            } catch (RemoteException e) {
19050                // Ignore
19051            }
19052        }
19053        mUserSwitchObservers.finishBroadcast();
19054    }
19055
19056    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19057        long ident = Binder.clearCallingIdentity();
19058        try {
19059            Intent intent;
19060            if (oldUserId >= 0) {
19061                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19062                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19063                int count = profiles.size();
19064                for (int i = 0; i < count; i++) {
19065                    int profileUserId = profiles.get(i).id;
19066                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19067                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19068                            | Intent.FLAG_RECEIVER_FOREGROUND);
19069                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19070                    broadcastIntentLocked(null, null, intent,
19071                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19072                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19073                }
19074            }
19075            if (newUserId >= 0) {
19076                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19077                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19078                int count = profiles.size();
19079                for (int i = 0; i < count; i++) {
19080                    int profileUserId = profiles.get(i).id;
19081                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19082                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19083                            | Intent.FLAG_RECEIVER_FOREGROUND);
19084                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19085                    broadcastIntentLocked(null, null, intent,
19086                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19087                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19088                }
19089                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19090                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19091                        | Intent.FLAG_RECEIVER_FOREGROUND);
19092                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19093                broadcastIntentLocked(null, null, intent,
19094                        null, null, 0, null, null,
19095                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19096                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19097            }
19098        } finally {
19099            Binder.restoreCallingIdentity(ident);
19100        }
19101    }
19102
19103    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
19104            final int newUserId) {
19105        final int N = mUserSwitchObservers.beginBroadcast();
19106        if (N > 0) {
19107            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19108                int mCount = 0;
19109                @Override
19110                public void sendResult(Bundle data) throws RemoteException {
19111                    synchronized (ActivityManagerService.this) {
19112                        if (mCurUserSwitchCallback == this) {
19113                            mCount++;
19114                            if (mCount == N) {
19115                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19116                            }
19117                        }
19118                    }
19119                }
19120            };
19121            synchronized (this) {
19122                uss.switching = true;
19123                mCurUserSwitchCallback = callback;
19124            }
19125            for (int i=0; i<N; i++) {
19126                try {
19127                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19128                            newUserId, callback);
19129                } catch (RemoteException e) {
19130                }
19131            }
19132        } else {
19133            synchronized (this) {
19134                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19135            }
19136        }
19137        mUserSwitchObservers.finishBroadcast();
19138    }
19139
19140    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19141        synchronized (this) {
19142            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19143            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19144        }
19145    }
19146
19147    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
19148        mCurUserSwitchCallback = null;
19149        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19150        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19151                oldUserId, newUserId, uss));
19152    }
19153
19154    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
19155        synchronized (this) {
19156            if (foreground) {
19157                moveUserToForeground(uss, oldUserId, newUserId);
19158            }
19159        }
19160
19161        completeSwitchAndInitalize(uss, newUserId, true, false);
19162    }
19163
19164    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19165        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19166        if (homeInFront) {
19167            startHomeActivityLocked(newUserId, "moveUserToFroreground");
19168        } else {
19169            mStackSupervisor.resumeTopActivitiesLocked();
19170        }
19171        EventLogTags.writeAmSwitchUser(newUserId);
19172        getUserManagerLocked().userForeground(newUserId);
19173        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19174    }
19175
19176    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19177        completeSwitchAndInitalize(uss, newUserId, false, true);
19178    }
19179
19180    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19181            boolean clearInitializing, boolean clearSwitching) {
19182        boolean unfrozen = false;
19183        synchronized (this) {
19184            if (clearInitializing) {
19185                uss.initializing = false;
19186                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19187            }
19188            if (clearSwitching) {
19189                uss.switching = false;
19190            }
19191            if (!uss.switching && !uss.initializing) {
19192                mWindowManager.stopFreezingScreen();
19193                unfrozen = true;
19194            }
19195        }
19196        if (unfrozen) {
19197            final int N = mUserSwitchObservers.beginBroadcast();
19198            for (int i=0; i<N; i++) {
19199                try {
19200                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19201                } catch (RemoteException e) {
19202                }
19203            }
19204            mUserSwitchObservers.finishBroadcast();
19205        }
19206        stopGuestUserIfBackground();
19207    }
19208
19209    /**
19210     * Stops the guest user if it has gone to the background.
19211     */
19212    private void stopGuestUserIfBackground() {
19213        synchronized (this) {
19214            final int num = mUserLru.size();
19215            for (int i = 0; i < num; i++) {
19216                Integer oldUserId = mUserLru.get(i);
19217                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19218                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19219                        || oldUss.mState == UserStartedState.STATE_STOPPING
19220                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19221                    continue;
19222                }
19223                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19224                if (userInfo.isGuest()) {
19225                    // This is a user to be stopped.
19226                    stopUserLocked(oldUserId, null);
19227                    break;
19228                }
19229            }
19230        }
19231    }
19232
19233    void scheduleStartProfilesLocked() {
19234        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19235            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19236                    DateUtils.SECOND_IN_MILLIS);
19237        }
19238    }
19239
19240    void startProfilesLocked() {
19241        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19242        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19243                mCurrentUserId, false /* enabledOnly */);
19244        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19245        for (UserInfo user : profiles) {
19246            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19247                    && user.id != mCurrentUserId) {
19248                toStart.add(user);
19249            }
19250        }
19251        final int n = toStart.size();
19252        int i = 0;
19253        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19254            startUserInBackground(toStart.get(i).id);
19255        }
19256        if (i < n) {
19257            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19258        }
19259    }
19260
19261    void finishUserBoot(UserStartedState uss) {
19262        synchronized (this) {
19263            if (uss.mState == UserStartedState.STATE_BOOTING
19264                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19265                uss.mState = UserStartedState.STATE_RUNNING;
19266                final int userId = uss.mHandle.getIdentifier();
19267                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19268                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19269                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19270                broadcastIntentLocked(null, null, intent,
19271                        null, null, 0, null, null,
19272                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19273                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19274            }
19275        }
19276    }
19277
19278    void finishUserSwitch(UserStartedState uss) {
19279        synchronized (this) {
19280            finishUserBoot(uss);
19281
19282            startProfilesLocked();
19283
19284            int num = mUserLru.size();
19285            int i = 0;
19286            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19287                Integer oldUserId = mUserLru.get(i);
19288                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19289                if (oldUss == null) {
19290                    // Shouldn't happen, but be sane if it does.
19291                    mUserLru.remove(i);
19292                    num--;
19293                    continue;
19294                }
19295                if (oldUss.mState == UserStartedState.STATE_STOPPING
19296                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19297                    // This user is already stopping, doesn't count.
19298                    num--;
19299                    i++;
19300                    continue;
19301                }
19302                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19303                    // Owner and current can't be stopped, but count as running.
19304                    i++;
19305                    continue;
19306                }
19307                // This is a user to be stopped.
19308                stopUserLocked(oldUserId, null);
19309                num--;
19310                i++;
19311            }
19312        }
19313    }
19314
19315    @Override
19316    public int stopUser(final int userId, final IStopUserCallback callback) {
19317        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19318                != PackageManager.PERMISSION_GRANTED) {
19319            String msg = "Permission Denial: switchUser() from pid="
19320                    + Binder.getCallingPid()
19321                    + ", uid=" + Binder.getCallingUid()
19322                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19323            Slog.w(TAG, msg);
19324            throw new SecurityException(msg);
19325        }
19326        if (userId < 0 || userId == UserHandle.USER_OWNER) {
19327            throw new IllegalArgumentException("Can't stop primary user " + userId);
19328        }
19329        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19330        synchronized (this) {
19331            return stopUserLocked(userId, callback);
19332        }
19333    }
19334
19335    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19336        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19337        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19338            return ActivityManager.USER_OP_IS_CURRENT;
19339        }
19340
19341        final UserStartedState uss = mStartedUsers.get(userId);
19342        if (uss == null) {
19343            // User is not started, nothing to do...  but we do need to
19344            // callback if requested.
19345            if (callback != null) {
19346                mHandler.post(new Runnable() {
19347                    @Override
19348                    public void run() {
19349                        try {
19350                            callback.userStopped(userId);
19351                        } catch (RemoteException e) {
19352                        }
19353                    }
19354                });
19355            }
19356            return ActivityManager.USER_OP_SUCCESS;
19357        }
19358
19359        if (callback != null) {
19360            uss.mStopCallbacks.add(callback);
19361        }
19362
19363        if (uss.mState != UserStartedState.STATE_STOPPING
19364                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19365            uss.mState = UserStartedState.STATE_STOPPING;
19366            updateStartedUserArrayLocked();
19367
19368            long ident = Binder.clearCallingIdentity();
19369            try {
19370                // We are going to broadcast ACTION_USER_STOPPING and then
19371                // once that is done send a final ACTION_SHUTDOWN and then
19372                // stop the user.
19373                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19374                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19375                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19376                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19377                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19378                // This is the result receiver for the final shutdown broadcast.
19379                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19380                    @Override
19381                    public void performReceive(Intent intent, int resultCode, String data,
19382                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19383                        finishUserStop(uss);
19384                    }
19385                };
19386                // This is the result receiver for the initial stopping broadcast.
19387                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19388                    @Override
19389                    public void performReceive(Intent intent, int resultCode, String data,
19390                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19391                        // On to the next.
19392                        synchronized (ActivityManagerService.this) {
19393                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19394                                // Whoops, we are being started back up.  Abort, abort!
19395                                return;
19396                            }
19397                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19398                        }
19399                        mBatteryStatsService.noteEvent(
19400                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19401                                Integer.toString(userId), userId);
19402                        mSystemServiceManager.stopUser(userId);
19403                        broadcastIntentLocked(null, null, shutdownIntent,
19404                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19405                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19406                    }
19407                };
19408                // Kick things off.
19409                broadcastIntentLocked(null, null, stoppingIntent,
19410                        null, stoppingReceiver, 0, null, null,
19411                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19412                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19413            } finally {
19414                Binder.restoreCallingIdentity(ident);
19415            }
19416        }
19417
19418        return ActivityManager.USER_OP_SUCCESS;
19419    }
19420
19421    void finishUserStop(UserStartedState uss) {
19422        final int userId = uss.mHandle.getIdentifier();
19423        boolean stopped;
19424        ArrayList<IStopUserCallback> callbacks;
19425        synchronized (this) {
19426            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19427            if (mStartedUsers.get(userId) != uss) {
19428                stopped = false;
19429            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19430                stopped = false;
19431            } else {
19432                stopped = true;
19433                // User can no longer run.
19434                mStartedUsers.remove(userId);
19435                mUserLru.remove(Integer.valueOf(userId));
19436                updateStartedUserArrayLocked();
19437
19438                // Clean up all state and processes associated with the user.
19439                // Kill all the processes for the user.
19440                forceStopUserLocked(userId, "finish user");
19441            }
19442
19443            // Explicitly remove the old information in mRecentTasks.
19444            mRecentTasks.removeTasksForUserLocked(userId);
19445        }
19446
19447        for (int i=0; i<callbacks.size(); i++) {
19448            try {
19449                if (stopped) callbacks.get(i).userStopped(userId);
19450                else callbacks.get(i).userStopAborted(userId);
19451            } catch (RemoteException e) {
19452            }
19453        }
19454
19455        if (stopped) {
19456            mSystemServiceManager.cleanupUser(userId);
19457            synchronized (this) {
19458                mStackSupervisor.removeUserLocked(userId);
19459            }
19460        }
19461    }
19462
19463    @Override
19464    public UserInfo getCurrentUser() {
19465        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19466                != PackageManager.PERMISSION_GRANTED) && (
19467                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19468                != PackageManager.PERMISSION_GRANTED)) {
19469            String msg = "Permission Denial: getCurrentUser() from pid="
19470                    + Binder.getCallingPid()
19471                    + ", uid=" + Binder.getCallingUid()
19472                    + " requires " + INTERACT_ACROSS_USERS;
19473            Slog.w(TAG, msg);
19474            throw new SecurityException(msg);
19475        }
19476        synchronized (this) {
19477            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19478            return getUserManagerLocked().getUserInfo(userId);
19479        }
19480    }
19481
19482    int getCurrentUserIdLocked() {
19483        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19484    }
19485
19486    @Override
19487    public boolean isUserRunning(int userId, boolean orStopped) {
19488        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19489                != PackageManager.PERMISSION_GRANTED) {
19490            String msg = "Permission Denial: isUserRunning() from pid="
19491                    + Binder.getCallingPid()
19492                    + ", uid=" + Binder.getCallingUid()
19493                    + " requires " + INTERACT_ACROSS_USERS;
19494            Slog.w(TAG, msg);
19495            throw new SecurityException(msg);
19496        }
19497        synchronized (this) {
19498            return isUserRunningLocked(userId, orStopped);
19499        }
19500    }
19501
19502    boolean isUserRunningLocked(int userId, boolean orStopped) {
19503        UserStartedState state = mStartedUsers.get(userId);
19504        if (state == null) {
19505            return false;
19506        }
19507        if (orStopped) {
19508            return true;
19509        }
19510        return state.mState != UserStartedState.STATE_STOPPING
19511                && state.mState != UserStartedState.STATE_SHUTDOWN;
19512    }
19513
19514    @Override
19515    public int[] getRunningUserIds() {
19516        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19517                != PackageManager.PERMISSION_GRANTED) {
19518            String msg = "Permission Denial: isUserRunning() from pid="
19519                    + Binder.getCallingPid()
19520                    + ", uid=" + Binder.getCallingUid()
19521                    + " requires " + INTERACT_ACROSS_USERS;
19522            Slog.w(TAG, msg);
19523            throw new SecurityException(msg);
19524        }
19525        synchronized (this) {
19526            return mStartedUserArray;
19527        }
19528    }
19529
19530    private void updateStartedUserArrayLocked() {
19531        int num = 0;
19532        for (int i=0; i<mStartedUsers.size();  i++) {
19533            UserStartedState uss = mStartedUsers.valueAt(i);
19534            // This list does not include stopping users.
19535            if (uss.mState != UserStartedState.STATE_STOPPING
19536                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19537                num++;
19538            }
19539        }
19540        mStartedUserArray = new int[num];
19541        num = 0;
19542        for (int i=0; i<mStartedUsers.size();  i++) {
19543            UserStartedState uss = mStartedUsers.valueAt(i);
19544            if (uss.mState != UserStartedState.STATE_STOPPING
19545                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19546                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19547                num++;
19548            }
19549        }
19550    }
19551
19552    @Override
19553    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19554        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19555                != PackageManager.PERMISSION_GRANTED) {
19556            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19557                    + Binder.getCallingPid()
19558                    + ", uid=" + Binder.getCallingUid()
19559                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19560            Slog.w(TAG, msg);
19561            throw new SecurityException(msg);
19562        }
19563
19564        mUserSwitchObservers.register(observer);
19565    }
19566
19567    @Override
19568    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19569        mUserSwitchObservers.unregister(observer);
19570    }
19571
19572    int[] getUsersLocked() {
19573        UserManagerService ums = getUserManagerLocked();
19574        return ums != null ? ums.getUserIds() : new int[] { 0 };
19575    }
19576
19577    UserManagerService getUserManagerLocked() {
19578        if (mUserManager == null) {
19579            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19580            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19581        }
19582        return mUserManager;
19583    }
19584
19585    private int applyUserId(int uid, int userId) {
19586        return UserHandle.getUid(userId, uid);
19587    }
19588
19589    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19590        if (info == null) return null;
19591        ApplicationInfo newInfo = new ApplicationInfo(info);
19592        newInfo.uid = applyUserId(info.uid, userId);
19593        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19594                + info.packageName;
19595        return newInfo;
19596    }
19597
19598    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19599        if (aInfo == null
19600                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19601            return aInfo;
19602        }
19603
19604        ActivityInfo info = new ActivityInfo(aInfo);
19605        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19606        return info;
19607    }
19608
19609    private final class LocalService extends ActivityManagerInternal {
19610        @Override
19611        public void onWakefulnessChanged(int wakefulness) {
19612            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19613        }
19614
19615        @Override
19616        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19617                String processName, String abiOverride, int uid, Runnable crashHandler) {
19618            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19619                    processName, abiOverride, uid, crashHandler);
19620        }
19621    }
19622
19623    /**
19624     * An implementation of IAppTask, that allows an app to manage its own tasks via
19625     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19626     * only the process that calls getAppTasks() can call the AppTask methods.
19627     */
19628    class AppTaskImpl extends IAppTask.Stub {
19629        private int mTaskId;
19630        private int mCallingUid;
19631
19632        public AppTaskImpl(int taskId, int callingUid) {
19633            mTaskId = taskId;
19634            mCallingUid = callingUid;
19635        }
19636
19637        private void checkCaller() {
19638            if (mCallingUid != Binder.getCallingUid()) {
19639                throw new SecurityException("Caller " + mCallingUid
19640                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19641            }
19642        }
19643
19644        @Override
19645        public void finishAndRemoveTask() {
19646            checkCaller();
19647
19648            synchronized (ActivityManagerService.this) {
19649                long origId = Binder.clearCallingIdentity();
19650                try {
19651                    if (!removeTaskByIdLocked(mTaskId, false)) {
19652                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19653                    }
19654                } finally {
19655                    Binder.restoreCallingIdentity(origId);
19656                }
19657            }
19658        }
19659
19660        @Override
19661        public ActivityManager.RecentTaskInfo getTaskInfo() {
19662            checkCaller();
19663
19664            synchronized (ActivityManagerService.this) {
19665                long origId = Binder.clearCallingIdentity();
19666                try {
19667                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
19668                    if (tr == null) {
19669                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19670                    }
19671                    return createRecentTaskInfoFromTaskRecord(tr);
19672                } finally {
19673                    Binder.restoreCallingIdentity(origId);
19674                }
19675            }
19676        }
19677
19678        @Override
19679        public void moveToFront() {
19680            checkCaller();
19681            // Will bring task to front if it already has a root activity.
19682            startActivityFromRecentsInner(mTaskId, null);
19683        }
19684
19685        @Override
19686        public int startActivity(IBinder whoThread, String callingPackage,
19687                Intent intent, String resolvedType, Bundle options) {
19688            checkCaller();
19689
19690            int callingUser = UserHandle.getCallingUserId();
19691            TaskRecord tr;
19692            IApplicationThread appThread;
19693            synchronized (ActivityManagerService.this) {
19694                tr = mRecentTasks.taskForIdLocked(mTaskId);
19695                if (tr == null) {
19696                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19697                }
19698                appThread = ApplicationThreadNative.asInterface(whoThread);
19699                if (appThread == null) {
19700                    throw new IllegalArgumentException("Bad app thread " + appThread);
19701                }
19702            }
19703            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19704                    resolvedType, null, null, null, null, 0, 0, null, null,
19705                    null, options, callingUser, null, tr);
19706        }
19707
19708        @Override
19709        public void setExcludeFromRecents(boolean exclude) {
19710            checkCaller();
19711
19712            synchronized (ActivityManagerService.this) {
19713                long origId = Binder.clearCallingIdentity();
19714                try {
19715                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
19716                    if (tr == null) {
19717                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19718                    }
19719                    Intent intent = tr.getBaseIntent();
19720                    if (exclude) {
19721                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19722                    } else {
19723                        intent.setFlags(intent.getFlags()
19724                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19725                    }
19726                } finally {
19727                    Binder.restoreCallingIdentity(origId);
19728                }
19729            }
19730        }
19731    }
19732}
19733