ActivityManagerService.java revision d23e0d6901935588f9472bd7073fea0009581e9b
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.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static com.android.server.am.ActivityManagerDebugConfig.*;
31import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
32import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
33import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
34import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
35import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
36import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
37import static org.xmlpull.v1.XmlPullParser.START_TAG;
38
39import android.Manifest;
40import android.app.AppOpsManager;
41import android.app.ApplicationThreadNative;
42import android.app.IActivityContainer;
43import android.app.IActivityContainerCallback;
44import android.app.IAppTask;
45import android.app.ITaskStackListener;
46import android.app.ProfilerInfo;
47import android.app.usage.UsageEvents;
48import android.app.usage.UsageStatsManagerInternal;
49import android.appwidget.AppWidgetManager;
50import android.content.pm.PermissionInfo;
51import android.content.res.Resources;
52import android.graphics.Bitmap;
53import android.graphics.Point;
54import android.graphics.Rect;
55import android.os.BatteryStats;
56import android.os.PersistableBundle;
57import android.os.PowerManager;
58import android.os.TransactionTooLargeException;
59import android.os.WorkSource;
60import android.os.storage.IMountService;
61import android.os.storage.StorageManager;
62import android.service.voice.IVoiceInteractionSession;
63import android.util.ArrayMap;
64import android.util.ArraySet;
65import android.util.DebugUtils;
66import android.util.SparseIntArray;
67import android.view.Display;
68
69import com.android.internal.R;
70import com.android.internal.annotations.GuardedBy;
71import com.android.internal.app.DumpHeapActivity;
72import com.android.internal.app.IAppOpsService;
73import com.android.internal.app.IVoiceInteractor;
74import com.android.internal.app.ProcessMap;
75import com.android.internal.app.ProcessStats;
76import com.android.internal.os.BackgroundThread;
77import com.android.internal.os.BatteryStatsImpl;
78import com.android.internal.os.IResultReceiver;
79import com.android.internal.os.ProcessCpuTracker;
80import com.android.internal.os.TransferPipe;
81import com.android.internal.os.Zygote;
82import com.android.internal.util.ArrayUtils;
83import com.android.internal.util.FastPrintWriter;
84import com.android.internal.util.FastXmlSerializer;
85import com.android.internal.util.MemInfoReader;
86import com.android.internal.util.Preconditions;
87import com.android.server.AppOpsService;
88import com.android.server.AttributeCache;
89import com.android.server.IntentResolver;
90import com.android.server.LocalServices;
91import com.android.server.ServiceThread;
92import com.android.server.SystemService;
93import com.android.server.SystemServiceManager;
94import com.android.server.Watchdog;
95import com.android.server.am.ActivityStack.ActivityState;
96import com.android.server.firewall.IntentFirewall;
97import com.android.server.pm.Installer;
98import com.android.server.pm.UserManagerService;
99import com.android.server.statusbar.StatusBarManagerInternal;
100import com.android.server.wm.AppTransition;
101import com.android.server.wm.WindowManagerService;
102import com.google.android.collect.Lists;
103import com.google.android.collect.Maps;
104
105import libcore.io.IoUtils;
106import libcore.util.EmptyArray;
107
108import org.xmlpull.v1.XmlPullParser;
109import org.xmlpull.v1.XmlPullParserException;
110import org.xmlpull.v1.XmlSerializer;
111
112import android.app.Activity;
113import android.app.ActivityManager;
114import android.app.ActivityManager.RunningTaskInfo;
115import android.app.ActivityManager.StackInfo;
116import android.app.ActivityManagerInternal;
117import android.app.ActivityManagerInternal.SleepToken;
118import android.app.ActivityManagerNative;
119import android.app.ActivityOptions;
120import android.app.ActivityThread;
121import android.app.AlertDialog;
122import android.app.AppGlobals;
123import android.app.ApplicationErrorReport;
124import android.app.Dialog;
125import android.app.IActivityController;
126import android.app.IApplicationThread;
127import android.app.IInstrumentationWatcher;
128import android.app.INotificationManager;
129import android.app.IProcessObserver;
130import android.app.IServiceConnection;
131import android.app.IStopUserCallback;
132import android.app.IUidObserver;
133import android.app.IUiAutomationConnection;
134import android.app.IUserSwitchObserver;
135import android.app.Instrumentation;
136import android.app.Notification;
137import android.app.NotificationManager;
138import android.app.PendingIntent;
139import android.app.backup.IBackupManager;
140import android.content.ActivityNotFoundException;
141import android.content.BroadcastReceiver;
142import android.content.ClipData;
143import android.content.ComponentCallbacks2;
144import android.content.ComponentName;
145import android.content.ContentProvider;
146import android.content.ContentResolver;
147import android.content.Context;
148import android.content.DialogInterface;
149import android.content.IContentProvider;
150import android.content.IIntentReceiver;
151import android.content.IIntentSender;
152import android.content.Intent;
153import android.content.IntentFilter;
154import android.content.IntentSender;
155import android.content.pm.ActivityInfo;
156import android.content.pm.ApplicationInfo;
157import android.content.pm.ConfigurationInfo;
158import android.content.pm.IPackageDataObserver;
159import android.content.pm.IPackageManager;
160import android.content.pm.InstrumentationInfo;
161import android.content.pm.PackageInfo;
162import android.content.pm.PackageManager;
163import android.content.pm.ParceledListSlice;
164import android.content.pm.UserInfo;
165import android.content.pm.PackageManager.NameNotFoundException;
166import android.content.pm.PathPermission;
167import android.content.pm.ProviderInfo;
168import android.content.pm.ResolveInfo;
169import android.content.pm.ServiceInfo;
170import android.content.res.CompatibilityInfo;
171import android.content.res.Configuration;
172import android.net.Proxy;
173import android.net.ProxyInfo;
174import android.net.Uri;
175import android.os.Binder;
176import android.os.Build;
177import android.os.Bundle;
178import android.os.Debug;
179import android.os.DropBoxManager;
180import android.os.Environment;
181import android.os.FactoryTest;
182import android.os.FileObserver;
183import android.os.FileUtils;
184import android.os.Handler;
185import android.os.IBinder;
186import android.os.IPermissionController;
187import android.os.IProcessInfoService;
188import android.os.IRemoteCallback;
189import android.os.IUserManager;
190import android.os.Looper;
191import android.os.Message;
192import android.os.Parcel;
193import android.os.ParcelFileDescriptor;
194import android.os.PowerManagerInternal;
195import android.os.Process;
196import android.os.RemoteCallbackList;
197import android.os.RemoteException;
198import android.os.SELinux;
199import android.os.ServiceManager;
200import android.os.StrictMode;
201import android.os.SystemClock;
202import android.os.SystemProperties;
203import android.os.UpdateLock;
204import android.os.UserHandle;
205import android.os.UserManager;
206import android.provider.Settings;
207import android.text.format.DateUtils;
208import android.text.format.Time;
209import android.util.AtomicFile;
210import android.util.EventLog;
211import android.util.Log;
212import android.util.Pair;
213import android.util.PrintWriterPrinter;
214import android.util.Slog;
215import android.util.SparseArray;
216import android.util.TimeUtils;
217import android.util.Xml;
218import android.view.Gravity;
219import android.view.LayoutInflater;
220import android.view.View;
221import android.view.WindowManager;
222
223import dalvik.system.VMRuntime;
224
225import java.io.BufferedInputStream;
226import java.io.BufferedOutputStream;
227import java.io.DataInputStream;
228import java.io.DataOutputStream;
229import java.io.File;
230import java.io.FileDescriptor;
231import java.io.FileInputStream;
232import java.io.FileNotFoundException;
233import java.io.FileOutputStream;
234import java.io.IOException;
235import java.io.InputStreamReader;
236import java.io.PrintWriter;
237import java.io.StringWriter;
238import java.lang.ref.WeakReference;
239import java.nio.charset.StandardCharsets;
240import java.util.ArrayList;
241import java.util.Arrays;
242import java.util.Collections;
243import java.util.Comparator;
244import java.util.HashMap;
245import java.util.HashSet;
246import java.util.Iterator;
247import java.util.List;
248import java.util.Locale;
249import java.util.Map;
250import java.util.Set;
251import java.util.concurrent.atomic.AtomicBoolean;
252import java.util.concurrent.atomic.AtomicLong;
253
254public final class ActivityManagerService extends ActivityManagerNative
255        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
256
257    // File that stores last updated system version and called preboot receivers
258    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
259
260    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
261    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
262    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
263    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
264    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
265    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
266    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
267    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
268    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
269    private static final String TAG_LRU = TAG + POSTFIX_LRU;
270    private static final String TAG_MU = TAG + POSTFIX_MU;
271    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
272    private static final String TAG_POWER = TAG + POSTFIX_POWER;
273    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
274    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
275    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
276    private static final String TAG_PSS = TAG + POSTFIX_PSS;
277    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
278    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
279    private static final String TAG_STACK = TAG + POSTFIX_STACK;
280    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
281    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
282    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
283    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
284
285    /** Control over CPU and battery monitoring */
286    // write battery stats every 30 minutes.
287    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
288    static final boolean MONITOR_CPU_USAGE = true;
289    // don't sample cpu less than every 5 seconds.
290    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
291    // wait possibly forever for next cpu sample.
292    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
293    static final boolean MONITOR_THREAD_CPU_USAGE = false;
294
295    // The flags that are set for all calls we make to the package manager.
296    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
297
298    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
299
300    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
301
302    // Amount of time after a call to stopAppSwitches() during which we will
303    // prevent further untrusted switches from happening.
304    static final long APP_SWITCH_DELAY_TIME = 5*1000;
305
306    // How long we wait for a launched process to attach to the activity manager
307    // before we decide it's never going to come up for real.
308    static final int PROC_START_TIMEOUT = 10*1000;
309
310    // How long we wait for a launched process to attach to the activity manager
311    // before we decide it's never going to come up for real, when the process was
312    // started with a wrapper for instrumentation (such as Valgrind) because it
313    // could take much longer than usual.
314    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
315
316    // How long to wait after going idle before forcing apps to GC.
317    static final int GC_TIMEOUT = 5*1000;
318
319    // The minimum amount of time between successive GC requests for a process.
320    static final int GC_MIN_INTERVAL = 60*1000;
321
322    // The minimum amount of time between successive PSS requests for a process.
323    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
324
325    // The minimum amount of time between successive PSS requests for a process
326    // when the request is due to the memory state being lowered.
327    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
328
329    // The rate at which we check for apps using excessive power -- 15 mins.
330    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
331
332    // The minimum sample duration we will allow before deciding we have
333    // enough data on wake locks to start killing things.
334    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
335
336    // The minimum sample duration we will allow before deciding we have
337    // enough data on CPU usage to start killing things.
338    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
339
340    // How long we allow a receiver to run before giving up on it.
341    static final int BROADCAST_FG_TIMEOUT = 10*1000;
342    static final int BROADCAST_BG_TIMEOUT = 60*1000;
343
344    // How long we wait until we timeout on key dispatching.
345    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
346
347    // How long we wait until we timeout on key dispatching during instrumentation.
348    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
349
350    // Amount of time we wait for observers to handle a user switch before
351    // giving up on them and unfreezing the screen.
352    static final int USER_SWITCH_TIMEOUT = 2*1000;
353
354    // Maximum number of users we allow to be running at a time.
355    static final int MAX_RUNNING_USERS = 3;
356
357    // How long to wait in getAssistContextExtras for the activity and foreground services
358    // to respond with the result.
359    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
360
361    // Maximum number of persisted Uri grants a package is allowed
362    static final int MAX_PERSISTED_URI_GRANTS = 128;
363
364    static final int MY_PID = Process.myPid();
365
366    static final String[] EMPTY_STRING_ARRAY = new String[0];
367
368    // How many bytes to write into the dropbox log before truncating
369    static final int DROPBOX_MAX_SIZE = 256 * 1024;
370
371    // Access modes for handleIncomingUser.
372    static final int ALLOW_NON_FULL = 0;
373    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
374    static final int ALLOW_FULL_ONLY = 2;
375
376    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
377
378    // Delay in notifying task stack change listeners (in millis)
379    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
380
381    // Necessary ApplicationInfo flags to mark an app as persistent
382    private static final int PERSISTENT_MASK =
383            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
384
385    /** All system services */
386    SystemServiceManager mSystemServiceManager;
387
388    private Installer mInstaller;
389
390    /** Run all ActivityStacks through this */
391    ActivityStackSupervisor mStackSupervisor;
392
393    /** Task stack change listeners. */
394    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
395            new RemoteCallbackList<ITaskStackListener>();
396
397    public IntentFirewall mIntentFirewall;
398
399    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
400    // default actuion automatically.  Important for devices without direct input
401    // devices.
402    private boolean mShowDialogs = true;
403
404    BroadcastQueue mFgBroadcastQueue;
405    BroadcastQueue mBgBroadcastQueue;
406    // Convenient for easy iteration over the queues. Foreground is first
407    // so that dispatch of foreground broadcasts gets precedence.
408    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
409
410    BroadcastQueue broadcastQueueForIntent(Intent intent) {
411        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
412        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
413                "Broadcast intent " + intent + " on "
414                + (isFg ? "foreground" : "background") + " queue");
415        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
416    }
417
418    /**
419     * Activity we have told the window manager to have key focus.
420     */
421    ActivityRecord mFocusedActivity = null;
422
423    /**
424     * User id of the last activity mFocusedActivity was set to.
425     */
426    private int mLastFocusedUserId;
427
428    /**
429     * List of intents that were used to start the most recent tasks.
430     */
431    private final RecentTasks mRecentTasks;
432
433    /**
434     * For addAppTask: cached of the last activity component that was added.
435     */
436    ComponentName mLastAddedTaskComponent;
437
438    /**
439     * For addAppTask: cached of the last activity uid that was added.
440     */
441    int mLastAddedTaskUid;
442
443    /**
444     * For addAppTask: cached of the last ActivityInfo that was added.
445     */
446    ActivityInfo mLastAddedTaskActivity;
447
448    /**
449     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
450     */
451    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
452
453    /**
454     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
455     */
456    String mDeviceOwnerName;
457
458    /**
459     * Preferred activities to start on boot/user switch, as set by DevicePolicyManager. Indexed
460     * by userId.
461     */
462    SparseArray<ComponentName> mPreferredSetupActivities = new SparseArray<>();
463
464    public class PendingAssistExtras extends Binder implements Runnable {
465        public final ActivityRecord activity;
466        public final Bundle extras;
467        public final Intent intent;
468        public final String hint;
469        public final IResultReceiver receiver;
470        public final int userHandle;
471        public boolean haveResult = false;
472        public Bundle result = null;
473        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
474                String _hint, IResultReceiver _receiver, int _userHandle) {
475            activity = _activity;
476            extras = _extras;
477            intent = _intent;
478            hint = _hint;
479            receiver = _receiver;
480            userHandle = _userHandle;
481        }
482        @Override
483        public void run() {
484            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
485            synchronized (ActivityManagerService.this) {
486                synchronized (this) {
487                    haveResult = true;
488                    notifyAll();
489                }
490                pendingAssistExtrasTimedOutLocked(this);
491            }
492        }
493    }
494
495    final ArrayList<PendingAssistExtras> mPendingAssistExtras
496            = new ArrayList<PendingAssistExtras>();
497
498    /**
499     * Process management.
500     */
501    final ProcessList mProcessList = new ProcessList();
502
503    /**
504     * All of the applications we currently have running organized by name.
505     * The keys are strings of the application package name (as
506     * returned by the package manager), and the keys are ApplicationRecord
507     * objects.
508     */
509    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
510
511    /**
512     * Tracking long-term execution of processes to look for abuse and other
513     * bad app behavior.
514     */
515    final ProcessStatsService mProcessStats;
516
517    /**
518     * The currently running isolated processes.
519     */
520    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
521
522    /**
523     * Counter for assigning isolated process uids, to avoid frequently reusing the
524     * same ones.
525     */
526    int mNextIsolatedProcessUid = 0;
527
528    /**
529     * The currently running heavy-weight process, if any.
530     */
531    ProcessRecord mHeavyWeightProcess = null;
532
533    /**
534     * The last time that various processes have crashed.
535     */
536    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
537
538    /**
539     * Information about a process that is currently marked as bad.
540     */
541    static final class BadProcessInfo {
542        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
543            this.time = time;
544            this.shortMsg = shortMsg;
545            this.longMsg = longMsg;
546            this.stack = stack;
547        }
548
549        final long time;
550        final String shortMsg;
551        final String longMsg;
552        final String stack;
553    }
554
555    /**
556     * Set of applications that we consider to be bad, and will reject
557     * incoming broadcasts from (which the user has no control over).
558     * Processes are added to this set when they have crashed twice within
559     * a minimum amount of time; they are removed from it when they are
560     * later restarted (hopefully due to some user action).  The value is the
561     * time it was added to the list.
562     */
563    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
564
565    /**
566     * All of the processes we currently have running organized by pid.
567     * The keys are the pid running the application.
568     *
569     * <p>NOTE: This object is protected by its own lock, NOT the global
570     * activity manager lock!
571     */
572    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
573
574    /**
575     * All of the processes that have been forced to be foreground.  The key
576     * is the pid of the caller who requested it (we hold a death
577     * link on it).
578     */
579    abstract class ForegroundToken implements IBinder.DeathRecipient {
580        int pid;
581        IBinder token;
582    }
583    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
584
585    /**
586     * List of records for processes that someone had tried to start before the
587     * system was ready.  We don't start them at that point, but ensure they
588     * are started by the time booting is complete.
589     */
590    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
591
592    /**
593     * List of persistent applications that are in the process
594     * of being started.
595     */
596    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
597
598    /**
599     * Processes that are being forcibly torn down.
600     */
601    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
602
603    /**
604     * List of running applications, sorted by recent usage.
605     * The first entry in the list is the least recently used.
606     */
607    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
608
609    /**
610     * Where in mLruProcesses that the processes hosting activities start.
611     */
612    int mLruProcessActivityStart = 0;
613
614    /**
615     * Where in mLruProcesses that the processes hosting services start.
616     * This is after (lower index) than mLruProcessesActivityStart.
617     */
618    int mLruProcessServiceStart = 0;
619
620    /**
621     * List of processes that should gc as soon as things are idle.
622     */
623    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
624
625    /**
626     * Processes we want to collect PSS data from.
627     */
628    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
629
630    /**
631     * Last time we requested PSS data of all processes.
632     */
633    long mLastFullPssTime = SystemClock.uptimeMillis();
634
635    /**
636     * If set, the next time we collect PSS data we should do a full collection
637     * with data from native processes and the kernel.
638     */
639    boolean mFullPssPending = false;
640
641    /**
642     * This is the process holding what we currently consider to be
643     * the "home" activity.
644     */
645    ProcessRecord mHomeProcess;
646
647    /**
648     * This is the process holding the activity the user last visited that
649     * is in a different process from the one they are currently in.
650     */
651    ProcessRecord mPreviousProcess;
652
653    /**
654     * The time at which the previous process was last visible.
655     */
656    long mPreviousProcessVisibleTime;
657
658    /**
659     * Track all uids that have actively running processes.
660     */
661    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
662
663    /**
664     * Which uses have been started, so are allowed to run code.
665     */
666    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<>();
667
668    /**
669     * LRU list of history of current users.  Most recently current is at the end.
670     */
671    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
672
673    /**
674     * Constant array of the users that are currently started.
675     */
676    int[] mStartedUserArray = new int[] { 0 };
677
678    /**
679     * Registered observers of the user switching mechanics.
680     */
681    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
682            = new RemoteCallbackList<IUserSwitchObserver>();
683
684    /**
685     * Currently active user switch.
686     */
687    Object mCurUserSwitchCallback;
688
689    /**
690     * Packages that the user has asked to have run in screen size
691     * compatibility mode instead of filling the screen.
692     */
693    final CompatModePackages mCompatModePackages;
694
695    /**
696     * Set of IntentSenderRecord objects that are currently active.
697     */
698    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
699            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
700
701    /**
702     * Fingerprints (hashCode()) of stack traces that we've
703     * already logged DropBox entries for.  Guarded by itself.  If
704     * something (rogue user app) forces this over
705     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
706     */
707    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
708    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
709
710    /**
711     * Strict Mode background batched logging state.
712     *
713     * The string buffer is guarded by itself, and its lock is also
714     * used to determine if another batched write is already
715     * in-flight.
716     */
717    private final StringBuilder mStrictModeBuffer = new StringBuilder();
718
719    /**
720     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
721     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
722     */
723    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
724
725    /**
726     * Resolver for broadcast intents to registered receivers.
727     * Holds BroadcastFilter (subclass of IntentFilter).
728     */
729    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
730            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
731        @Override
732        protected boolean allowFilterResult(
733                BroadcastFilter filter, List<BroadcastFilter> dest) {
734            IBinder target = filter.receiverList.receiver.asBinder();
735            for (int i = dest.size() - 1; i >= 0; i--) {
736                if (dest.get(i).receiverList.receiver.asBinder() == target) {
737                    return false;
738                }
739            }
740            return true;
741        }
742
743        @Override
744        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
745            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
746                    || userId == filter.owningUserId) {
747                return super.newResult(filter, match, userId);
748            }
749            return null;
750        }
751
752        @Override
753        protected BroadcastFilter[] newArray(int size) {
754            return new BroadcastFilter[size];
755        }
756
757        @Override
758        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
759            return packageName.equals(filter.packageName);
760        }
761    };
762
763    /**
764     * State of all active sticky broadcasts per user.  Keys are the action of the
765     * sticky Intent, values are an ArrayList of all broadcasted intents with
766     * that action (which should usually be one).  The SparseArray is keyed
767     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
768     * for stickies that are sent to all users.
769     */
770    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
771            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
772
773    final ActiveServices mServices;
774
775    final static class Association {
776        final int mSourceUid;
777        final String mSourceProcess;
778        final int mTargetUid;
779        final ComponentName mTargetComponent;
780        final String mTargetProcess;
781
782        int mCount;
783        long mTime;
784
785        int mNesting;
786        long mStartTime;
787
788        Association(int sourceUid, String sourceProcess, int targetUid,
789                ComponentName targetComponent, String targetProcess) {
790            mSourceUid = sourceUid;
791            mSourceProcess = sourceProcess;
792            mTargetUid = targetUid;
793            mTargetComponent = targetComponent;
794            mTargetProcess = targetProcess;
795        }
796    }
797
798    /**
799     * When service association tracking is enabled, this is all of the associations we
800     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
801     * -> association data.
802     */
803    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
804            mAssociations = new SparseArray<>();
805    boolean mTrackingAssociations;
806
807    /**
808     * Backup/restore process management
809     */
810    String mBackupAppName = null;
811    BackupRecord mBackupTarget = null;
812
813    final ProviderMap mProviderMap;
814
815    /**
816     * List of content providers who have clients waiting for them.  The
817     * application is currently being launched and the provider will be
818     * removed from this list once it is published.
819     */
820    final ArrayList<ContentProviderRecord> mLaunchingProviders
821            = new ArrayList<ContentProviderRecord>();
822
823    /**
824     * File storing persisted {@link #mGrantedUriPermissions}.
825     */
826    private final AtomicFile mGrantFile;
827
828    /** XML constants used in {@link #mGrantFile} */
829    private static final String TAG_URI_GRANTS = "uri-grants";
830    private static final String TAG_URI_GRANT = "uri-grant";
831    private static final String ATTR_USER_HANDLE = "userHandle";
832    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
833    private static final String ATTR_TARGET_USER_ID = "targetUserId";
834    private static final String ATTR_SOURCE_PKG = "sourcePkg";
835    private static final String ATTR_TARGET_PKG = "targetPkg";
836    private static final String ATTR_URI = "uri";
837    private static final String ATTR_MODE_FLAGS = "modeFlags";
838    private static final String ATTR_CREATED_TIME = "createdTime";
839    private static final String ATTR_PREFIX = "prefix";
840
841    /**
842     * Global set of specific {@link Uri} permissions that have been granted.
843     * This optimized lookup structure maps from {@link UriPermission#targetUid}
844     * to {@link UriPermission#uri} to {@link UriPermission}.
845     */
846    @GuardedBy("this")
847    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
848            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
849
850    public static class GrantUri {
851        public final int sourceUserId;
852        public final Uri uri;
853        public boolean prefix;
854
855        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
856            this.sourceUserId = sourceUserId;
857            this.uri = uri;
858            this.prefix = prefix;
859        }
860
861        @Override
862        public int hashCode() {
863            int hashCode = 1;
864            hashCode = 31 * hashCode + sourceUserId;
865            hashCode = 31 * hashCode + uri.hashCode();
866            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
867            return hashCode;
868        }
869
870        @Override
871        public boolean equals(Object o) {
872            if (o instanceof GrantUri) {
873                GrantUri other = (GrantUri) o;
874                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
875                        && prefix == other.prefix;
876            }
877            return false;
878        }
879
880        @Override
881        public String toString() {
882            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
883            if (prefix) result += " [prefix]";
884            return result;
885        }
886
887        public String toSafeString() {
888            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
889            if (prefix) result += " [prefix]";
890            return result;
891        }
892
893        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
894            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
895                    ContentProvider.getUriWithoutUserId(uri), false);
896        }
897    }
898
899    CoreSettingsObserver mCoreSettingsObserver;
900
901    /**
902     * Thread-local storage used to carry caller permissions over through
903     * indirect content-provider access.
904     */
905    private class Identity {
906        public final IBinder token;
907        public final int pid;
908        public final int uid;
909
910        Identity(IBinder _token, int _pid, int _uid) {
911            token = _token;
912            pid = _pid;
913            uid = _uid;
914        }
915    }
916
917    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
918
919    /**
920     * All information we have collected about the runtime performance of
921     * any user id that can impact battery performance.
922     */
923    final BatteryStatsService mBatteryStatsService;
924
925    /**
926     * Information about component usage
927     */
928    UsageStatsManagerInternal mUsageStatsService;
929
930    /**
931     * Information about and control over application operations
932     */
933    final AppOpsService mAppOpsService;
934
935    /**
936     * Save recent tasks information across reboots.
937     */
938    final TaskPersister mTaskPersister;
939
940    /**
941     * Current configuration information.  HistoryRecord objects are given
942     * a reference to this object to indicate which configuration they are
943     * currently running in, so this object must be kept immutable.
944     */
945    Configuration mConfiguration = new Configuration();
946
947    /**
948     * Current sequencing integer of the configuration, for skipping old
949     * configurations.
950     */
951    int mConfigurationSeq = 0;
952
953    /**
954     * Hardware-reported OpenGLES version.
955     */
956    final int GL_ES_VERSION;
957
958    /**
959     * List of initialization arguments to pass to all processes when binding applications to them.
960     * For example, references to the commonly used services.
961     */
962    HashMap<String, IBinder> mAppBindArgs;
963
964    /**
965     * Temporary to avoid allocations.  Protected by main lock.
966     */
967    final StringBuilder mStringBuilder = new StringBuilder(256);
968
969    /**
970     * Used to control how we initialize the service.
971     */
972    ComponentName mTopComponent;
973    String mTopAction = Intent.ACTION_MAIN;
974    String mTopData;
975    boolean mProcessesReady = false;
976    boolean mSystemReady = false;
977    boolean mBooting = false;
978    boolean mCallFinishBooting = false;
979    boolean mBootAnimationComplete = false;
980    boolean mWaitingUpdate = false;
981    boolean mDidUpdate = false;
982    boolean mOnBattery = false;
983    boolean mLaunchWarningShown = false;
984
985    Context mContext;
986
987    int mFactoryTest;
988
989    boolean mCheckedForSetup;
990
991    /**
992     * The time at which we will allow normal application switches again,
993     * after a call to {@link #stopAppSwitches()}.
994     */
995    long mAppSwitchesAllowedTime;
996
997    /**
998     * This is set to true after the first switch after mAppSwitchesAllowedTime
999     * is set; any switches after that will clear the time.
1000     */
1001    boolean mDidAppSwitch;
1002
1003    /**
1004     * Last time (in realtime) at which we checked for power usage.
1005     */
1006    long mLastPowerCheckRealtime;
1007
1008    /**
1009     * Last time (in uptime) at which we checked for power usage.
1010     */
1011    long mLastPowerCheckUptime;
1012
1013    /**
1014     * Set while we are wanting to sleep, to prevent any
1015     * activities from being started/resumed.
1016     */
1017    private boolean mSleeping = false;
1018
1019    /**
1020     * The process state used for processes that are running the top activities.
1021     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1022     */
1023    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1024
1025    /**
1026     * Set while we are running a voice interaction.  This overrides
1027     * sleeping while it is active.
1028     */
1029    private IVoiceInteractionSession mRunningVoice;
1030
1031    /**
1032     * For some direct access we need to power manager.
1033     */
1034    PowerManagerInternal mLocalPowerManager;
1035
1036    /**
1037     * We want to hold a wake lock while running a voice interaction session, since
1038     * this may happen with the screen off and we need to keep the CPU running to
1039     * be able to continue to interact with the user.
1040     */
1041    PowerManager.WakeLock mVoiceWakeLock;
1042
1043    /**
1044     * State of external calls telling us if the device is awake or asleep.
1045     */
1046    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1047
1048    /**
1049     * A list of tokens that cause the top activity to be put to sleep.
1050     * They are used by components that may hide and block interaction with underlying
1051     * activities.
1052     */
1053    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1054
1055    static final int LOCK_SCREEN_HIDDEN = 0;
1056    static final int LOCK_SCREEN_LEAVING = 1;
1057    static final int LOCK_SCREEN_SHOWN = 2;
1058    /**
1059     * State of external call telling us if the lock screen is shown.
1060     */
1061    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1062
1063    /**
1064     * Set if we are shutting down the system, similar to sleeping.
1065     */
1066    boolean mShuttingDown = false;
1067
1068    /**
1069     * Current sequence id for oom_adj computation traversal.
1070     */
1071    int mAdjSeq = 0;
1072
1073    /**
1074     * Current sequence id for process LRU updating.
1075     */
1076    int mLruSeq = 0;
1077
1078    /**
1079     * Keep track of the non-cached/empty process we last found, to help
1080     * determine how to distribute cached/empty processes next time.
1081     */
1082    int mNumNonCachedProcs = 0;
1083
1084    /**
1085     * Keep track of the number of cached hidden procs, to balance oom adj
1086     * distribution between those and empty procs.
1087     */
1088    int mNumCachedHiddenProcs = 0;
1089
1090    /**
1091     * Keep track of the number of service processes we last found, to
1092     * determine on the next iteration which should be B services.
1093     */
1094    int mNumServiceProcs = 0;
1095    int mNewNumAServiceProcs = 0;
1096    int mNewNumServiceProcs = 0;
1097
1098    /**
1099     * Allow the current computed overall memory level of the system to go down?
1100     * This is set to false when we are killing processes for reasons other than
1101     * memory management, so that the now smaller process list will not be taken as
1102     * an indication that memory is tighter.
1103     */
1104    boolean mAllowLowerMemLevel = false;
1105
1106    /**
1107     * The last computed memory level, for holding when we are in a state that
1108     * processes are going away for other reasons.
1109     */
1110    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1111
1112    /**
1113     * The last total number of process we have, to determine if changes actually look
1114     * like a shrinking number of process due to lower RAM.
1115     */
1116    int mLastNumProcesses;
1117
1118    /**
1119     * The uptime of the last time we performed idle maintenance.
1120     */
1121    long mLastIdleTime = SystemClock.uptimeMillis();
1122
1123    /**
1124     * Total time spent with RAM that has been added in the past since the last idle time.
1125     */
1126    long mLowRamTimeSinceLastIdle = 0;
1127
1128    /**
1129     * If RAM is currently low, when that horrible situation started.
1130     */
1131    long mLowRamStartTime = 0;
1132
1133    /**
1134     * For reporting to battery stats the current top application.
1135     */
1136    private String mCurResumedPackage = null;
1137    private int mCurResumedUid = -1;
1138
1139    /**
1140     * For reporting to battery stats the apps currently running foreground
1141     * service.  The ProcessMap is package/uid tuples; each of these contain
1142     * an array of the currently foreground processes.
1143     */
1144    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1145            = new ProcessMap<ArrayList<ProcessRecord>>();
1146
1147    /**
1148     * This is set if we had to do a delayed dexopt of an app before launching
1149     * it, to increase the ANR timeouts in that case.
1150     */
1151    boolean mDidDexOpt;
1152
1153    /**
1154     * Set if the systemServer made a call to enterSafeMode.
1155     */
1156    boolean mSafeMode;
1157
1158    /**
1159     * If true, we are running under a test environment so will sample PSS from processes
1160     * much more rapidly to try to collect better data when the tests are rapidly
1161     * running through apps.
1162     */
1163    boolean mTestPssMode = false;
1164
1165    String mDebugApp = null;
1166    boolean mWaitForDebugger = false;
1167    boolean mDebugTransient = false;
1168    String mOrigDebugApp = null;
1169    boolean mOrigWaitForDebugger = false;
1170    boolean mAlwaysFinishActivities = false;
1171    IActivityController mController = null;
1172    String mProfileApp = null;
1173    ProcessRecord mProfileProc = null;
1174    String mProfileFile;
1175    ParcelFileDescriptor mProfileFd;
1176    int mSamplingInterval = 0;
1177    boolean mAutoStopProfiler = false;
1178    int mProfileType = 0;
1179    String mOpenGlTraceApp = null;
1180    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1181    String mMemWatchDumpProcName;
1182    String mMemWatchDumpFile;
1183    int mMemWatchDumpPid;
1184    int mMemWatchDumpUid;
1185
1186    final long[] mTmpLong = new long[1];
1187
1188    static final class ProcessChangeItem {
1189        static final int CHANGE_ACTIVITIES = 1<<0;
1190        static final int CHANGE_PROCESS_STATE = 1<<1;
1191        int changes;
1192        int uid;
1193        int pid;
1194        int processState;
1195        boolean foregroundActivities;
1196    }
1197
1198    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1199    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1200
1201    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1202    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1203
1204    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1205    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1206
1207    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1208    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1209
1210    /**
1211     * Runtime CPU use collection thread.  This object's lock is used to
1212     * perform synchronization with the thread (notifying it to run).
1213     */
1214    final Thread mProcessCpuThread;
1215
1216    /**
1217     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1218     * Must acquire this object's lock when accessing it.
1219     * NOTE: this lock will be held while doing long operations (trawling
1220     * through all processes in /proc), so it should never be acquired by
1221     * any critical paths such as when holding the main activity manager lock.
1222     */
1223    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1224            MONITOR_THREAD_CPU_USAGE);
1225    final AtomicLong mLastCpuTime = new AtomicLong(0);
1226    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1227
1228    long mLastWriteTime = 0;
1229
1230    /**
1231     * Used to retain an update lock when the foreground activity is in
1232     * immersive mode.
1233     */
1234    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1235
1236    /**
1237     * Set to true after the system has finished booting.
1238     */
1239    boolean mBooted = false;
1240
1241    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1242    int mProcessLimitOverride = -1;
1243
1244    WindowManagerService mWindowManager;
1245
1246    final ActivityThread mSystemThread;
1247
1248    // Holds the current foreground user's id
1249    int mCurrentUserId = 0;
1250    // Holds the target user's id during a user switch
1251    int mTargetUserId = UserHandle.USER_NULL;
1252    // If there are multiple profiles for the current user, their ids are here
1253    // Currently only the primary user can have managed profiles
1254    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1255
1256    /**
1257     * Mapping from each known user ID to the profile group ID it is associated with.
1258     */
1259    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1260
1261    private UserManagerService mUserManager;
1262
1263    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1264        final ProcessRecord mApp;
1265        final int mPid;
1266        final IApplicationThread mAppThread;
1267
1268        AppDeathRecipient(ProcessRecord app, int pid,
1269                IApplicationThread thread) {
1270            if (DEBUG_ALL) Slog.v(
1271                TAG, "New death recipient " + this
1272                + " for thread " + thread.asBinder());
1273            mApp = app;
1274            mPid = pid;
1275            mAppThread = thread;
1276        }
1277
1278        @Override
1279        public void binderDied() {
1280            if (DEBUG_ALL) Slog.v(
1281                TAG, "Death received in " + this
1282                + " for thread " + mAppThread.asBinder());
1283            synchronized(ActivityManagerService.this) {
1284                appDiedLocked(mApp, mPid, mAppThread, true);
1285            }
1286        }
1287    }
1288
1289    static final int SHOW_ERROR_MSG = 1;
1290    static final int SHOW_NOT_RESPONDING_MSG = 2;
1291    static final int SHOW_FACTORY_ERROR_MSG = 3;
1292    static final int UPDATE_CONFIGURATION_MSG = 4;
1293    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1294    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1295    static final int SERVICE_TIMEOUT_MSG = 12;
1296    static final int UPDATE_TIME_ZONE = 13;
1297    static final int SHOW_UID_ERROR_MSG = 14;
1298    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1299    static final int PROC_START_TIMEOUT_MSG = 20;
1300    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1301    static final int KILL_APPLICATION_MSG = 22;
1302    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1303    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1304    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1305    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1306    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1307    static final int CLEAR_DNS_CACHE_MSG = 28;
1308    static final int UPDATE_HTTP_PROXY_MSG = 29;
1309    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1310    static final int DISPATCH_PROCESSES_CHANGED = 31;
1311    static final int DISPATCH_PROCESS_DIED = 32;
1312    static final int REPORT_MEM_USAGE_MSG = 33;
1313    static final int REPORT_USER_SWITCH_MSG = 34;
1314    static final int CONTINUE_USER_SWITCH_MSG = 35;
1315    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1316    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1317    static final int PERSIST_URI_GRANTS_MSG = 38;
1318    static final int REQUEST_ALL_PSS_MSG = 39;
1319    static final int START_PROFILES_MSG = 40;
1320    static final int UPDATE_TIME = 41;
1321    static final int SYSTEM_USER_START_MSG = 42;
1322    static final int SYSTEM_USER_CURRENT_MSG = 43;
1323    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1324    static final int FINISH_BOOTING_MSG = 45;
1325    static final int START_USER_SWITCH_MSG = 46;
1326    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1327    static final int DISMISS_DIALOG_MSG = 48;
1328    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1329    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1330    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1331    static final int DELETE_DUMPHEAP_MSG = 52;
1332    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1333    static final int DISPATCH_UIDS_CHANGED = 54;
1334
1335    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1336    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1337    static final int FIRST_COMPAT_MODE_MSG = 300;
1338    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1339
1340    CompatModeDialog mCompatModeDialog;
1341    long mLastMemUsageReportTime = 0;
1342
1343    /**
1344     * Flag whether the current user is a "monkey", i.e. whether
1345     * the UI is driven by a UI automation tool.
1346     */
1347    private boolean mUserIsMonkey;
1348
1349    /** Flag whether the device has a Recents UI */
1350    boolean mHasRecents;
1351
1352    /** The dimensions of the thumbnails in the Recents UI. */
1353    int mThumbnailWidth;
1354    int mThumbnailHeight;
1355
1356    final ServiceThread mHandlerThread;
1357    final MainHandler mHandler;
1358    final UiHandler mUiHandler;
1359
1360    final class UiHandler extends Handler {
1361        public UiHandler() {
1362            super(com.android.server.UiThread.get().getLooper(), null, true);
1363        }
1364
1365        @Override
1366        public void handleMessage(Message msg) {
1367            switch (msg.what) {
1368            case SHOW_ERROR_MSG: {
1369                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1370                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1371                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1372                synchronized (ActivityManagerService.this) {
1373                    ProcessRecord proc = (ProcessRecord)data.get("app");
1374                    AppErrorResult res = (AppErrorResult) data.get("result");
1375                    if (proc != null && proc.crashDialog != null) {
1376                        Slog.e(TAG, "App already has crash dialog: " + proc);
1377                        if (res != null) {
1378                            res.set(0);
1379                        }
1380                        return;
1381                    }
1382                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1383                            >= Process.FIRST_APPLICATION_UID
1384                            && proc.pid != MY_PID);
1385                    for (int userId : mCurrentProfileIds) {
1386                        isBackground &= (proc.userId != userId);
1387                    }
1388                    if (isBackground && !showBackground) {
1389                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1390                        if (res != null) {
1391                            res.set(0);
1392                        }
1393                        return;
1394                    }
1395                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1396                        Dialog d = new AppErrorDialog(mContext,
1397                                ActivityManagerService.this, res, proc);
1398                        d.show();
1399                        proc.crashDialog = d;
1400                    } else {
1401                        // The device is asleep, so just pretend that the user
1402                        // saw a crash dialog and hit "force quit".
1403                        if (res != null) {
1404                            res.set(0);
1405                        }
1406                    }
1407                }
1408
1409                ensureBootCompleted();
1410            } break;
1411            case SHOW_NOT_RESPONDING_MSG: {
1412                synchronized (ActivityManagerService.this) {
1413                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1414                    ProcessRecord proc = (ProcessRecord)data.get("app");
1415                    if (proc != null && proc.anrDialog != null) {
1416                        Slog.e(TAG, "App already has anr dialog: " + proc);
1417                        return;
1418                    }
1419
1420                    Intent intent = new Intent("android.intent.action.ANR");
1421                    if (!mProcessesReady) {
1422                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1423                                | Intent.FLAG_RECEIVER_FOREGROUND);
1424                    }
1425                    broadcastIntentLocked(null, null, intent,
1426                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1427                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1428
1429                    if (mShowDialogs) {
1430                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1431                                mContext, proc, (ActivityRecord)data.get("activity"),
1432                                msg.arg1 != 0);
1433                        d.show();
1434                        proc.anrDialog = d;
1435                    } else {
1436                        // Just kill the app if there is no dialog to be shown.
1437                        killAppAtUsersRequest(proc, null);
1438                    }
1439                }
1440
1441                ensureBootCompleted();
1442            } break;
1443            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1444                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1445                synchronized (ActivityManagerService.this) {
1446                    ProcessRecord proc = (ProcessRecord) data.get("app");
1447                    if (proc == null) {
1448                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1449                        break;
1450                    }
1451                    if (proc.crashDialog != null) {
1452                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1453                        return;
1454                    }
1455                    AppErrorResult res = (AppErrorResult) data.get("result");
1456                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1457                        Dialog d = new StrictModeViolationDialog(mContext,
1458                                ActivityManagerService.this, res, proc);
1459                        d.show();
1460                        proc.crashDialog = d;
1461                    } else {
1462                        // The device is asleep, so just pretend that the user
1463                        // saw a crash dialog and hit "force quit".
1464                        res.set(0);
1465                    }
1466                }
1467                ensureBootCompleted();
1468            } break;
1469            case SHOW_FACTORY_ERROR_MSG: {
1470                Dialog d = new FactoryErrorDialog(
1471                    mContext, msg.getData().getCharSequence("msg"));
1472                d.show();
1473                ensureBootCompleted();
1474            } break;
1475            case WAIT_FOR_DEBUGGER_MSG: {
1476                synchronized (ActivityManagerService.this) {
1477                    ProcessRecord app = (ProcessRecord)msg.obj;
1478                    if (msg.arg1 != 0) {
1479                        if (!app.waitedForDebugger) {
1480                            Dialog d = new AppWaitingForDebuggerDialog(
1481                                    ActivityManagerService.this,
1482                                    mContext, app);
1483                            app.waitDialog = d;
1484                            app.waitedForDebugger = true;
1485                            d.show();
1486                        }
1487                    } else {
1488                        if (app.waitDialog != null) {
1489                            app.waitDialog.dismiss();
1490                            app.waitDialog = null;
1491                        }
1492                    }
1493                }
1494            } break;
1495            case SHOW_UID_ERROR_MSG: {
1496                if (mShowDialogs) {
1497                    AlertDialog d = new BaseErrorDialog(mContext);
1498                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1499                    d.setCancelable(false);
1500                    d.setTitle(mContext.getText(R.string.android_system_label));
1501                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1502                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1503                            obtainMessage(DISMISS_DIALOG_MSG, d));
1504                    d.show();
1505                }
1506            } break;
1507            case SHOW_FINGERPRINT_ERROR_MSG: {
1508                if (mShowDialogs) {
1509                    AlertDialog d = new BaseErrorDialog(mContext);
1510                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1511                    d.setCancelable(false);
1512                    d.setTitle(mContext.getText(R.string.android_system_label));
1513                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1514                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1515                            obtainMessage(DISMISS_DIALOG_MSG, d));
1516                    d.show();
1517                }
1518            } break;
1519            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1520                synchronized (ActivityManagerService.this) {
1521                    ActivityRecord ar = (ActivityRecord) msg.obj;
1522                    if (mCompatModeDialog != null) {
1523                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1524                                ar.info.applicationInfo.packageName)) {
1525                            return;
1526                        }
1527                        mCompatModeDialog.dismiss();
1528                        mCompatModeDialog = null;
1529                    }
1530                    if (ar != null && false) {
1531                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1532                                ar.packageName)) {
1533                            int mode = mCompatModePackages.computeCompatModeLocked(
1534                                    ar.info.applicationInfo);
1535                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1536                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1537                                mCompatModeDialog = new CompatModeDialog(
1538                                        ActivityManagerService.this, mContext,
1539                                        ar.info.applicationInfo);
1540                                mCompatModeDialog.show();
1541                            }
1542                        }
1543                    }
1544                }
1545                break;
1546            }
1547            case START_USER_SWITCH_MSG: {
1548                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1549                break;
1550            }
1551            case DISMISS_DIALOG_MSG: {
1552                final Dialog d = (Dialog) msg.obj;
1553                d.dismiss();
1554                break;
1555            }
1556            case DISPATCH_PROCESSES_CHANGED: {
1557                dispatchProcessesChanged();
1558                break;
1559            }
1560            case DISPATCH_PROCESS_DIED: {
1561                final int pid = msg.arg1;
1562                final int uid = msg.arg2;
1563                dispatchProcessDied(pid, uid);
1564                break;
1565            }
1566            case DISPATCH_UIDS_CHANGED: {
1567                dispatchUidsChanged();
1568            } break;
1569            }
1570        }
1571    }
1572
1573    final class MainHandler extends Handler {
1574        public MainHandler(Looper looper) {
1575            super(looper, null, true);
1576        }
1577
1578        @Override
1579        public void handleMessage(Message msg) {
1580            switch (msg.what) {
1581            case UPDATE_CONFIGURATION_MSG: {
1582                final ContentResolver resolver = mContext.getContentResolver();
1583                Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1584            } break;
1585            case GC_BACKGROUND_PROCESSES_MSG: {
1586                synchronized (ActivityManagerService.this) {
1587                    performAppGcsIfAppropriateLocked();
1588                }
1589            } break;
1590            case SERVICE_TIMEOUT_MSG: {
1591                if (mDidDexOpt) {
1592                    mDidDexOpt = false;
1593                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1594                    nmsg.obj = msg.obj;
1595                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1596                    return;
1597                }
1598                mServices.serviceTimeout((ProcessRecord)msg.obj);
1599            } break;
1600            case UPDATE_TIME_ZONE: {
1601                synchronized (ActivityManagerService.this) {
1602                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1603                        ProcessRecord r = mLruProcesses.get(i);
1604                        if (r.thread != null) {
1605                            try {
1606                                r.thread.updateTimeZone();
1607                            } catch (RemoteException ex) {
1608                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1609                            }
1610                        }
1611                    }
1612                }
1613            } break;
1614            case CLEAR_DNS_CACHE_MSG: {
1615                synchronized (ActivityManagerService.this) {
1616                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1617                        ProcessRecord r = mLruProcesses.get(i);
1618                        if (r.thread != null) {
1619                            try {
1620                                r.thread.clearDnsCache();
1621                            } catch (RemoteException ex) {
1622                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1623                            }
1624                        }
1625                    }
1626                }
1627            } break;
1628            case UPDATE_HTTP_PROXY_MSG: {
1629                ProxyInfo proxy = (ProxyInfo)msg.obj;
1630                String host = "";
1631                String port = "";
1632                String exclList = "";
1633                Uri pacFileUrl = Uri.EMPTY;
1634                if (proxy != null) {
1635                    host = proxy.getHost();
1636                    port = Integer.toString(proxy.getPort());
1637                    exclList = proxy.getExclusionListAsString();
1638                    pacFileUrl = proxy.getPacFileUrl();
1639                }
1640                synchronized (ActivityManagerService.this) {
1641                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1642                        ProcessRecord r = mLruProcesses.get(i);
1643                        if (r.thread != null) {
1644                            try {
1645                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1646                            } catch (RemoteException ex) {
1647                                Slog.w(TAG, "Failed to update http proxy for: " +
1648                                        r.info.processName);
1649                            }
1650                        }
1651                    }
1652                }
1653            } break;
1654            case PROC_START_TIMEOUT_MSG: {
1655                if (mDidDexOpt) {
1656                    mDidDexOpt = false;
1657                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1658                    nmsg.obj = msg.obj;
1659                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1660                    return;
1661                }
1662                ProcessRecord app = (ProcessRecord)msg.obj;
1663                synchronized (ActivityManagerService.this) {
1664                    processStartTimedOutLocked(app);
1665                }
1666            } break;
1667            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1668                synchronized (ActivityManagerService.this) {
1669                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1670                }
1671            } break;
1672            case KILL_APPLICATION_MSG: {
1673                synchronized (ActivityManagerService.this) {
1674                    int appid = msg.arg1;
1675                    boolean restart = (msg.arg2 == 1);
1676                    Bundle bundle = (Bundle)msg.obj;
1677                    String pkg = bundle.getString("pkg");
1678                    String reason = bundle.getString("reason");
1679                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1680                            false, UserHandle.USER_ALL, reason);
1681                }
1682            } break;
1683            case FINALIZE_PENDING_INTENT_MSG: {
1684                ((PendingIntentRecord)msg.obj).completeFinalize();
1685            } break;
1686            case POST_HEAVY_NOTIFICATION_MSG: {
1687                INotificationManager inm = NotificationManager.getService();
1688                if (inm == null) {
1689                    return;
1690                }
1691
1692                ActivityRecord root = (ActivityRecord)msg.obj;
1693                ProcessRecord process = root.app;
1694                if (process == null) {
1695                    return;
1696                }
1697
1698                try {
1699                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1700                    String text = mContext.getString(R.string.heavy_weight_notification,
1701                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1702                    Notification notification = new Notification();
1703                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1704                    notification.when = 0;
1705                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1706                    notification.tickerText = text;
1707                    notification.defaults = 0; // please be quiet
1708                    notification.sound = null;
1709                    notification.vibrate = null;
1710                    notification.color = mContext.getColor(
1711                            com.android.internal.R.color.system_notification_accent_color);
1712                    notification.setLatestEventInfo(context, text,
1713                            mContext.getText(R.string.heavy_weight_notification_detail),
1714                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1715                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1716                                    new UserHandle(root.userId)));
1717
1718                    try {
1719                        int[] outId = new int[1];
1720                        inm.enqueueNotificationWithTag("android", "android", null,
1721                                R.string.heavy_weight_notification,
1722                                notification, outId, root.userId);
1723                    } catch (RuntimeException e) {
1724                        Slog.w(ActivityManagerService.TAG,
1725                                "Error showing notification for heavy-weight app", e);
1726                    } catch (RemoteException e) {
1727                    }
1728                } catch (NameNotFoundException e) {
1729                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1730                }
1731            } break;
1732            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1733                INotificationManager inm = NotificationManager.getService();
1734                if (inm == null) {
1735                    return;
1736                }
1737                try {
1738                    inm.cancelNotificationWithTag("android", null,
1739                            R.string.heavy_weight_notification,  msg.arg1);
1740                } catch (RuntimeException e) {
1741                    Slog.w(ActivityManagerService.TAG,
1742                            "Error canceling notification for service", e);
1743                } catch (RemoteException e) {
1744                }
1745            } break;
1746            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1747                synchronized (ActivityManagerService.this) {
1748                    checkExcessivePowerUsageLocked(true);
1749                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1750                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1751                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1752                }
1753            } break;
1754            case REPORT_MEM_USAGE_MSG: {
1755                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1756                Thread thread = new Thread() {
1757                    @Override public void run() {
1758                        reportMemUsage(memInfos);
1759                    }
1760                };
1761                thread.start();
1762                break;
1763            }
1764            case REPORT_USER_SWITCH_MSG: {
1765                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1766                break;
1767            }
1768            case CONTINUE_USER_SWITCH_MSG: {
1769                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1770                break;
1771            }
1772            case USER_SWITCH_TIMEOUT_MSG: {
1773                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1774                break;
1775            }
1776            case IMMERSIVE_MODE_LOCK_MSG: {
1777                final boolean nextState = (msg.arg1 != 0);
1778                if (mUpdateLock.isHeld() != nextState) {
1779                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1780                            "Applying new update lock state '" + nextState
1781                            + "' for " + (ActivityRecord)msg.obj);
1782                    if (nextState) {
1783                        mUpdateLock.acquire();
1784                    } else {
1785                        mUpdateLock.release();
1786                    }
1787                }
1788                break;
1789            }
1790            case PERSIST_URI_GRANTS_MSG: {
1791                writeGrantedUriPermissions();
1792                break;
1793            }
1794            case REQUEST_ALL_PSS_MSG: {
1795                synchronized (ActivityManagerService.this) {
1796                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1797                }
1798                break;
1799            }
1800            case START_PROFILES_MSG: {
1801                synchronized (ActivityManagerService.this) {
1802                    startProfilesLocked();
1803                }
1804                break;
1805            }
1806            case UPDATE_TIME: {
1807                synchronized (ActivityManagerService.this) {
1808                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1809                        ProcessRecord r = mLruProcesses.get(i);
1810                        if (r.thread != null) {
1811                            try {
1812                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1813                            } catch (RemoteException ex) {
1814                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1815                            }
1816                        }
1817                    }
1818                }
1819                break;
1820            }
1821            case SYSTEM_USER_START_MSG: {
1822                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1823                        Integer.toString(msg.arg1), msg.arg1);
1824                mSystemServiceManager.startUser(msg.arg1);
1825                break;
1826            }
1827            case SYSTEM_USER_CURRENT_MSG: {
1828                mBatteryStatsService.noteEvent(
1829                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1830                        Integer.toString(msg.arg2), msg.arg2);
1831                mBatteryStatsService.noteEvent(
1832                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1833                        Integer.toString(msg.arg1), msg.arg1);
1834                mSystemServiceManager.switchUser(msg.arg1);
1835                break;
1836            }
1837            case ENTER_ANIMATION_COMPLETE_MSG: {
1838                synchronized (ActivityManagerService.this) {
1839                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1840                    if (r != null && r.app != null && r.app.thread != null) {
1841                        try {
1842                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1843                        } catch (RemoteException e) {
1844                        }
1845                    }
1846                }
1847                break;
1848            }
1849            case FINISH_BOOTING_MSG: {
1850                if (msg.arg1 != 0) {
1851                    finishBooting();
1852                }
1853                if (msg.arg2 != 0) {
1854                    enableScreenAfterBoot();
1855                }
1856                break;
1857            }
1858            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1859                try {
1860                    Locale l = (Locale) msg.obj;
1861                    IBinder service = ServiceManager.getService("mount");
1862                    IMountService mountService = IMountService.Stub.asInterface(service);
1863                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1864                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1865                } catch (RemoteException e) {
1866                    Log.e(TAG, "Error storing locale for decryption UI", e);
1867                }
1868                break;
1869            }
1870            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1871                synchronized (ActivityManagerService.this) {
1872                    int i = mTaskStackListeners.beginBroadcast();
1873                    while (i > 0) {
1874                        i--;
1875                        try {
1876                            // Make a one-way callback to the listener
1877                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1878                        } catch (RemoteException e){
1879                            // Handled by the RemoteCallbackList
1880                        }
1881                    }
1882                    mTaskStackListeners.finishBroadcast();
1883                }
1884                break;
1885            }
1886            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1887                final int uid = msg.arg1;
1888                final byte[] firstPacket = (byte[]) msg.obj;
1889
1890                synchronized (mPidsSelfLocked) {
1891                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1892                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1893                        if (p.uid == uid) {
1894                            try {
1895                                p.thread.notifyCleartextNetwork(firstPacket);
1896                            } catch (RemoteException ignored) {
1897                            }
1898                        }
1899                    }
1900                }
1901                break;
1902            }
1903            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1904                final String procName;
1905                final int uid;
1906                final long memLimit;
1907                final String reportPackage;
1908                synchronized (ActivityManagerService.this) {
1909                    procName = mMemWatchDumpProcName;
1910                    uid = mMemWatchDumpUid;
1911                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1912                    if (val == null) {
1913                        val = mMemWatchProcesses.get(procName, 0);
1914                    }
1915                    if (val != null) {
1916                        memLimit = val.first;
1917                        reportPackage = val.second;
1918                    } else {
1919                        memLimit = 0;
1920                        reportPackage = null;
1921                    }
1922                }
1923                if (procName == null) {
1924                    return;
1925                }
1926
1927                if (DEBUG_PSS) Slog.d(TAG_PSS,
1928                        "Showing dump heap notification from " + procName + "/" + uid);
1929
1930                INotificationManager inm = NotificationManager.getService();
1931                if (inm == null) {
1932                    return;
1933                }
1934
1935                String text = mContext.getString(R.string.dump_heap_notification, procName);
1936                Notification notification = new Notification();
1937                notification.icon = com.android.internal.R.drawable.stat_sys_adb;
1938                notification.when = 0;
1939                notification.flags = Notification.FLAG_ONGOING_EVENT|Notification.FLAG_AUTO_CANCEL;
1940                notification.tickerText = text;
1941                notification.defaults = 0; // please be quiet
1942                notification.sound = null;
1943                notification.vibrate = null;
1944                notification.color = mContext.getColor(
1945                        com.android.internal.R.color.system_notification_accent_color);
1946                Intent deleteIntent = new Intent();
1947                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1948                notification.deleteIntent = PendingIntent.getBroadcastAsUser(mContext, 0,
1949                        deleteIntent, 0, UserHandle.OWNER);
1950                Intent intent = new Intent();
1951                intent.setClassName("android", DumpHeapActivity.class.getName());
1952                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1953                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1954                if (reportPackage != null) {
1955                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1956                }
1957                int userId = UserHandle.getUserId(uid);
1958                notification.setLatestEventInfo(mContext, text,
1959                        mContext.getText(R.string.dump_heap_notification_detail),
1960                        PendingIntent.getActivityAsUser(mContext, 0, intent,
1961                                PendingIntent.FLAG_CANCEL_CURRENT, null,
1962                                new UserHandle(userId)));
1963
1964                try {
1965                    int[] outId = new int[1];
1966                    inm.enqueueNotificationWithTag("android", "android", null,
1967                            R.string.dump_heap_notification,
1968                            notification, outId, userId);
1969                } catch (RuntimeException e) {
1970                    Slog.w(ActivityManagerService.TAG,
1971                            "Error showing notification for dump heap", e);
1972                } catch (RemoteException e) {
1973                }
1974            } break;
1975            case DELETE_DUMPHEAP_MSG: {
1976                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
1977                        DumpHeapActivity.JAVA_URI,
1978                        Intent.FLAG_GRANT_READ_URI_PERMISSION
1979                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
1980                        UserHandle.myUserId());
1981                synchronized (ActivityManagerService.this) {
1982                    mMemWatchDumpFile = null;
1983                    mMemWatchDumpProcName = null;
1984                    mMemWatchDumpPid = -1;
1985                    mMemWatchDumpUid = -1;
1986                }
1987            } break;
1988            case FOREGROUND_PROFILE_CHANGED_MSG: {
1989                dispatchForegroundProfileChanged(msg.arg1);
1990            } break;
1991            }
1992        }
1993    };
1994
1995    static final int COLLECT_PSS_BG_MSG = 1;
1996
1997    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1998        @Override
1999        public void handleMessage(Message msg) {
2000            switch (msg.what) {
2001            case COLLECT_PSS_BG_MSG: {
2002                long start = SystemClock.uptimeMillis();
2003                MemInfoReader memInfo = null;
2004                synchronized (ActivityManagerService.this) {
2005                    if (mFullPssPending) {
2006                        mFullPssPending = false;
2007                        memInfo = new MemInfoReader();
2008                    }
2009                }
2010                if (memInfo != null) {
2011                    updateCpuStatsNow();
2012                    long nativeTotalPss = 0;
2013                    synchronized (mProcessCpuTracker) {
2014                        final int N = mProcessCpuTracker.countStats();
2015                        for (int j=0; j<N; j++) {
2016                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2017                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2018                                // This is definitely an application process; skip it.
2019                                continue;
2020                            }
2021                            synchronized (mPidsSelfLocked) {
2022                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2023                                    // This is one of our own processes; skip it.
2024                                    continue;
2025                                }
2026                            }
2027                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2028                        }
2029                    }
2030                    memInfo.readMemInfo();
2031                    synchronized (ActivityManagerService.this) {
2032                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2033                                + (SystemClock.uptimeMillis()-start) + "ms");
2034                        final long cachedKb = memInfo.getCachedSizeKb();
2035                        final long freeKb = memInfo.getFreeSizeKb();
2036                        final long zramKb = memInfo.getZramTotalSizeKb();
2037                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2038                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2039                                kernelKb*1024, nativeTotalPss*1024);
2040                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2041                                nativeTotalPss);
2042                    }
2043                }
2044
2045                int num = 0;
2046                long[] tmp = new long[1];
2047                do {
2048                    ProcessRecord proc;
2049                    int procState;
2050                    int pid;
2051                    long lastPssTime;
2052                    synchronized (ActivityManagerService.this) {
2053                        if (mPendingPssProcesses.size() <= 0) {
2054                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2055                                    "Collected PSS of " + num + " processes in "
2056                                    + (SystemClock.uptimeMillis() - start) + "ms");
2057                            mPendingPssProcesses.clear();
2058                            return;
2059                        }
2060                        proc = mPendingPssProcesses.remove(0);
2061                        procState = proc.pssProcState;
2062                        lastPssTime = proc.lastPssTime;
2063                        if (proc.thread != null && procState == proc.setProcState
2064                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2065                                        < SystemClock.uptimeMillis()) {
2066                            pid = proc.pid;
2067                        } else {
2068                            proc = null;
2069                            pid = 0;
2070                        }
2071                    }
2072                    if (proc != null) {
2073                        long pss = Debug.getPss(pid, tmp, null);
2074                        synchronized (ActivityManagerService.this) {
2075                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2076                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2077                                num++;
2078                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2079                                        SystemClock.uptimeMillis());
2080                            }
2081                        }
2082                    }
2083                } while (true);
2084            }
2085            }
2086        }
2087    };
2088
2089    public void setSystemProcess() {
2090        try {
2091            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2092            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2093            ServiceManager.addService("meminfo", new MemBinder(this));
2094            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2095            ServiceManager.addService("dbinfo", new DbBinder(this));
2096            if (MONITOR_CPU_USAGE) {
2097                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2098            }
2099            ServiceManager.addService("permission", new PermissionController(this));
2100            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2101
2102            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2103                    "android", STOCK_PM_FLAGS);
2104            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2105
2106            synchronized (this) {
2107                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2108                app.persistent = true;
2109                app.pid = MY_PID;
2110                app.maxAdj = ProcessList.SYSTEM_ADJ;
2111                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2112                synchronized (mPidsSelfLocked) {
2113                    mPidsSelfLocked.put(app.pid, app);
2114                }
2115                updateLruProcessLocked(app, false, null);
2116                updateOomAdjLocked();
2117            }
2118        } catch (PackageManager.NameNotFoundException e) {
2119            throw new RuntimeException(
2120                    "Unable to find android system package", e);
2121        }
2122    }
2123
2124    public void setWindowManager(WindowManagerService wm) {
2125        mWindowManager = wm;
2126        mStackSupervisor.setWindowManager(wm);
2127    }
2128
2129    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2130        mUsageStatsService = usageStatsManager;
2131    }
2132
2133    public void startObservingNativeCrashes() {
2134        final NativeCrashListener ncl = new NativeCrashListener(this);
2135        ncl.start();
2136    }
2137
2138    public IAppOpsService getAppOpsService() {
2139        return mAppOpsService;
2140    }
2141
2142    static class MemBinder extends Binder {
2143        ActivityManagerService mActivityManagerService;
2144        MemBinder(ActivityManagerService activityManagerService) {
2145            mActivityManagerService = activityManagerService;
2146        }
2147
2148        @Override
2149        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2150            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2151                    != PackageManager.PERMISSION_GRANTED) {
2152                pw.println("Permission Denial: can't dump meminfo from from pid="
2153                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2154                        + " without permission " + android.Manifest.permission.DUMP);
2155                return;
2156            }
2157
2158            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2159        }
2160    }
2161
2162    static class GraphicsBinder extends Binder {
2163        ActivityManagerService mActivityManagerService;
2164        GraphicsBinder(ActivityManagerService activityManagerService) {
2165            mActivityManagerService = activityManagerService;
2166        }
2167
2168        @Override
2169        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2170            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2171                    != PackageManager.PERMISSION_GRANTED) {
2172                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2173                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2174                        + " without permission " + android.Manifest.permission.DUMP);
2175                return;
2176            }
2177
2178            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2179        }
2180    }
2181
2182    static class DbBinder extends Binder {
2183        ActivityManagerService mActivityManagerService;
2184        DbBinder(ActivityManagerService activityManagerService) {
2185            mActivityManagerService = activityManagerService;
2186        }
2187
2188        @Override
2189        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2190            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2191                    != PackageManager.PERMISSION_GRANTED) {
2192                pw.println("Permission Denial: can't dump dbinfo from from pid="
2193                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2194                        + " without permission " + android.Manifest.permission.DUMP);
2195                return;
2196            }
2197
2198            mActivityManagerService.dumpDbInfo(fd, pw, args);
2199        }
2200    }
2201
2202    static class CpuBinder extends Binder {
2203        ActivityManagerService mActivityManagerService;
2204        CpuBinder(ActivityManagerService activityManagerService) {
2205            mActivityManagerService = activityManagerService;
2206        }
2207
2208        @Override
2209        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2210            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2211                    != PackageManager.PERMISSION_GRANTED) {
2212                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2213                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2214                        + " without permission " + android.Manifest.permission.DUMP);
2215                return;
2216            }
2217
2218            synchronized (mActivityManagerService.mProcessCpuTracker) {
2219                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2220                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2221                        SystemClock.uptimeMillis()));
2222            }
2223        }
2224    }
2225
2226    public static final class Lifecycle extends SystemService {
2227        private final ActivityManagerService mService;
2228
2229        public Lifecycle(Context context) {
2230            super(context);
2231            mService = new ActivityManagerService(context);
2232        }
2233
2234        @Override
2235        public void onStart() {
2236            mService.start();
2237        }
2238
2239        public ActivityManagerService getService() {
2240            return mService;
2241        }
2242    }
2243
2244    // Note: This method is invoked on the main thread but may need to attach various
2245    // handlers to other threads.  So take care to be explicit about the looper.
2246    public ActivityManagerService(Context systemContext) {
2247        mContext = systemContext;
2248        mFactoryTest = FactoryTest.getMode();
2249        mSystemThread = ActivityThread.currentActivityThread();
2250
2251        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2252
2253        mHandlerThread = new ServiceThread(TAG,
2254                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2255        mHandlerThread.start();
2256        mHandler = new MainHandler(mHandlerThread.getLooper());
2257        mUiHandler = new UiHandler();
2258
2259        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2260                "foreground", BROADCAST_FG_TIMEOUT, false);
2261        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2262                "background", BROADCAST_BG_TIMEOUT, true);
2263        mBroadcastQueues[0] = mFgBroadcastQueue;
2264        mBroadcastQueues[1] = mBgBroadcastQueue;
2265
2266        mServices = new ActiveServices(this);
2267        mProviderMap = new ProviderMap(this);
2268
2269        // TODO: Move creation of battery stats service outside of activity manager service.
2270        File dataDir = Environment.getDataDirectory();
2271        File systemDir = new File(dataDir, "system");
2272        systemDir.mkdirs();
2273        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2274        mBatteryStatsService.getActiveStatistics().readLocked();
2275        mBatteryStatsService.scheduleWriteToDisk();
2276        mOnBattery = DEBUG_POWER ? true
2277                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2278        mBatteryStatsService.getActiveStatistics().setCallback(this);
2279
2280        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2281
2282        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2283
2284        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2285
2286        // User 0 is the first and only user that runs at boot.
2287        mStartedUsers.put(UserHandle.USER_OWNER, new UserStartedState(UserHandle.OWNER, true));
2288        mUserLru.add(UserHandle.USER_OWNER);
2289        updateStartedUserArrayLocked();
2290
2291        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2292            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2293
2294        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2295
2296        mConfiguration.setToDefaults();
2297        mConfiguration.setLocale(Locale.getDefault());
2298
2299        mConfigurationSeq = mConfiguration.seq = 1;
2300        mProcessCpuTracker.init();
2301
2302        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2303        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2304        mRecentTasks = new RecentTasks(this);
2305        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2306        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2307
2308        mProcessCpuThread = new Thread("CpuTracker") {
2309            @Override
2310            public void run() {
2311                while (true) {
2312                    try {
2313                        try {
2314                            synchronized(this) {
2315                                final long now = SystemClock.uptimeMillis();
2316                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2317                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2318                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2319                                //        + ", write delay=" + nextWriteDelay);
2320                                if (nextWriteDelay < nextCpuDelay) {
2321                                    nextCpuDelay = nextWriteDelay;
2322                                }
2323                                if (nextCpuDelay > 0) {
2324                                    mProcessCpuMutexFree.set(true);
2325                                    this.wait(nextCpuDelay);
2326                                }
2327                            }
2328                        } catch (InterruptedException e) {
2329                        }
2330                        updateCpuStatsNow();
2331                    } catch (Exception e) {
2332                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2333                    }
2334                }
2335            }
2336        };
2337
2338        Watchdog.getInstance().addMonitor(this);
2339        Watchdog.getInstance().addThread(mHandler);
2340    }
2341
2342    public void setSystemServiceManager(SystemServiceManager mgr) {
2343        mSystemServiceManager = mgr;
2344    }
2345
2346    public void setInstaller(Installer installer) {
2347        mInstaller = installer;
2348    }
2349
2350    private void start() {
2351        Process.removeAllProcessGroups();
2352        mProcessCpuThread.start();
2353
2354        mBatteryStatsService.publish(mContext);
2355        mAppOpsService.publish(mContext);
2356        Slog.d("AppOps", "AppOpsService published");
2357        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2358    }
2359
2360    public void initPowerManagement() {
2361        mStackSupervisor.initPowerManagement();
2362        mBatteryStatsService.initPowerManagement();
2363        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2364        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2365        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2366        mVoiceWakeLock.setReferenceCounted(false);
2367    }
2368
2369    @Override
2370    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2371            throws RemoteException {
2372        if (code == SYSPROPS_TRANSACTION) {
2373            // We need to tell all apps about the system property change.
2374            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2375            synchronized(this) {
2376                final int NP = mProcessNames.getMap().size();
2377                for (int ip=0; ip<NP; ip++) {
2378                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2379                    final int NA = apps.size();
2380                    for (int ia=0; ia<NA; ia++) {
2381                        ProcessRecord app = apps.valueAt(ia);
2382                        if (app.thread != null) {
2383                            procs.add(app.thread.asBinder());
2384                        }
2385                    }
2386                }
2387            }
2388
2389            int N = procs.size();
2390            for (int i=0; i<N; i++) {
2391                Parcel data2 = Parcel.obtain();
2392                try {
2393                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2394                } catch (RemoteException e) {
2395                }
2396                data2.recycle();
2397            }
2398        }
2399        try {
2400            return super.onTransact(code, data, reply, flags);
2401        } catch (RuntimeException e) {
2402            // The activity manager only throws security exceptions, so let's
2403            // log all others.
2404            if (!(e instanceof SecurityException)) {
2405                Slog.wtf(TAG, "Activity Manager Crash", e);
2406            }
2407            throw e;
2408        }
2409    }
2410
2411    void updateCpuStats() {
2412        final long now = SystemClock.uptimeMillis();
2413        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2414            return;
2415        }
2416        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2417            synchronized (mProcessCpuThread) {
2418                mProcessCpuThread.notify();
2419            }
2420        }
2421    }
2422
2423    void updateCpuStatsNow() {
2424        synchronized (mProcessCpuTracker) {
2425            mProcessCpuMutexFree.set(false);
2426            final long now = SystemClock.uptimeMillis();
2427            boolean haveNewCpuStats = false;
2428
2429            if (MONITOR_CPU_USAGE &&
2430                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2431                mLastCpuTime.set(now);
2432                mProcessCpuTracker.update();
2433                if (mProcessCpuTracker.hasGoodLastStats()) {
2434                    haveNewCpuStats = true;
2435                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2436                    //Slog.i(TAG, "Total CPU usage: "
2437                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2438
2439                    // Slog the cpu usage if the property is set.
2440                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2441                        int user = mProcessCpuTracker.getLastUserTime();
2442                        int system = mProcessCpuTracker.getLastSystemTime();
2443                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2444                        int irq = mProcessCpuTracker.getLastIrqTime();
2445                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2446                        int idle = mProcessCpuTracker.getLastIdleTime();
2447
2448                        int total = user + system + iowait + irq + softIrq + idle;
2449                        if (total == 0) total = 1;
2450
2451                        EventLog.writeEvent(EventLogTags.CPU,
2452                                ((user+system+iowait+irq+softIrq) * 100) / total,
2453                                (user * 100) / total,
2454                                (system * 100) / total,
2455                                (iowait * 100) / total,
2456                                (irq * 100) / total,
2457                                (softIrq * 100) / total);
2458                    }
2459                }
2460            }
2461
2462            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2463            synchronized(bstats) {
2464                synchronized(mPidsSelfLocked) {
2465                    if (haveNewCpuStats) {
2466                        final int perc = bstats.startAddingCpuLocked();
2467                        if (perc >= 0) {
2468                            int remainUTime = 0;
2469                            int remainSTime = 0;
2470                            int totalUTime = 0;
2471                            int totalSTime = 0;
2472                            final int N = mProcessCpuTracker.countStats();
2473                            for (int i=0; i<N; i++) {
2474                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2475                                if (!st.working) {
2476                                    continue;
2477                                }
2478                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2479                                int otherUTime = (st.rel_utime*perc)/100;
2480                                int otherSTime = (st.rel_stime*perc)/100;
2481                                remainUTime += otherUTime;
2482                                remainSTime += otherSTime;
2483                                totalUTime += st.rel_utime;
2484                                totalSTime += st.rel_stime;
2485                                if (pr != null) {
2486                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2487                                    if (ps == null || !ps.isActive()) {
2488                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2489                                                pr.info.uid, pr.processName);
2490                                    }
2491                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2492                                            st.rel_stime - otherSTime);
2493                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2494                                } else {
2495                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2496                                    if (ps == null || !ps.isActive()) {
2497                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2498                                                bstats.mapUid(st.uid), st.name);
2499                                    }
2500                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2501                                            st.rel_stime - otherSTime);
2502                                }
2503                            }
2504                            final int userTime = mProcessCpuTracker.getLastUserTime();
2505                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2506                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2507                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2508                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2509                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2510                            bstats.finishAddingCpuLocked(perc, remainUTime,
2511                                    remainSTime, totalUTime, totalSTime, userTime, systemTime,
2512                                    iowaitTime, irqTime, softIrqTime, idleTime);
2513                        }
2514                    }
2515                }
2516
2517                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2518                    mLastWriteTime = now;
2519                    mBatteryStatsService.scheduleWriteToDisk();
2520                }
2521            }
2522        }
2523    }
2524
2525    @Override
2526    public void batteryNeedsCpuUpdate() {
2527        updateCpuStatsNow();
2528    }
2529
2530    @Override
2531    public void batteryPowerChanged(boolean onBattery) {
2532        // When plugging in, update the CPU stats first before changing
2533        // the plug state.
2534        updateCpuStatsNow();
2535        synchronized (this) {
2536            synchronized(mPidsSelfLocked) {
2537                mOnBattery = DEBUG_POWER ? true : onBattery;
2538            }
2539        }
2540    }
2541
2542    @Override
2543    public void batterySendBroadcast(Intent intent) {
2544        broadcastIntentLocked(null, null, intent, null,
2545                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
2546                Process.SYSTEM_UID, UserHandle.USER_ALL);
2547    }
2548
2549    /**
2550     * Initialize the application bind args. These are passed to each
2551     * process when the bindApplication() IPC is sent to the process. They're
2552     * lazily setup to make sure the services are running when they're asked for.
2553     */
2554    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2555        if (mAppBindArgs == null) {
2556            mAppBindArgs = new HashMap<>();
2557
2558            // Isolated processes won't get this optimization, so that we don't
2559            // violate the rules about which services they have access to.
2560            if (!isolated) {
2561                // Setup the application init args
2562                mAppBindArgs.put("package", ServiceManager.getService("package"));
2563                mAppBindArgs.put("window", ServiceManager.getService("window"));
2564                mAppBindArgs.put(Context.ALARM_SERVICE,
2565                        ServiceManager.getService(Context.ALARM_SERVICE));
2566            }
2567        }
2568        return mAppBindArgs;
2569    }
2570
2571    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2572        if (r != null && mFocusedActivity != r) {
2573            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2574            ActivityRecord last = mFocusedActivity;
2575            mFocusedActivity = r;
2576            if (r.task != null && r.task.voiceInteractor != null) {
2577                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2578            } else {
2579                finishRunningVoiceLocked();
2580                if (last != null && last.task.voiceSession != null) {
2581                    // We had been in a voice interaction session, but now focused has
2582                    // move to something different.  Just finish the session, we can't
2583                    // return to it and retain the proper state and synchronization with
2584                    // the voice interaction service.
2585                    finishVoiceTask(last.task.voiceSession);
2586                }
2587            }
2588            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2589                mWindowManager.setFocusedApp(r.appToken, true);
2590            }
2591            applyUpdateLockStateLocked(r);
2592            if (mFocusedActivity.userId != mLastFocusedUserId) {
2593                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2594                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2595                        mFocusedActivity.userId, 0));
2596                mLastFocusedUserId = mFocusedActivity.userId;
2597            }
2598        }
2599        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2600                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2601                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2602    }
2603
2604    final void clearFocusedActivity(ActivityRecord r) {
2605        if (mFocusedActivity == r) {
2606            ActivityStack stack = mStackSupervisor.getFocusedStack();
2607            if (stack != null) {
2608                ActivityRecord top = stack.topActivity();
2609                if (top != null && top.userId != mLastFocusedUserId) {
2610                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2611                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2612                                    top.userId, 0));
2613                    mLastFocusedUserId = top.userId;
2614                }
2615            }
2616            mFocusedActivity = null;
2617            EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2618        }
2619    }
2620
2621    @Override
2622    public void setFocusedStack(int stackId) {
2623        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2624        synchronized (ActivityManagerService.this) {
2625            ActivityStack stack = mStackSupervisor.getStack(stackId);
2626            if (stack != null) {
2627                ActivityRecord r = stack.topRunningActivityLocked(null);
2628                if (r != null) {
2629                    setFocusedActivityLocked(r, "setFocusedStack");
2630                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2631                }
2632            }
2633        }
2634    }
2635
2636    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2637    @Override
2638    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2639        synchronized (ActivityManagerService.this) {
2640            if (listener != null) {
2641                mTaskStackListeners.register(listener);
2642            }
2643        }
2644    }
2645
2646    @Override
2647    public void notifyActivityDrawn(IBinder token) {
2648        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2649        synchronized (this) {
2650            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2651            if (r != null) {
2652                r.task.stack.notifyActivityDrawnLocked(r);
2653            }
2654        }
2655    }
2656
2657    final void applyUpdateLockStateLocked(ActivityRecord r) {
2658        // Modifications to the UpdateLock state are done on our handler, outside
2659        // the activity manager's locks.  The new state is determined based on the
2660        // state *now* of the relevant activity record.  The object is passed to
2661        // the handler solely for logging detail, not to be consulted/modified.
2662        final boolean nextState = r != null && r.immersive;
2663        mHandler.sendMessage(
2664                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2665    }
2666
2667    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2668        Message msg = Message.obtain();
2669        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2670        msg.obj = r.task.askedCompatMode ? null : r;
2671        mUiHandler.sendMessage(msg);
2672    }
2673
2674    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2675            String what, Object obj, ProcessRecord srcApp) {
2676        app.lastActivityTime = now;
2677
2678        if (app.activities.size() > 0) {
2679            // Don't want to touch dependent processes that are hosting activities.
2680            return index;
2681        }
2682
2683        int lrui = mLruProcesses.lastIndexOf(app);
2684        if (lrui < 0) {
2685            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2686                    + what + " " + obj + " from " + srcApp);
2687            return index;
2688        }
2689
2690        if (lrui >= index) {
2691            // Don't want to cause this to move dependent processes *back* in the
2692            // list as if they were less frequently used.
2693            return index;
2694        }
2695
2696        if (lrui >= mLruProcessActivityStart) {
2697            // Don't want to touch dependent processes that are hosting activities.
2698            return index;
2699        }
2700
2701        mLruProcesses.remove(lrui);
2702        if (index > 0) {
2703            index--;
2704        }
2705        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2706                + " in LRU list: " + app);
2707        mLruProcesses.add(index, app);
2708        return index;
2709    }
2710
2711    final void removeLruProcessLocked(ProcessRecord app) {
2712        int lrui = mLruProcesses.lastIndexOf(app);
2713        if (lrui >= 0) {
2714            if (!app.killed) {
2715                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2716                Process.killProcessQuiet(app.pid);
2717                Process.killProcessGroup(app.info.uid, app.pid);
2718            }
2719            if (lrui <= mLruProcessActivityStart) {
2720                mLruProcessActivityStart--;
2721            }
2722            if (lrui <= mLruProcessServiceStart) {
2723                mLruProcessServiceStart--;
2724            }
2725            mLruProcesses.remove(lrui);
2726        }
2727    }
2728
2729    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2730            ProcessRecord client) {
2731        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2732                || app.treatLikeActivity;
2733        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2734        if (!activityChange && hasActivity) {
2735            // The process has activities, so we are only allowing activity-based adjustments
2736            // to move it.  It should be kept in the front of the list with other
2737            // processes that have activities, and we don't want those to change their
2738            // order except due to activity operations.
2739            return;
2740        }
2741
2742        mLruSeq++;
2743        final long now = SystemClock.uptimeMillis();
2744        app.lastActivityTime = now;
2745
2746        // First a quick reject: if the app is already at the position we will
2747        // put it, then there is nothing to do.
2748        if (hasActivity) {
2749            final int N = mLruProcesses.size();
2750            if (N > 0 && mLruProcesses.get(N-1) == app) {
2751                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2752                return;
2753            }
2754        } else {
2755            if (mLruProcessServiceStart > 0
2756                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2757                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2758                return;
2759            }
2760        }
2761
2762        int lrui = mLruProcesses.lastIndexOf(app);
2763
2764        if (app.persistent && lrui >= 0) {
2765            // We don't care about the position of persistent processes, as long as
2766            // they are in the list.
2767            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2768            return;
2769        }
2770
2771        /* In progress: compute new position first, so we can avoid doing work
2772           if the process is not actually going to move.  Not yet working.
2773        int addIndex;
2774        int nextIndex;
2775        boolean inActivity = false, inService = false;
2776        if (hasActivity) {
2777            // Process has activities, put it at the very tipsy-top.
2778            addIndex = mLruProcesses.size();
2779            nextIndex = mLruProcessServiceStart;
2780            inActivity = true;
2781        } else if (hasService) {
2782            // Process has services, put it at the top of the service list.
2783            addIndex = mLruProcessActivityStart;
2784            nextIndex = mLruProcessServiceStart;
2785            inActivity = true;
2786            inService = true;
2787        } else  {
2788            // Process not otherwise of interest, it goes to the top of the non-service area.
2789            addIndex = mLruProcessServiceStart;
2790            if (client != null) {
2791                int clientIndex = mLruProcesses.lastIndexOf(client);
2792                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2793                        + app);
2794                if (clientIndex >= 0 && addIndex > clientIndex) {
2795                    addIndex = clientIndex;
2796                }
2797            }
2798            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2799        }
2800
2801        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2802                + mLruProcessActivityStart + "): " + app);
2803        */
2804
2805        if (lrui >= 0) {
2806            if (lrui < mLruProcessActivityStart) {
2807                mLruProcessActivityStart--;
2808            }
2809            if (lrui < mLruProcessServiceStart) {
2810                mLruProcessServiceStart--;
2811            }
2812            /*
2813            if (addIndex > lrui) {
2814                addIndex--;
2815            }
2816            if (nextIndex > lrui) {
2817                nextIndex--;
2818            }
2819            */
2820            mLruProcesses.remove(lrui);
2821        }
2822
2823        /*
2824        mLruProcesses.add(addIndex, app);
2825        if (inActivity) {
2826            mLruProcessActivityStart++;
2827        }
2828        if (inService) {
2829            mLruProcessActivityStart++;
2830        }
2831        */
2832
2833        int nextIndex;
2834        if (hasActivity) {
2835            final int N = mLruProcesses.size();
2836            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2837                // Process doesn't have activities, but has clients with
2838                // activities...  move it up, but one below the top (the top
2839                // should always have a real activity).
2840                if (DEBUG_LRU) Slog.d(TAG_LRU,
2841                        "Adding to second-top of LRU activity list: " + app);
2842                mLruProcesses.add(N - 1, app);
2843                // To keep it from spamming the LRU list (by making a bunch of clients),
2844                // we will push down any other entries owned by the app.
2845                final int uid = app.info.uid;
2846                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2847                    ProcessRecord subProc = mLruProcesses.get(i);
2848                    if (subProc.info.uid == uid) {
2849                        // We want to push this one down the list.  If the process after
2850                        // it is for the same uid, however, don't do so, because we don't
2851                        // want them internally to be re-ordered.
2852                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2853                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2854                                    "Pushing uid " + uid + " swapping at " + i + ": "
2855                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2856                            ProcessRecord tmp = mLruProcesses.get(i);
2857                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2858                            mLruProcesses.set(i - 1, tmp);
2859                            i--;
2860                        }
2861                    } else {
2862                        // A gap, we can stop here.
2863                        break;
2864                    }
2865                }
2866            } else {
2867                // Process has activities, put it at the very tipsy-top.
2868                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2869                mLruProcesses.add(app);
2870            }
2871            nextIndex = mLruProcessServiceStart;
2872        } else if (hasService) {
2873            // Process has services, put it at the top of the service list.
2874            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2875            mLruProcesses.add(mLruProcessActivityStart, app);
2876            nextIndex = mLruProcessServiceStart;
2877            mLruProcessActivityStart++;
2878        } else  {
2879            // Process not otherwise of interest, it goes to the top of the non-service area.
2880            int index = mLruProcessServiceStart;
2881            if (client != null) {
2882                // If there is a client, don't allow the process to be moved up higher
2883                // in the list than that client.
2884                int clientIndex = mLruProcesses.lastIndexOf(client);
2885                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2886                        + " when updating " + app);
2887                if (clientIndex <= lrui) {
2888                    // Don't allow the client index restriction to push it down farther in the
2889                    // list than it already is.
2890                    clientIndex = lrui;
2891                }
2892                if (clientIndex >= 0 && index > clientIndex) {
2893                    index = clientIndex;
2894                }
2895            }
2896            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2897            mLruProcesses.add(index, app);
2898            nextIndex = index-1;
2899            mLruProcessActivityStart++;
2900            mLruProcessServiceStart++;
2901        }
2902
2903        // If the app is currently using a content provider or service,
2904        // bump those processes as well.
2905        for (int j=app.connections.size()-1; j>=0; j--) {
2906            ConnectionRecord cr = app.connections.valueAt(j);
2907            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2908                    && cr.binding.service.app != null
2909                    && cr.binding.service.app.lruSeq != mLruSeq
2910                    && !cr.binding.service.app.persistent) {
2911                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2912                        "service connection", cr, app);
2913            }
2914        }
2915        for (int j=app.conProviders.size()-1; j>=0; j--) {
2916            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2917            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2918                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2919                        "provider reference", cpr, app);
2920            }
2921        }
2922    }
2923
2924    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2925        if (uid == Process.SYSTEM_UID) {
2926            // The system gets to run in any process.  If there are multiple
2927            // processes with the same uid, just pick the first (this
2928            // should never happen).
2929            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2930            if (procs == null) return null;
2931            final int N = procs.size();
2932            for (int i = 0; i < N; i++) {
2933                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2934            }
2935        }
2936        ProcessRecord proc = mProcessNames.get(processName, uid);
2937        if (false && proc != null && !keepIfLarge
2938                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2939                && proc.lastCachedPss >= 4000) {
2940            // Turn this condition on to cause killing to happen regularly, for testing.
2941            if (proc.baseProcessTracker != null) {
2942                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2943            }
2944            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2945        } else if (proc != null && !keepIfLarge
2946                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2947                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2948            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2949            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2950                if (proc.baseProcessTracker != null) {
2951                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2952                }
2953                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2954            }
2955        }
2956        return proc;
2957    }
2958
2959    void ensurePackageDexOpt(String packageName) {
2960        IPackageManager pm = AppGlobals.getPackageManager();
2961        try {
2962            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2963                mDidDexOpt = true;
2964            }
2965        } catch (RemoteException e) {
2966        }
2967    }
2968
2969    boolean isNextTransitionForward() {
2970        int transit = mWindowManager.getPendingAppTransition();
2971        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2972                || transit == AppTransition.TRANSIT_TASK_OPEN
2973                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2974    }
2975
2976    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2977            String processName, String abiOverride, int uid, Runnable crashHandler) {
2978        synchronized(this) {
2979            ApplicationInfo info = new ApplicationInfo();
2980            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2981            // For isolated processes, the former contains the parent's uid and the latter the
2982            // actual uid of the isolated process.
2983            // In the special case introduced by this method (which is, starting an isolated
2984            // process directly from the SystemServer without an actual parent app process) the
2985            // closest thing to a parent's uid is SYSTEM_UID.
2986            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2987            // the |isolated| logic in the ProcessRecord constructor.
2988            info.uid = Process.SYSTEM_UID;
2989            info.processName = processName;
2990            info.className = entryPoint;
2991            info.packageName = "android";
2992            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2993                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2994                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2995                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2996                    crashHandler);
2997            return proc != null ? proc.pid : 0;
2998        }
2999    }
3000
3001    final ProcessRecord startProcessLocked(String processName,
3002            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3003            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3004            boolean isolated, boolean keepIfLarge) {
3005        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3006                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3007                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3008                null /* crashHandler */);
3009    }
3010
3011    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3012            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3013            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3014            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3015        long startTime = SystemClock.elapsedRealtime();
3016        ProcessRecord app;
3017        if (!isolated) {
3018            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3019            checkTime(startTime, "startProcess: after getProcessRecord");
3020
3021            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3022                // If we are in the background, then check to see if this process
3023                // is bad.  If so, we will just silently fail.
3024                if (mBadProcesses.get(info.processName, info.uid) != null) {
3025                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3026                            + "/" + info.processName);
3027                    return null;
3028                }
3029            } else {
3030                // When the user is explicitly starting a process, then clear its
3031                // crash count so that we won't make it bad until they see at
3032                // least one crash dialog again, and make the process good again
3033                // if it had been bad.
3034                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3035                        + "/" + info.processName);
3036                mProcessCrashTimes.remove(info.processName, info.uid);
3037                if (mBadProcesses.get(info.processName, info.uid) != null) {
3038                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3039                            UserHandle.getUserId(info.uid), info.uid,
3040                            info.processName);
3041                    mBadProcesses.remove(info.processName, info.uid);
3042                    if (app != null) {
3043                        app.bad = false;
3044                    }
3045                }
3046            }
3047        } else {
3048            // If this is an isolated process, it can't re-use an existing process.
3049            app = null;
3050        }
3051
3052        // We don't have to do anything more if:
3053        // (1) There is an existing application record; and
3054        // (2) The caller doesn't think it is dead, OR there is no thread
3055        //     object attached to it so we know it couldn't have crashed; and
3056        // (3) There is a pid assigned to it, so it is either starting or
3057        //     already running.
3058        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3059                + " app=" + app + " knownToBeDead=" + knownToBeDead
3060                + " thread=" + (app != null ? app.thread : null)
3061                + " pid=" + (app != null ? app.pid : -1));
3062        if (app != null && app.pid > 0) {
3063            if (!knownToBeDead || app.thread == null) {
3064                // We already have the app running, or are waiting for it to
3065                // come up (we have a pid but not yet its thread), so keep it.
3066                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3067                // If this is a new package in the process, add the package to the list
3068                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3069                checkTime(startTime, "startProcess: done, added package to proc");
3070                return app;
3071            }
3072
3073            // An application record is attached to a previous process,
3074            // clean it up now.
3075            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3076            checkTime(startTime, "startProcess: bad proc running, killing");
3077            Process.killProcessGroup(app.info.uid, app.pid);
3078            handleAppDiedLocked(app, true, true);
3079            checkTime(startTime, "startProcess: done killing old proc");
3080        }
3081
3082        String hostingNameStr = hostingName != null
3083                ? hostingName.flattenToShortString() : null;
3084
3085        if (app == null) {
3086            checkTime(startTime, "startProcess: creating new process record");
3087            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3088            if (app == null) {
3089                Slog.w(TAG, "Failed making new process record for "
3090                        + processName + "/" + info.uid + " isolated=" + isolated);
3091                return null;
3092            }
3093            app.crashHandler = crashHandler;
3094            checkTime(startTime, "startProcess: done creating new process record");
3095        } else {
3096            // If this is a new package in the process, add the package to the list
3097            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3098            checkTime(startTime, "startProcess: added package to existing proc");
3099        }
3100
3101        // If the system is not ready yet, then hold off on starting this
3102        // process until it is.
3103        if (!mProcessesReady
3104                && !isAllowedWhileBooting(info)
3105                && !allowWhileBooting) {
3106            if (!mProcessesOnHold.contains(app)) {
3107                mProcessesOnHold.add(app);
3108            }
3109            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3110                    "System not ready, putting on hold: " + app);
3111            checkTime(startTime, "startProcess: returning with proc on hold");
3112            return app;
3113        }
3114
3115        checkTime(startTime, "startProcess: stepping in to startProcess");
3116        startProcessLocked(
3117                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3118        checkTime(startTime, "startProcess: done starting proc!");
3119        return (app.pid != 0) ? app : null;
3120    }
3121
3122    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3123        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3124    }
3125
3126    private final void startProcessLocked(ProcessRecord app,
3127            String hostingType, String hostingNameStr) {
3128        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3129                null /* entryPoint */, null /* entryPointArgs */);
3130    }
3131
3132    private final void startProcessLocked(ProcessRecord app, String hostingType,
3133            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3134        long startTime = SystemClock.elapsedRealtime();
3135        if (app.pid > 0 && app.pid != MY_PID) {
3136            checkTime(startTime, "startProcess: removing from pids map");
3137            synchronized (mPidsSelfLocked) {
3138                mPidsSelfLocked.remove(app.pid);
3139                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3140            }
3141            checkTime(startTime, "startProcess: done removing from pids map");
3142            app.setPid(0);
3143        }
3144
3145        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3146                "startProcessLocked removing on hold: " + app);
3147        mProcessesOnHold.remove(app);
3148
3149        checkTime(startTime, "startProcess: starting to update cpu stats");
3150        updateCpuStats();
3151        checkTime(startTime, "startProcess: done updating cpu stats");
3152
3153        try {
3154            try {
3155                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3156                    // This is caught below as if we had failed to fork zygote
3157                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3158                }
3159            } catch (RemoteException e) {
3160                throw e.rethrowAsRuntimeException();
3161            }
3162
3163            int uid = app.uid;
3164            int[] gids = null;
3165            int mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
3166            if (!app.isolated) {
3167                int[] permGids = null;
3168                try {
3169                    checkTime(startTime, "startProcess: getting gids from package manager");
3170                    permGids = AppGlobals.getPackageManager().getPackageGids(app.info.packageName,
3171                            app.userId);
3172                } catch (RemoteException e) {
3173                    throw e.rethrowAsRuntimeException();
3174                }
3175
3176                /*
3177                 * Add shared application and profile GIDs so applications can share some
3178                 * resources like shared libraries and access user-wide resources
3179                 */
3180                if (ArrayUtils.isEmpty(permGids)) {
3181                    gids = new int[2];
3182                } else {
3183                    gids = new int[permGids.length + 2];
3184                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3185                }
3186                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3187                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3188            }
3189            checkTime(startTime, "startProcess: building args");
3190            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3191                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3192                        && mTopComponent != null
3193                        && app.processName.equals(mTopComponent.getPackageName())) {
3194                    uid = 0;
3195                }
3196                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3197                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3198                    uid = 0;
3199                }
3200            }
3201            int debugFlags = 0;
3202            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3203                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3204                // Also turn on CheckJNI for debuggable apps. It's quite
3205                // awkward to turn on otherwise.
3206                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3207            }
3208            // Run the app in safe mode if its manifest requests so or the
3209            // system is booted in safe mode.
3210            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3211                mSafeMode == true) {
3212                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3213            }
3214            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3215                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3216            }
3217            String jitDebugProperty = SystemProperties.get("debug.usejit");
3218            if ("true".equals(jitDebugProperty)) {
3219                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3220            } else if (!"false".equals(jitDebugProperty)) {
3221                // If we didn't force disable by setting false, defer to the dalvik vm options.
3222                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3223                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3224                }
3225            }
3226            String genCFIDebugProperty = SystemProperties.get("debug.gencfi");
3227            if ("true".equals(genCFIDebugProperty)) {
3228                debugFlags |= Zygote.DEBUG_GENERATE_CFI;
3229            }
3230            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3231                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3232            }
3233            if ("1".equals(SystemProperties.get("debug.assert"))) {
3234                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3235            }
3236
3237            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3238            if (requiredAbi == null) {
3239                requiredAbi = Build.SUPPORTED_ABIS[0];
3240            }
3241
3242            String instructionSet = null;
3243            if (app.info.primaryCpuAbi != null) {
3244                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3245            }
3246
3247            app.gids = gids;
3248            app.requiredAbi = requiredAbi;
3249            app.instructionSet = instructionSet;
3250
3251            // Start the process.  It will either succeed and return a result containing
3252            // the PID of the new process, or else throw a RuntimeException.
3253            boolean isActivityProcess = (entryPoint == null);
3254            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3255            checkTime(startTime, "startProcess: asking zygote to start proc");
3256            Process.ProcessStartResult startResult = Process.start(entryPoint,
3257                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3258                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3259                    app.info.dataDir, entryPointArgs);
3260            checkTime(startTime, "startProcess: returned from zygote!");
3261
3262            if (app.isolated) {
3263                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3264            }
3265            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3266            checkTime(startTime, "startProcess: done updating battery stats");
3267
3268            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3269                    UserHandle.getUserId(uid), startResult.pid, uid,
3270                    app.processName, hostingType,
3271                    hostingNameStr != null ? hostingNameStr : "");
3272
3273            if (app.persistent) {
3274                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3275            }
3276
3277            checkTime(startTime, "startProcess: building log message");
3278            StringBuilder buf = mStringBuilder;
3279            buf.setLength(0);
3280            buf.append("Start proc ");
3281            buf.append(startResult.pid);
3282            buf.append(':');
3283            buf.append(app.processName);
3284            buf.append('/');
3285            UserHandle.formatUid(buf, uid);
3286            if (!isActivityProcess) {
3287                buf.append(" [");
3288                buf.append(entryPoint);
3289                buf.append("]");
3290            }
3291            buf.append(" for ");
3292            buf.append(hostingType);
3293            if (hostingNameStr != null) {
3294                buf.append(" ");
3295                buf.append(hostingNameStr);
3296            }
3297            Slog.i(TAG, buf.toString());
3298            app.setPid(startResult.pid);
3299            app.usingWrapper = startResult.usingWrapper;
3300            app.removed = false;
3301            app.killed = false;
3302            app.killedByAm = false;
3303            checkTime(startTime, "startProcess: starting to update pids map");
3304            synchronized (mPidsSelfLocked) {
3305                this.mPidsSelfLocked.put(startResult.pid, app);
3306                if (isActivityProcess) {
3307                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3308                    msg.obj = app;
3309                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3310                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3311                }
3312            }
3313            checkTime(startTime, "startProcess: done updating pids map");
3314        } catch (RuntimeException e) {
3315            // XXX do better error recovery.
3316            app.setPid(0);
3317            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3318            if (app.isolated) {
3319                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3320            }
3321            Slog.e(TAG, "Failure starting process " + app.processName, e);
3322        }
3323    }
3324
3325    void updateUsageStats(ActivityRecord component, boolean resumed) {
3326        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3327                "updateUsageStats: comp=" + component + "res=" + resumed);
3328        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3329        if (resumed) {
3330            if (mUsageStatsService != null) {
3331                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3332                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3333            }
3334            synchronized (stats) {
3335                stats.noteActivityResumedLocked(component.app.uid);
3336            }
3337        } else {
3338            if (mUsageStatsService != null) {
3339                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3340                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3341            }
3342            synchronized (stats) {
3343                stats.noteActivityPausedLocked(component.app.uid);
3344            }
3345        }
3346    }
3347
3348    Intent getHomeIntent() {
3349        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3350        intent.setComponent(mTopComponent);
3351        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3352            intent.addCategory(Intent.CATEGORY_HOME);
3353        }
3354        return intent;
3355    }
3356
3357    boolean startHomeActivityLocked(int userId, String reason) {
3358        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3359                && mTopAction == null) {
3360            // We are running in factory test mode, but unable to find
3361            // the factory test app, so just sit around displaying the
3362            // error message and don't try to start anything.
3363            return false;
3364        }
3365        Intent intent = getHomeIntent();
3366        ActivityInfo aInfo =
3367            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3368        if (aInfo != null) {
3369            intent.setComponent(new ComponentName(
3370                    aInfo.applicationInfo.packageName, aInfo.name));
3371            // Don't do this if the home app is currently being
3372            // instrumented.
3373            aInfo = new ActivityInfo(aInfo);
3374            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3375            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3376                    aInfo.applicationInfo.uid, true);
3377            if (app == null || app.instrumentationClass == null) {
3378                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3379                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3380            }
3381        }
3382
3383        return true;
3384    }
3385
3386    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3387        ActivityInfo ai = null;
3388        ComponentName comp = intent.getComponent();
3389        try {
3390            if (comp != null) {
3391                // Factory test.
3392                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3393            } else {
3394                ComponentName preferredComponent = mPreferredSetupActivities.get(userId);
3395                if (preferredComponent != null) {
3396                    ai = AppGlobals.getPackageManager().getActivityInfo(
3397                            preferredComponent, flags, userId);
3398                } else {
3399                    ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3400                            intent,
3401                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3402                                flags, userId);
3403
3404                    if (info != null) {
3405                        ai = info.activityInfo;
3406                    }
3407                }
3408            }
3409        } catch (RemoteException e) {
3410            // ignore
3411        }
3412
3413        return ai;
3414    }
3415
3416    /**
3417     * Starts the "new version setup screen" if appropriate.
3418     */
3419    void startSetupActivityLocked() {
3420        // Only do this once per boot.
3421        if (mCheckedForSetup) {
3422            return;
3423        }
3424
3425        // We will show this screen if the current one is a different
3426        // version than the last one shown, and we are not running in
3427        // low-level factory test mode.
3428        final ContentResolver resolver = mContext.getContentResolver();
3429        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3430                Settings.Global.getInt(resolver,
3431                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3432            mCheckedForSetup = true;
3433
3434            // See if we should be showing the platform update setup UI.
3435            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3436            List<ResolveInfo> ris = mContext.getPackageManager()
3437                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3438
3439            // We don't allow third party apps to replace this.
3440            ResolveInfo ri = null;
3441            for (int i=0; ris != null && i<ris.size(); i++) {
3442                if ((ris.get(i).activityInfo.applicationInfo.flags
3443                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3444                    ri = ris.get(i);
3445                    break;
3446                }
3447            }
3448
3449            if (ri != null) {
3450                String vers = ri.activityInfo.metaData != null
3451                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3452                        : null;
3453                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3454                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3455                            Intent.METADATA_SETUP_VERSION);
3456                }
3457                String lastVers = Settings.Secure.getString(
3458                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3459                if (vers != null && !vers.equals(lastVers)) {
3460                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3461                    intent.setComponent(new ComponentName(
3462                            ri.activityInfo.packageName, ri.activityInfo.name));
3463                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3464                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3465                            null);
3466                }
3467            }
3468        }
3469    }
3470
3471    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3472        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3473    }
3474
3475    void enforceNotIsolatedCaller(String caller) {
3476        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3477            throw new SecurityException("Isolated process not allowed to call " + caller);
3478        }
3479    }
3480
3481    void enforceShellRestriction(String restriction, int userHandle) {
3482        if (Binder.getCallingUid() == Process.SHELL_UID) {
3483            if (userHandle < 0
3484                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3485                throw new SecurityException("Shell does not have permission to access user "
3486                        + userHandle);
3487            }
3488        }
3489    }
3490
3491    @Override
3492    public int getFrontActivityScreenCompatMode() {
3493        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3494        synchronized (this) {
3495            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3496        }
3497    }
3498
3499    @Override
3500    public void setFrontActivityScreenCompatMode(int mode) {
3501        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3502                "setFrontActivityScreenCompatMode");
3503        synchronized (this) {
3504            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3505        }
3506    }
3507
3508    @Override
3509    public int getPackageScreenCompatMode(String packageName) {
3510        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3511        synchronized (this) {
3512            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3513        }
3514    }
3515
3516    @Override
3517    public void setPackageScreenCompatMode(String packageName, int mode) {
3518        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3519                "setPackageScreenCompatMode");
3520        synchronized (this) {
3521            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3522        }
3523    }
3524
3525    @Override
3526    public boolean getPackageAskScreenCompat(String packageName) {
3527        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3528        synchronized (this) {
3529            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3530        }
3531    }
3532
3533    @Override
3534    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3535        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3536                "setPackageAskScreenCompat");
3537        synchronized (this) {
3538            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3539        }
3540    }
3541
3542    @Override
3543    public int getPackageProcessState(String packageName) {
3544        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3545        synchronized (this) {
3546            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3547                final ProcessRecord proc = mLruProcesses.get(i);
3548                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3549                        || procState > proc.setProcState) {
3550                    boolean found = false;
3551                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3552                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3553                            procState = proc.setProcState;
3554                            found = true;
3555                        }
3556                    }
3557                    if (proc.pkgDeps != null && !found) {
3558                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3559                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3560                                procState = proc.setProcState;
3561                                break;
3562                            }
3563                        }
3564                    }
3565                }
3566            }
3567        }
3568        return procState;
3569    }
3570
3571    private void dispatchProcessesChanged() {
3572        int N;
3573        synchronized (this) {
3574            N = mPendingProcessChanges.size();
3575            if (mActiveProcessChanges.length < N) {
3576                mActiveProcessChanges = new ProcessChangeItem[N];
3577            }
3578            mPendingProcessChanges.toArray(mActiveProcessChanges);
3579            mPendingProcessChanges.clear();
3580            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3581                    "*** Delivering " + N + " process changes");
3582        }
3583
3584        int i = mProcessObservers.beginBroadcast();
3585        while (i > 0) {
3586            i--;
3587            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3588            if (observer != null) {
3589                try {
3590                    for (int j=0; j<N; j++) {
3591                        ProcessChangeItem item = mActiveProcessChanges[j];
3592                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3593                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3594                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3595                                    + item.uid + ": " + item.foregroundActivities);
3596                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3597                                    item.foregroundActivities);
3598                        }
3599                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3600                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3601                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3602                                    + ": " + item.processState);
3603                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3604                        }
3605                    }
3606                } catch (RemoteException e) {
3607                }
3608            }
3609        }
3610        mProcessObservers.finishBroadcast();
3611
3612        synchronized (this) {
3613            for (int j=0; j<N; j++) {
3614                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3615            }
3616        }
3617    }
3618
3619    private void dispatchProcessDied(int pid, int uid) {
3620        int i = mProcessObservers.beginBroadcast();
3621        while (i > 0) {
3622            i--;
3623            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3624            if (observer != null) {
3625                try {
3626                    observer.onProcessDied(pid, uid);
3627                } catch (RemoteException e) {
3628                }
3629            }
3630        }
3631        mProcessObservers.finishBroadcast();
3632    }
3633
3634    private void dispatchUidsChanged() {
3635        int N;
3636        synchronized (this) {
3637            N = mPendingUidChanges.size();
3638            if (mActiveUidChanges.length < N) {
3639                mActiveUidChanges = new UidRecord.ChangeItem[N];
3640            }
3641            for (int i=0; i<N; i++) {
3642                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3643                mActiveUidChanges[i] = change;
3644                change.uidRecord.pendingChange = null;
3645                change.uidRecord = null;
3646            }
3647            mPendingUidChanges.clear();
3648            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3649                    "*** Delivering " + N + " uid changes");
3650        }
3651
3652        if (mLocalPowerManager != null) {
3653            for (int j=0; j<N; j++) {
3654                UidRecord.ChangeItem item = mActiveUidChanges[j];
3655                if (item.gone) {
3656                    mLocalPowerManager.uidGone(item.uid);
3657                } else {
3658                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3659                }
3660            }
3661        }
3662
3663        int i = mUidObservers.beginBroadcast();
3664        while (i > 0) {
3665            i--;
3666            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3667            if (observer != null) {
3668                try {
3669                    for (int j=0; j<N; j++) {
3670                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3671                        if (item.gone) {
3672                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3673                                    "UID gone uid=" + item.uid);
3674                            observer.onUidGone(item.uid);
3675                        } else {
3676                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3677                                    "UID CHANGED uid=" + item.uid
3678                                    + ": " + item.processState);
3679                            observer.onUidStateChanged(item.uid, item.processState);
3680                        }
3681                    }
3682                } catch (RemoteException e) {
3683                }
3684            }
3685        }
3686        mUidObservers.finishBroadcast();
3687
3688        synchronized (this) {
3689            for (int j=0; j<N; j++) {
3690                mAvailUidChanges.add(mActiveUidChanges[j]);
3691            }
3692        }
3693    }
3694
3695    @Override
3696    public final int startActivity(IApplicationThread caller, String callingPackage,
3697            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3698            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3699        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3700            resultWho, requestCode, startFlags, profilerInfo, options,
3701            UserHandle.getCallingUserId());
3702    }
3703
3704    @Override
3705    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3706            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3707            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3708        enforceNotIsolatedCaller("startActivity");
3709        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3710                false, ALLOW_FULL_ONLY, "startActivity", null);
3711        // TODO: Switch to user app stacks here.
3712        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3713                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3714                profilerInfo, null, null, options, userId, null, null);
3715    }
3716
3717    @Override
3718    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3719            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3720            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3721
3722        // This is very dangerous -- it allows you to perform a start activity (including
3723        // permission grants) as any app that may launch one of your own activities.  So
3724        // we will only allow this to be done from activities that are part of the core framework,
3725        // and then only when they are running as the system.
3726        final ActivityRecord sourceRecord;
3727        final int targetUid;
3728        final String targetPackage;
3729        synchronized (this) {
3730            if (resultTo == null) {
3731                throw new SecurityException("Must be called from an activity");
3732            }
3733            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3734            if (sourceRecord == null) {
3735                throw new SecurityException("Called with bad activity token: " + resultTo);
3736            }
3737            if (!sourceRecord.info.packageName.equals("android")) {
3738                throw new SecurityException(
3739                        "Must be called from an activity that is declared in the android package");
3740            }
3741            if (sourceRecord.app == null) {
3742                throw new SecurityException("Called without a process attached to activity");
3743            }
3744            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3745                // This is still okay, as long as this activity is running under the
3746                // uid of the original calling activity.
3747                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3748                    throw new SecurityException(
3749                            "Calling activity in uid " + sourceRecord.app.uid
3750                                    + " must be system uid or original calling uid "
3751                                    + sourceRecord.launchedFromUid);
3752                }
3753            }
3754            targetUid = sourceRecord.launchedFromUid;
3755            targetPackage = sourceRecord.launchedFromPackage;
3756        }
3757
3758        if (userId == UserHandle.USER_NULL) {
3759            userId = UserHandle.getUserId(sourceRecord.app.uid);
3760        }
3761
3762        // TODO: Switch to user app stacks here.
3763        try {
3764            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3765                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3766                    null, null, options, userId, null, null);
3767            return ret;
3768        } catch (SecurityException e) {
3769            // XXX need to figure out how to propagate to original app.
3770            // A SecurityException here is generally actually a fault of the original
3771            // calling activity (such as a fairly granting permissions), so propagate it
3772            // back to them.
3773            /*
3774            StringBuilder msg = new StringBuilder();
3775            msg.append("While launching");
3776            msg.append(intent.toString());
3777            msg.append(": ");
3778            msg.append(e.getMessage());
3779            */
3780            throw e;
3781        }
3782    }
3783
3784    @Override
3785    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3786            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3787            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3788        enforceNotIsolatedCaller("startActivityAndWait");
3789        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3790                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3791        WaitResult res = new WaitResult();
3792        // TODO: Switch to user app stacks here.
3793        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3794                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3795                options, userId, null, null);
3796        return res;
3797    }
3798
3799    @Override
3800    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3801            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3802            int startFlags, Configuration config, Bundle options, int userId) {
3803        enforceNotIsolatedCaller("startActivityWithConfig");
3804        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3805                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3806        // TODO: Switch to user app stacks here.
3807        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3808                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3809                null, null, config, options, userId, null, null);
3810        return ret;
3811    }
3812
3813    @Override
3814    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3815            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3816            int requestCode, int flagsMask, int flagsValues, Bundle options)
3817            throws TransactionTooLargeException {
3818        enforceNotIsolatedCaller("startActivityIntentSender");
3819        // Refuse possible leaked file descriptors
3820        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3821            throw new IllegalArgumentException("File descriptors passed in Intent");
3822        }
3823
3824        IIntentSender sender = intent.getTarget();
3825        if (!(sender instanceof PendingIntentRecord)) {
3826            throw new IllegalArgumentException("Bad PendingIntent object");
3827        }
3828
3829        PendingIntentRecord pir = (PendingIntentRecord)sender;
3830
3831        synchronized (this) {
3832            // If this is coming from the currently resumed activity, it is
3833            // effectively saying that app switches are allowed at this point.
3834            final ActivityStack stack = getFocusedStack();
3835            if (stack.mResumedActivity != null &&
3836                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3837                mAppSwitchesAllowedTime = 0;
3838            }
3839        }
3840        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3841                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3842        return ret;
3843    }
3844
3845    @Override
3846    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3847            Intent intent, String resolvedType, IVoiceInteractionSession session,
3848            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3849            Bundle options, int userId) {
3850        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3851                != PackageManager.PERMISSION_GRANTED) {
3852            String msg = "Permission Denial: startVoiceActivity() from pid="
3853                    + Binder.getCallingPid()
3854                    + ", uid=" + Binder.getCallingUid()
3855                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3856            Slog.w(TAG, msg);
3857            throw new SecurityException(msg);
3858        }
3859        if (session == null || interactor == null) {
3860            throw new NullPointerException("null session or interactor");
3861        }
3862        userId = handleIncomingUser(callingPid, callingUid, userId,
3863                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3864        // TODO: Switch to user app stacks here.
3865        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3866                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3867                null, options, userId, null, null);
3868    }
3869
3870    @Override
3871    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3872        synchronized (this) {
3873            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3874                if (keepAwake) {
3875                    mVoiceWakeLock.acquire();
3876                } else {
3877                    mVoiceWakeLock.release();
3878                }
3879            }
3880        }
3881    }
3882
3883    @Override
3884    public boolean startNextMatchingActivity(IBinder callingActivity,
3885            Intent intent, Bundle options) {
3886        // Refuse possible leaked file descriptors
3887        if (intent != null && intent.hasFileDescriptors() == true) {
3888            throw new IllegalArgumentException("File descriptors passed in Intent");
3889        }
3890
3891        synchronized (this) {
3892            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3893            if (r == null) {
3894                ActivityOptions.abort(options);
3895                return false;
3896            }
3897            if (r.app == null || r.app.thread == null) {
3898                // The caller is not running...  d'oh!
3899                ActivityOptions.abort(options);
3900                return false;
3901            }
3902            intent = new Intent(intent);
3903            // The caller is not allowed to change the data.
3904            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3905            // And we are resetting to find the next component...
3906            intent.setComponent(null);
3907
3908            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3909
3910            ActivityInfo aInfo = null;
3911            try {
3912                List<ResolveInfo> resolves =
3913                    AppGlobals.getPackageManager().queryIntentActivities(
3914                            intent, r.resolvedType,
3915                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3916                            UserHandle.getCallingUserId());
3917
3918                // Look for the original activity in the list...
3919                final int N = resolves != null ? resolves.size() : 0;
3920                for (int i=0; i<N; i++) {
3921                    ResolveInfo rInfo = resolves.get(i);
3922                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3923                            && rInfo.activityInfo.name.equals(r.info.name)) {
3924                        // We found the current one...  the next matching is
3925                        // after it.
3926                        i++;
3927                        if (i<N) {
3928                            aInfo = resolves.get(i).activityInfo;
3929                        }
3930                        if (debug) {
3931                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3932                                    + "/" + r.info.name);
3933                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3934                                    + "/" + aInfo.name);
3935                        }
3936                        break;
3937                    }
3938                }
3939            } catch (RemoteException e) {
3940            }
3941
3942            if (aInfo == null) {
3943                // Nobody who is next!
3944                ActivityOptions.abort(options);
3945                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3946                return false;
3947            }
3948
3949            intent.setComponent(new ComponentName(
3950                    aInfo.applicationInfo.packageName, aInfo.name));
3951            intent.setFlags(intent.getFlags()&~(
3952                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3953                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3954                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3955                    Intent.FLAG_ACTIVITY_NEW_TASK));
3956
3957            // Okay now we need to start the new activity, replacing the
3958            // currently running activity.  This is a little tricky because
3959            // we want to start the new one as if the current one is finished,
3960            // but not finish the current one first so that there is no flicker.
3961            // And thus...
3962            final boolean wasFinishing = r.finishing;
3963            r.finishing = true;
3964
3965            // Propagate reply information over to the new activity.
3966            final ActivityRecord resultTo = r.resultTo;
3967            final String resultWho = r.resultWho;
3968            final int requestCode = r.requestCode;
3969            r.resultTo = null;
3970            if (resultTo != null) {
3971                resultTo.removeResultsLocked(r, resultWho, requestCode);
3972            }
3973
3974            final long origId = Binder.clearCallingIdentity();
3975            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3976                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3977                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3978                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3979            Binder.restoreCallingIdentity(origId);
3980
3981            r.finishing = wasFinishing;
3982            if (res != ActivityManager.START_SUCCESS) {
3983                return false;
3984            }
3985            return true;
3986        }
3987    }
3988
3989    @Override
3990    public final int startActivityFromRecents(int taskId, Bundle options) {
3991        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3992            String msg = "Permission Denial: startActivityFromRecents called without " +
3993                    START_TASKS_FROM_RECENTS;
3994            Slog.w(TAG, msg);
3995            throw new SecurityException(msg);
3996        }
3997        return startActivityFromRecentsInner(taskId, options);
3998    }
3999
4000    final int startActivityFromRecentsInner(int taskId, Bundle options) {
4001        final TaskRecord task;
4002        final int callingUid;
4003        final String callingPackage;
4004        final Intent intent;
4005        final int userId;
4006        synchronized (this) {
4007            task = mRecentTasks.taskForIdLocked(taskId);
4008            if (task == null) {
4009                throw new IllegalArgumentException("Task " + taskId + " not found.");
4010            }
4011            if (task.getRootActivity() != null) {
4012                moveTaskToFrontLocked(task.taskId, 0, null);
4013                return ActivityManager.START_TASK_TO_FRONT;
4014            }
4015            callingUid = task.mCallingUid;
4016            callingPackage = task.mCallingPackage;
4017            intent = task.intent;
4018            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4019            userId = task.userId;
4020        }
4021        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4022                options, userId, null, task);
4023    }
4024
4025    final int startActivityInPackage(int uid, String callingPackage,
4026            Intent intent, String resolvedType, IBinder resultTo,
4027            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4028            IActivityContainer container, TaskRecord inTask) {
4029
4030        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4031                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4032
4033        // TODO: Switch to user app stacks here.
4034        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4035                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4036                null, null, null, options, userId, container, inTask);
4037        return ret;
4038    }
4039
4040    @Override
4041    public final int startActivities(IApplicationThread caller, String callingPackage,
4042            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4043            int userId) {
4044        enforceNotIsolatedCaller("startActivities");
4045        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4046                false, ALLOW_FULL_ONLY, "startActivity", null);
4047        // TODO: Switch to user app stacks here.
4048        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4049                resolvedTypes, resultTo, options, userId);
4050        return ret;
4051    }
4052
4053    final int startActivitiesInPackage(int uid, String callingPackage,
4054            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4055            Bundle options, int userId) {
4056
4057        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4058                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4059        // TODO: Switch to user app stacks here.
4060        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4061                resultTo, options, userId);
4062        return ret;
4063    }
4064
4065    @Override
4066    public void reportActivityFullyDrawn(IBinder token) {
4067        synchronized (this) {
4068            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4069            if (r == null) {
4070                return;
4071            }
4072            r.reportFullyDrawnLocked();
4073        }
4074    }
4075
4076    @Override
4077    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4078        synchronized (this) {
4079            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4080            if (r == null) {
4081                return;
4082            }
4083            if (r.task != null && r.task.mResizeable) {
4084                // Fixed screen orientation isn't supported with resizeable activities.
4085                return;
4086            }
4087            final long origId = Binder.clearCallingIdentity();
4088            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4089            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4090                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4091            if (config != null) {
4092                r.frozenBeforeDestroy = true;
4093                if (!updateConfigurationLocked(config, r, false, false)) {
4094                    mStackSupervisor.resumeTopActivitiesLocked();
4095                }
4096            }
4097            Binder.restoreCallingIdentity(origId);
4098        }
4099    }
4100
4101    @Override
4102    public int getRequestedOrientation(IBinder token) {
4103        synchronized (this) {
4104            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4105            if (r == null) {
4106                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4107            }
4108            return mWindowManager.getAppOrientation(r.appToken);
4109        }
4110    }
4111
4112    /**
4113     * This is the internal entry point for handling Activity.finish().
4114     *
4115     * @param token The Binder token referencing the Activity we want to finish.
4116     * @param resultCode Result code, if any, from this Activity.
4117     * @param resultData Result data (Intent), if any, from this Activity.
4118     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4119     *            the root Activity in the task.
4120     *
4121     * @return Returns true if the activity successfully finished, or false if it is still running.
4122     */
4123    @Override
4124    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4125            boolean finishTask) {
4126        // Refuse possible leaked file descriptors
4127        if (resultData != null && resultData.hasFileDescriptors() == true) {
4128            throw new IllegalArgumentException("File descriptors passed in Intent");
4129        }
4130
4131        synchronized(this) {
4132            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4133            if (r == null) {
4134                return true;
4135            }
4136            // Keep track of the root activity of the task before we finish it
4137            TaskRecord tr = r.task;
4138            ActivityRecord rootR = tr.getRootActivity();
4139            if (rootR == null) {
4140                Slog.w(TAG, "Finishing task with all activities already finished");
4141            }
4142            // Do not allow task to finish if last task in lockTask mode. Launchable apps can
4143            // finish themselves.
4144            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE && rootR == r &&
4145                    mStackSupervisor.isLastLockedTask(tr)) {
4146                Slog.i(TAG, "Not finishing task in lock task mode");
4147                mStackSupervisor.showLockTaskToast();
4148                return false;
4149            }
4150            if (mController != null) {
4151                // Find the first activity that is not finishing.
4152                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4153                if (next != null) {
4154                    // ask watcher if this is allowed
4155                    boolean resumeOK = true;
4156                    try {
4157                        resumeOK = mController.activityResuming(next.packageName);
4158                    } catch (RemoteException e) {
4159                        mController = null;
4160                        Watchdog.getInstance().setActivityController(null);
4161                    }
4162
4163                    if (!resumeOK) {
4164                        Slog.i(TAG, "Not finishing activity because controller resumed");
4165                        return false;
4166                    }
4167                }
4168            }
4169            final long origId = Binder.clearCallingIdentity();
4170            try {
4171                boolean res;
4172                if (finishTask && r == rootR) {
4173                    // If requested, remove the task that is associated to this activity only if it
4174                    // was the root activity in the task. The result code and data is ignored
4175                    // because we don't support returning them across task boundaries.
4176                    res = removeTaskByIdLocked(tr.taskId, false);
4177                    if (!res) {
4178                        Slog.i(TAG, "Removing task failed to finish activity");
4179                    }
4180                } else {
4181                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4182                            resultData, "app-request", true);
4183                    if (!res) {
4184                        Slog.i(TAG, "Failed to finish by app-request");
4185                    }
4186                }
4187                return res;
4188            } finally {
4189                Binder.restoreCallingIdentity(origId);
4190            }
4191        }
4192    }
4193
4194    @Override
4195    public final void finishHeavyWeightApp() {
4196        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4197                != PackageManager.PERMISSION_GRANTED) {
4198            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4199                    + Binder.getCallingPid()
4200                    + ", uid=" + Binder.getCallingUid()
4201                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4202            Slog.w(TAG, msg);
4203            throw new SecurityException(msg);
4204        }
4205
4206        synchronized(this) {
4207            if (mHeavyWeightProcess == null) {
4208                return;
4209            }
4210
4211            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4212            for (int i = 0; i < activities.size(); i++) {
4213                ActivityRecord r = activities.get(i);
4214                if (!r.finishing && r.isInStackLocked()) {
4215                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4216                            null, "finish-heavy", true);
4217                }
4218            }
4219
4220            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4221                    mHeavyWeightProcess.userId, 0));
4222            mHeavyWeightProcess = null;
4223        }
4224    }
4225
4226    @Override
4227    public void crashApplication(int uid, int initialPid, String packageName,
4228            String message) {
4229        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4230                != PackageManager.PERMISSION_GRANTED) {
4231            String msg = "Permission Denial: crashApplication() from pid="
4232                    + Binder.getCallingPid()
4233                    + ", uid=" + Binder.getCallingUid()
4234                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4235            Slog.w(TAG, msg);
4236            throw new SecurityException(msg);
4237        }
4238
4239        synchronized(this) {
4240            ProcessRecord proc = null;
4241
4242            // Figure out which process to kill.  We don't trust that initialPid
4243            // still has any relation to current pids, so must scan through the
4244            // list.
4245            synchronized (mPidsSelfLocked) {
4246                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4247                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4248                    if (p.uid != uid) {
4249                        continue;
4250                    }
4251                    if (p.pid == initialPid) {
4252                        proc = p;
4253                        break;
4254                    }
4255                    if (p.pkgList.containsKey(packageName)) {
4256                        proc = p;
4257                    }
4258                }
4259            }
4260
4261            if (proc == null) {
4262                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4263                        + " initialPid=" + initialPid
4264                        + " packageName=" + packageName);
4265                return;
4266            }
4267
4268            if (proc.thread != null) {
4269                if (proc.pid == Process.myPid()) {
4270                    Log.w(TAG, "crashApplication: trying to crash self!");
4271                    return;
4272                }
4273                long ident = Binder.clearCallingIdentity();
4274                try {
4275                    proc.thread.scheduleCrash(message);
4276                } catch (RemoteException e) {
4277                }
4278                Binder.restoreCallingIdentity(ident);
4279            }
4280        }
4281    }
4282
4283    @Override
4284    public final void finishSubActivity(IBinder token, String resultWho,
4285            int requestCode) {
4286        synchronized(this) {
4287            final long origId = Binder.clearCallingIdentity();
4288            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4289            if (r != null) {
4290                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4291            }
4292            Binder.restoreCallingIdentity(origId);
4293        }
4294    }
4295
4296    @Override
4297    public boolean finishActivityAffinity(IBinder token) {
4298        synchronized(this) {
4299            final long origId = Binder.clearCallingIdentity();
4300            try {
4301                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4302                if (r == null) {
4303                    return false;
4304                }
4305
4306                // Do not allow the last non-launchable task to finish in Lock Task mode.
4307                final TaskRecord task = r.task;
4308                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE &&
4309                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4310                    mStackSupervisor.showLockTaskToast();
4311                    return false;
4312                }
4313                return task.stack.finishActivityAffinityLocked(r);
4314            } finally {
4315                Binder.restoreCallingIdentity(origId);
4316            }
4317        }
4318    }
4319
4320    @Override
4321    public void finishVoiceTask(IVoiceInteractionSession session) {
4322        synchronized(this) {
4323            final long origId = Binder.clearCallingIdentity();
4324            try {
4325                mStackSupervisor.finishVoiceTask(session);
4326            } finally {
4327                Binder.restoreCallingIdentity(origId);
4328            }
4329        }
4330
4331    }
4332
4333    @Override
4334    public boolean releaseActivityInstance(IBinder token) {
4335        synchronized(this) {
4336            final long origId = Binder.clearCallingIdentity();
4337            try {
4338                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4339                if (r == null) {
4340                    return false;
4341                }
4342                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4343            } finally {
4344                Binder.restoreCallingIdentity(origId);
4345            }
4346        }
4347    }
4348
4349    @Override
4350    public void releaseSomeActivities(IApplicationThread appInt) {
4351        synchronized(this) {
4352            final long origId = Binder.clearCallingIdentity();
4353            try {
4354                ProcessRecord app = getRecordForAppLocked(appInt);
4355                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4356            } finally {
4357                Binder.restoreCallingIdentity(origId);
4358            }
4359        }
4360    }
4361
4362    @Override
4363    public boolean willActivityBeVisible(IBinder token) {
4364        synchronized(this) {
4365            ActivityStack stack = ActivityRecord.getStackLocked(token);
4366            if (stack != null) {
4367                return stack.willActivityBeVisibleLocked(token);
4368            }
4369            return false;
4370        }
4371    }
4372
4373    @Override
4374    public void overridePendingTransition(IBinder token, String packageName,
4375            int enterAnim, int exitAnim) {
4376        synchronized(this) {
4377            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4378            if (self == null) {
4379                return;
4380            }
4381
4382            final long origId = Binder.clearCallingIdentity();
4383
4384            if (self.state == ActivityState.RESUMED
4385                    || self.state == ActivityState.PAUSING) {
4386                mWindowManager.overridePendingAppTransition(packageName,
4387                        enterAnim, exitAnim, null);
4388            }
4389
4390            Binder.restoreCallingIdentity(origId);
4391        }
4392    }
4393
4394    /**
4395     * Main function for removing an existing process from the activity manager
4396     * as a result of that process going away.  Clears out all connections
4397     * to the process.
4398     */
4399    private final void handleAppDiedLocked(ProcessRecord app,
4400            boolean restarting, boolean allowRestart) {
4401        int pid = app.pid;
4402        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4403        if (!kept && !restarting) {
4404            removeLruProcessLocked(app);
4405            if (pid > 0) {
4406                ProcessList.remove(pid);
4407            }
4408        }
4409
4410        if (mProfileProc == app) {
4411            clearProfilerLocked();
4412        }
4413
4414        // Remove this application's activities from active lists.
4415        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4416
4417        app.activities.clear();
4418
4419        if (app.instrumentationClass != null) {
4420            Slog.w(TAG, "Crash of app " + app.processName
4421                  + " running instrumentation " + app.instrumentationClass);
4422            Bundle info = new Bundle();
4423            info.putString("shortMsg", "Process crashed.");
4424            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4425        }
4426
4427        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4428            // If there was nothing to resume, and we are not already
4429            // restarting this process, but there is a visible activity that
4430            // is hosted by the process...  then make sure all visible
4431            // activities are running, taking care of restarting this
4432            // process.
4433            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4434        }
4435    }
4436
4437    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4438        IBinder threadBinder = thread.asBinder();
4439        // Find the application record.
4440        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4441            ProcessRecord rec = mLruProcesses.get(i);
4442            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4443                return i;
4444            }
4445        }
4446        return -1;
4447    }
4448
4449    final ProcessRecord getRecordForAppLocked(
4450            IApplicationThread thread) {
4451        if (thread == null) {
4452            return null;
4453        }
4454
4455        int appIndex = getLRURecordIndexForAppLocked(thread);
4456        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4457    }
4458
4459    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4460        // If there are no longer any background processes running,
4461        // and the app that died was not running instrumentation,
4462        // then tell everyone we are now low on memory.
4463        boolean haveBg = false;
4464        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4465            ProcessRecord rec = mLruProcesses.get(i);
4466            if (rec.thread != null
4467                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4468                haveBg = true;
4469                break;
4470            }
4471        }
4472
4473        if (!haveBg) {
4474            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4475            if (doReport) {
4476                long now = SystemClock.uptimeMillis();
4477                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4478                    doReport = false;
4479                } else {
4480                    mLastMemUsageReportTime = now;
4481                }
4482            }
4483            final ArrayList<ProcessMemInfo> memInfos
4484                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4485            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4486            long now = SystemClock.uptimeMillis();
4487            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4488                ProcessRecord rec = mLruProcesses.get(i);
4489                if (rec == dyingProc || rec.thread == null) {
4490                    continue;
4491                }
4492                if (doReport) {
4493                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4494                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4495                }
4496                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4497                    // The low memory report is overriding any current
4498                    // state for a GC request.  Make sure to do
4499                    // heavy/important/visible/foreground processes first.
4500                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4501                        rec.lastRequestedGc = 0;
4502                    } else {
4503                        rec.lastRequestedGc = rec.lastLowMemory;
4504                    }
4505                    rec.reportLowMemory = true;
4506                    rec.lastLowMemory = now;
4507                    mProcessesToGc.remove(rec);
4508                    addProcessToGcListLocked(rec);
4509                }
4510            }
4511            if (doReport) {
4512                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4513                mHandler.sendMessage(msg);
4514            }
4515            scheduleAppGcsLocked();
4516        }
4517    }
4518
4519    final void appDiedLocked(ProcessRecord app) {
4520       appDiedLocked(app, app.pid, app.thread, false);
4521    }
4522
4523    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4524            boolean fromBinderDied) {
4525        // First check if this ProcessRecord is actually active for the pid.
4526        synchronized (mPidsSelfLocked) {
4527            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4528            if (curProc != app) {
4529                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4530                return;
4531            }
4532        }
4533
4534        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4535        synchronized (stats) {
4536            stats.noteProcessDiedLocked(app.info.uid, pid);
4537        }
4538
4539        if (!app.killed) {
4540            if (!fromBinderDied) {
4541                Process.killProcessQuiet(pid);
4542            }
4543            Process.killProcessGroup(app.info.uid, pid);
4544            app.killed = true;
4545        }
4546
4547        // Clean up already done if the process has been re-started.
4548        if (app.pid == pid && app.thread != null &&
4549                app.thread.asBinder() == thread.asBinder()) {
4550            boolean doLowMem = app.instrumentationClass == null;
4551            boolean doOomAdj = doLowMem;
4552            if (!app.killedByAm) {
4553                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4554                        + ") has died");
4555                mAllowLowerMemLevel = true;
4556            } else {
4557                // Note that we always want to do oom adj to update our state with the
4558                // new number of procs.
4559                mAllowLowerMemLevel = false;
4560                doLowMem = false;
4561            }
4562            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4563            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4564                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4565            handleAppDiedLocked(app, false, true);
4566
4567            if (doOomAdj) {
4568                updateOomAdjLocked();
4569            }
4570            if (doLowMem) {
4571                doLowMemReportIfNeededLocked(app);
4572            }
4573        } else if (app.pid != pid) {
4574            // A new process has already been started.
4575            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4576                    + ") has died and restarted (pid " + app.pid + ").");
4577            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4578        } else if (DEBUG_PROCESSES) {
4579            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4580                    + thread.asBinder());
4581        }
4582    }
4583
4584    /**
4585     * If a stack trace dump file is configured, dump process stack traces.
4586     * @param clearTraces causes the dump file to be erased prior to the new
4587     *    traces being written, if true; when false, the new traces will be
4588     *    appended to any existing file content.
4589     * @param firstPids of dalvik VM processes to dump stack traces for first
4590     * @param lastPids of dalvik VM processes to dump stack traces for last
4591     * @param nativeProcs optional list of native process names to dump stack crawls
4592     * @return file containing stack traces, or null if no dump file is configured
4593     */
4594    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4595            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4596        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4597        if (tracesPath == null || tracesPath.length() == 0) {
4598            return null;
4599        }
4600
4601        File tracesFile = new File(tracesPath);
4602        try {
4603            File tracesDir = tracesFile.getParentFile();
4604            if (!tracesDir.exists()) {
4605                tracesDir.mkdirs();
4606                if (!SELinux.restorecon(tracesDir)) {
4607                    return null;
4608                }
4609            }
4610            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4611
4612            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4613            tracesFile.createNewFile();
4614            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4615        } catch (IOException e) {
4616            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4617            return null;
4618        }
4619
4620        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4621        return tracesFile;
4622    }
4623
4624    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4625            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4626        // Use a FileObserver to detect when traces finish writing.
4627        // The order of traces is considered important to maintain for legibility.
4628        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4629            @Override
4630            public synchronized void onEvent(int event, String path) { notify(); }
4631        };
4632
4633        try {
4634            observer.startWatching();
4635
4636            // First collect all of the stacks of the most important pids.
4637            if (firstPids != null) {
4638                try {
4639                    int num = firstPids.size();
4640                    for (int i = 0; i < num; i++) {
4641                        synchronized (observer) {
4642                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4643                            observer.wait(200);  // Wait for write-close, give up after 200msec
4644                        }
4645                    }
4646                } catch (InterruptedException e) {
4647                    Slog.wtf(TAG, e);
4648                }
4649            }
4650
4651            // Next collect the stacks of the native pids
4652            if (nativeProcs != null) {
4653                int[] pids = Process.getPidsForCommands(nativeProcs);
4654                if (pids != null) {
4655                    for (int pid : pids) {
4656                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4657                    }
4658                }
4659            }
4660
4661            // Lastly, measure CPU usage.
4662            if (processCpuTracker != null) {
4663                processCpuTracker.init();
4664                System.gc();
4665                processCpuTracker.update();
4666                try {
4667                    synchronized (processCpuTracker) {
4668                        processCpuTracker.wait(500); // measure over 1/2 second.
4669                    }
4670                } catch (InterruptedException e) {
4671                }
4672                processCpuTracker.update();
4673
4674                // We'll take the stack crawls of just the top apps using CPU.
4675                final int N = processCpuTracker.countWorkingStats();
4676                int numProcs = 0;
4677                for (int i=0; i<N && numProcs<5; i++) {
4678                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4679                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4680                        numProcs++;
4681                        try {
4682                            synchronized (observer) {
4683                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4684                                observer.wait(200);  // Wait for write-close, give up after 200msec
4685                            }
4686                        } catch (InterruptedException e) {
4687                            Slog.wtf(TAG, e);
4688                        }
4689
4690                    }
4691                }
4692            }
4693        } finally {
4694            observer.stopWatching();
4695        }
4696    }
4697
4698    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4699        if (true || IS_USER_BUILD) {
4700            return;
4701        }
4702        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4703        if (tracesPath == null || tracesPath.length() == 0) {
4704            return;
4705        }
4706
4707        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4708        StrictMode.allowThreadDiskWrites();
4709        try {
4710            final File tracesFile = new File(tracesPath);
4711            final File tracesDir = tracesFile.getParentFile();
4712            final File tracesTmp = new File(tracesDir, "__tmp__");
4713            try {
4714                if (!tracesDir.exists()) {
4715                    tracesDir.mkdirs();
4716                    if (!SELinux.restorecon(tracesDir.getPath())) {
4717                        return;
4718                    }
4719                }
4720                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4721
4722                if (tracesFile.exists()) {
4723                    tracesTmp.delete();
4724                    tracesFile.renameTo(tracesTmp);
4725                }
4726                StringBuilder sb = new StringBuilder();
4727                Time tobj = new Time();
4728                tobj.set(System.currentTimeMillis());
4729                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4730                sb.append(": ");
4731                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4732                sb.append(" since ");
4733                sb.append(msg);
4734                FileOutputStream fos = new FileOutputStream(tracesFile);
4735                fos.write(sb.toString().getBytes());
4736                if (app == null) {
4737                    fos.write("\n*** No application process!".getBytes());
4738                }
4739                fos.close();
4740                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4741            } catch (IOException e) {
4742                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4743                return;
4744            }
4745
4746            if (app != null) {
4747                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4748                firstPids.add(app.pid);
4749                dumpStackTraces(tracesPath, firstPids, null, null, null);
4750            }
4751
4752            File lastTracesFile = null;
4753            File curTracesFile = null;
4754            for (int i=9; i>=0; i--) {
4755                String name = String.format(Locale.US, "slow%02d.txt", i);
4756                curTracesFile = new File(tracesDir, name);
4757                if (curTracesFile.exists()) {
4758                    if (lastTracesFile != null) {
4759                        curTracesFile.renameTo(lastTracesFile);
4760                    } else {
4761                        curTracesFile.delete();
4762                    }
4763                }
4764                lastTracesFile = curTracesFile;
4765            }
4766            tracesFile.renameTo(curTracesFile);
4767            if (tracesTmp.exists()) {
4768                tracesTmp.renameTo(tracesFile);
4769            }
4770        } finally {
4771            StrictMode.setThreadPolicy(oldPolicy);
4772        }
4773    }
4774
4775    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4776            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4777        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4778        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4779
4780        if (mController != null) {
4781            try {
4782                // 0 == continue, -1 = kill process immediately
4783                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4784                if (res < 0 && app.pid != MY_PID) {
4785                    app.kill("anr", true);
4786                }
4787            } catch (RemoteException e) {
4788                mController = null;
4789                Watchdog.getInstance().setActivityController(null);
4790            }
4791        }
4792
4793        long anrTime = SystemClock.uptimeMillis();
4794        if (MONITOR_CPU_USAGE) {
4795            updateCpuStatsNow();
4796        }
4797
4798        synchronized (this) {
4799            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4800            if (mShuttingDown) {
4801                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4802                return;
4803            } else if (app.notResponding) {
4804                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4805                return;
4806            } else if (app.crashing) {
4807                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4808                return;
4809            }
4810
4811            // In case we come through here for the same app before completing
4812            // this one, mark as anring now so we will bail out.
4813            app.notResponding = true;
4814
4815            // Log the ANR to the event log.
4816            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4817                    app.processName, app.info.flags, annotation);
4818
4819            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4820            firstPids.add(app.pid);
4821
4822            int parentPid = app.pid;
4823            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4824            if (parentPid != app.pid) firstPids.add(parentPid);
4825
4826            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4827
4828            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4829                ProcessRecord r = mLruProcesses.get(i);
4830                if (r != null && r.thread != null) {
4831                    int pid = r.pid;
4832                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4833                        if (r.persistent) {
4834                            firstPids.add(pid);
4835                        } else {
4836                            lastPids.put(pid, Boolean.TRUE);
4837                        }
4838                    }
4839                }
4840            }
4841        }
4842
4843        // Log the ANR to the main log.
4844        StringBuilder info = new StringBuilder();
4845        info.setLength(0);
4846        info.append("ANR in ").append(app.processName);
4847        if (activity != null && activity.shortComponentName != null) {
4848            info.append(" (").append(activity.shortComponentName).append(")");
4849        }
4850        info.append("\n");
4851        info.append("PID: ").append(app.pid).append("\n");
4852        if (annotation != null) {
4853            info.append("Reason: ").append(annotation).append("\n");
4854        }
4855        if (parent != null && parent != activity) {
4856            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4857        }
4858
4859        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4860
4861        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4862                NATIVE_STACKS_OF_INTEREST);
4863
4864        String cpuInfo = null;
4865        if (MONITOR_CPU_USAGE) {
4866            updateCpuStatsNow();
4867            synchronized (mProcessCpuTracker) {
4868                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4869            }
4870            info.append(processCpuTracker.printCurrentLoad());
4871            info.append(cpuInfo);
4872        }
4873
4874        info.append(processCpuTracker.printCurrentState(anrTime));
4875
4876        Slog.e(TAG, info.toString());
4877        if (tracesFile == null) {
4878            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4879            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4880        }
4881
4882        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4883                cpuInfo, tracesFile, null);
4884
4885        if (mController != null) {
4886            try {
4887                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4888                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4889                if (res != 0) {
4890                    if (res < 0 && app.pid != MY_PID) {
4891                        app.kill("anr", true);
4892                    } else {
4893                        synchronized (this) {
4894                            mServices.scheduleServiceTimeoutLocked(app);
4895                        }
4896                    }
4897                    return;
4898                }
4899            } catch (RemoteException e) {
4900                mController = null;
4901                Watchdog.getInstance().setActivityController(null);
4902            }
4903        }
4904
4905        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4906        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4907                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4908
4909        synchronized (this) {
4910            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
4911
4912            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4913                app.kill("bg anr", true);
4914                return;
4915            }
4916
4917            // Set the app's notResponding state, and look up the errorReportReceiver
4918            makeAppNotRespondingLocked(app,
4919                    activity != null ? activity.shortComponentName : null,
4920                    annotation != null ? "ANR " + annotation : "ANR",
4921                    info.toString());
4922
4923            // Bring up the infamous App Not Responding dialog
4924            Message msg = Message.obtain();
4925            HashMap<String, Object> map = new HashMap<String, Object>();
4926            msg.what = SHOW_NOT_RESPONDING_MSG;
4927            msg.obj = map;
4928            msg.arg1 = aboveSystem ? 1 : 0;
4929            map.put("app", app);
4930            if (activity != null) {
4931                map.put("activity", activity);
4932            }
4933
4934            mUiHandler.sendMessage(msg);
4935        }
4936    }
4937
4938    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4939        if (!mLaunchWarningShown) {
4940            mLaunchWarningShown = true;
4941            mUiHandler.post(new Runnable() {
4942                @Override
4943                public void run() {
4944                    synchronized (ActivityManagerService.this) {
4945                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4946                        d.show();
4947                        mUiHandler.postDelayed(new Runnable() {
4948                            @Override
4949                            public void run() {
4950                                synchronized (ActivityManagerService.this) {
4951                                    d.dismiss();
4952                                    mLaunchWarningShown = false;
4953                                }
4954                            }
4955                        }, 4000);
4956                    }
4957                }
4958            });
4959        }
4960    }
4961
4962    @Override
4963    public boolean clearApplicationUserData(final String packageName,
4964            final IPackageDataObserver observer, int userId) {
4965        enforceNotIsolatedCaller("clearApplicationUserData");
4966        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
4967            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
4968        }
4969        int uid = Binder.getCallingUid();
4970        int pid = Binder.getCallingPid();
4971        userId = handleIncomingUser(pid, uid,
4972                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4973        long callingId = Binder.clearCallingIdentity();
4974        try {
4975            IPackageManager pm = AppGlobals.getPackageManager();
4976            int pkgUid = -1;
4977            synchronized(this) {
4978                try {
4979                    pkgUid = pm.getPackageUid(packageName, userId);
4980                } catch (RemoteException e) {
4981                }
4982                if (pkgUid == -1) {
4983                    Slog.w(TAG, "Invalid packageName: " + packageName);
4984                    if (observer != null) {
4985                        try {
4986                            observer.onRemoveCompleted(packageName, false);
4987                        } catch (RemoteException e) {
4988                            Slog.i(TAG, "Observer no longer exists.");
4989                        }
4990                    }
4991                    return false;
4992                }
4993                if (uid == pkgUid || checkComponentPermission(
4994                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4995                        pid, uid, -1, true)
4996                        == PackageManager.PERMISSION_GRANTED) {
4997                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4998                } else {
4999                    throw new SecurityException("PID " + pid + " does not have permission "
5000                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5001                                    + " of package " + packageName);
5002                }
5003
5004                // Remove all tasks match the cleared application package and user
5005                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5006                    final TaskRecord tr = mRecentTasks.get(i);
5007                    final String taskPackageName =
5008                            tr.getBaseIntent().getComponent().getPackageName();
5009                    if (tr.userId != userId) continue;
5010                    if (!taskPackageName.equals(packageName)) continue;
5011                    removeTaskByIdLocked(tr.taskId, false);
5012                }
5013            }
5014
5015            try {
5016                // Clear application user data
5017                pm.clearApplicationUserData(packageName, observer, userId);
5018
5019                synchronized(this) {
5020                    // Remove all permissions granted from/to this package
5021                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5022                }
5023
5024                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5025                        Uri.fromParts("package", packageName, null));
5026                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5027                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5028                        null, null, 0, null, null, null, false, false, userId);
5029            } catch (RemoteException e) {
5030            }
5031        } finally {
5032            Binder.restoreCallingIdentity(callingId);
5033        }
5034        return true;
5035    }
5036
5037    @Override
5038    public void killBackgroundProcesses(final String packageName, int userId) {
5039        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5040                != PackageManager.PERMISSION_GRANTED &&
5041                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5042                        != PackageManager.PERMISSION_GRANTED) {
5043            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5044                    + Binder.getCallingPid()
5045                    + ", uid=" + Binder.getCallingUid()
5046                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5047            Slog.w(TAG, msg);
5048            throw new SecurityException(msg);
5049        }
5050
5051        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5052                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5053        long callingId = Binder.clearCallingIdentity();
5054        try {
5055            IPackageManager pm = AppGlobals.getPackageManager();
5056            synchronized(this) {
5057                int appId = -1;
5058                try {
5059                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5060                } catch (RemoteException e) {
5061                }
5062                if (appId == -1) {
5063                    Slog.w(TAG, "Invalid packageName: " + packageName);
5064                    return;
5065                }
5066                killPackageProcessesLocked(packageName, appId, userId,
5067                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5068            }
5069        } finally {
5070            Binder.restoreCallingIdentity(callingId);
5071        }
5072    }
5073
5074    @Override
5075    public void killAllBackgroundProcesses() {
5076        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5077                != PackageManager.PERMISSION_GRANTED) {
5078            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5079                    + Binder.getCallingPid()
5080                    + ", uid=" + Binder.getCallingUid()
5081                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5082            Slog.w(TAG, msg);
5083            throw new SecurityException(msg);
5084        }
5085
5086        long callingId = Binder.clearCallingIdentity();
5087        try {
5088            synchronized(this) {
5089                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5090                final int NP = mProcessNames.getMap().size();
5091                for (int ip=0; ip<NP; ip++) {
5092                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5093                    final int NA = apps.size();
5094                    for (int ia=0; ia<NA; ia++) {
5095                        ProcessRecord app = apps.valueAt(ia);
5096                        if (app.persistent) {
5097                            // we don't kill persistent processes
5098                            continue;
5099                        }
5100                        if (app.removed) {
5101                            procs.add(app);
5102                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5103                            app.removed = true;
5104                            procs.add(app);
5105                        }
5106                    }
5107                }
5108
5109                int N = procs.size();
5110                for (int i=0; i<N; i++) {
5111                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5112                }
5113                mAllowLowerMemLevel = true;
5114                updateOomAdjLocked();
5115                doLowMemReportIfNeededLocked(null);
5116            }
5117        } finally {
5118            Binder.restoreCallingIdentity(callingId);
5119        }
5120    }
5121
5122    @Override
5123    public void forceStopPackage(final String packageName, int userId) {
5124        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5125                != PackageManager.PERMISSION_GRANTED) {
5126            String msg = "Permission Denial: forceStopPackage() from pid="
5127                    + Binder.getCallingPid()
5128                    + ", uid=" + Binder.getCallingUid()
5129                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5130            Slog.w(TAG, msg);
5131            throw new SecurityException(msg);
5132        }
5133        final int callingPid = Binder.getCallingPid();
5134        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5135                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5136        long callingId = Binder.clearCallingIdentity();
5137        try {
5138            IPackageManager pm = AppGlobals.getPackageManager();
5139            synchronized(this) {
5140                int[] users = userId == UserHandle.USER_ALL
5141                        ? getUsersLocked() : new int[] { userId };
5142                for (int user : users) {
5143                    int pkgUid = -1;
5144                    try {
5145                        pkgUid = pm.getPackageUid(packageName, user);
5146                    } catch (RemoteException e) {
5147                    }
5148                    if (pkgUid == -1) {
5149                        Slog.w(TAG, "Invalid packageName: " + packageName);
5150                        continue;
5151                    }
5152                    try {
5153                        pm.setPackageStoppedState(packageName, true, user);
5154                    } catch (RemoteException e) {
5155                    } catch (IllegalArgumentException e) {
5156                        Slog.w(TAG, "Failed trying to unstop package "
5157                                + packageName + ": " + e);
5158                    }
5159                    if (isUserRunningLocked(user, false)) {
5160                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5161                    }
5162                }
5163            }
5164        } finally {
5165            Binder.restoreCallingIdentity(callingId);
5166        }
5167    }
5168
5169    @Override
5170    public void addPackageDependency(String packageName) {
5171        synchronized (this) {
5172            int callingPid = Binder.getCallingPid();
5173            if (callingPid == Process.myPid()) {
5174                //  Yeah, um, no.
5175                return;
5176            }
5177            ProcessRecord proc;
5178            synchronized (mPidsSelfLocked) {
5179                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5180            }
5181            if (proc != null) {
5182                if (proc.pkgDeps == null) {
5183                    proc.pkgDeps = new ArraySet<String>(1);
5184                }
5185                proc.pkgDeps.add(packageName);
5186            }
5187        }
5188    }
5189
5190    /*
5191     * The pkg name and app id have to be specified.
5192     */
5193    @Override
5194    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5195        if (pkg == null) {
5196            return;
5197        }
5198        // Make sure the uid is valid.
5199        if (appid < 0) {
5200            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5201            return;
5202        }
5203        int callerUid = Binder.getCallingUid();
5204        // Only the system server can kill an application
5205        if (callerUid == Process.SYSTEM_UID) {
5206            // Post an aysnc message to kill the application
5207            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5208            msg.arg1 = appid;
5209            msg.arg2 = 0;
5210            Bundle bundle = new Bundle();
5211            bundle.putString("pkg", pkg);
5212            bundle.putString("reason", reason);
5213            msg.obj = bundle;
5214            mHandler.sendMessage(msg);
5215        } else {
5216            throw new SecurityException(callerUid + " cannot kill pkg: " +
5217                    pkg);
5218        }
5219    }
5220
5221    @Override
5222    public void closeSystemDialogs(String reason) {
5223        enforceNotIsolatedCaller("closeSystemDialogs");
5224
5225        final int pid = Binder.getCallingPid();
5226        final int uid = Binder.getCallingUid();
5227        final long origId = Binder.clearCallingIdentity();
5228        try {
5229            synchronized (this) {
5230                // Only allow this from foreground processes, so that background
5231                // applications can't abuse it to prevent system UI from being shown.
5232                if (uid >= Process.FIRST_APPLICATION_UID) {
5233                    ProcessRecord proc;
5234                    synchronized (mPidsSelfLocked) {
5235                        proc = mPidsSelfLocked.get(pid);
5236                    }
5237                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5238                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5239                                + " from background process " + proc);
5240                        return;
5241                    }
5242                }
5243                closeSystemDialogsLocked(reason);
5244            }
5245        } finally {
5246            Binder.restoreCallingIdentity(origId);
5247        }
5248    }
5249
5250    void closeSystemDialogsLocked(String reason) {
5251        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5252        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5253                | Intent.FLAG_RECEIVER_FOREGROUND);
5254        if (reason != null) {
5255            intent.putExtra("reason", reason);
5256        }
5257        mWindowManager.closeSystemDialogs(reason);
5258
5259        mStackSupervisor.closeSystemDialogsLocked();
5260
5261        broadcastIntentLocked(null, null, intent, null,
5262                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5263                Process.SYSTEM_UID, UserHandle.USER_ALL);
5264    }
5265
5266    @Override
5267    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5268        enforceNotIsolatedCaller("getProcessMemoryInfo");
5269        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5270        for (int i=pids.length-1; i>=0; i--) {
5271            ProcessRecord proc;
5272            int oomAdj;
5273            synchronized (this) {
5274                synchronized (mPidsSelfLocked) {
5275                    proc = mPidsSelfLocked.get(pids[i]);
5276                    oomAdj = proc != null ? proc.setAdj : 0;
5277                }
5278            }
5279            infos[i] = new Debug.MemoryInfo();
5280            Debug.getMemoryInfo(pids[i], infos[i]);
5281            if (proc != null) {
5282                synchronized (this) {
5283                    if (proc.thread != null && proc.setAdj == oomAdj) {
5284                        // Record this for posterity if the process has been stable.
5285                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5286                                infos[i].getTotalUss(), false, proc.pkgList);
5287                    }
5288                }
5289            }
5290        }
5291        return infos;
5292    }
5293
5294    @Override
5295    public long[] getProcessPss(int[] pids) {
5296        enforceNotIsolatedCaller("getProcessPss");
5297        long[] pss = new long[pids.length];
5298        for (int i=pids.length-1; i>=0; i--) {
5299            ProcessRecord proc;
5300            int oomAdj;
5301            synchronized (this) {
5302                synchronized (mPidsSelfLocked) {
5303                    proc = mPidsSelfLocked.get(pids[i]);
5304                    oomAdj = proc != null ? proc.setAdj : 0;
5305                }
5306            }
5307            long[] tmpUss = new long[1];
5308            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5309            if (proc != null) {
5310                synchronized (this) {
5311                    if (proc.thread != null && proc.setAdj == oomAdj) {
5312                        // Record this for posterity if the process has been stable.
5313                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5314                    }
5315                }
5316            }
5317        }
5318        return pss;
5319    }
5320
5321    @Override
5322    public void killApplicationProcess(String processName, int uid) {
5323        if (processName == null) {
5324            return;
5325        }
5326
5327        int callerUid = Binder.getCallingUid();
5328        // Only the system server can kill an application
5329        if (callerUid == Process.SYSTEM_UID) {
5330            synchronized (this) {
5331                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5332                if (app != null && app.thread != null) {
5333                    try {
5334                        app.thread.scheduleSuicide();
5335                    } catch (RemoteException e) {
5336                        // If the other end already died, then our work here is done.
5337                    }
5338                } else {
5339                    Slog.w(TAG, "Process/uid not found attempting kill of "
5340                            + processName + " / " + uid);
5341                }
5342            }
5343        } else {
5344            throw new SecurityException(callerUid + " cannot kill app process: " +
5345                    processName);
5346        }
5347    }
5348
5349    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5350        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5351                false, true, false, false, UserHandle.getUserId(uid), reason);
5352        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5353                Uri.fromParts("package", packageName, null));
5354        if (!mProcessesReady) {
5355            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5356                    | Intent.FLAG_RECEIVER_FOREGROUND);
5357        }
5358        intent.putExtra(Intent.EXTRA_UID, uid);
5359        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5360        broadcastIntentLocked(null, null, intent,
5361                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5362                false, false,
5363                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5364    }
5365
5366    private void forceStopUserLocked(int userId, String reason) {
5367        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5368        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5369        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5370                | Intent.FLAG_RECEIVER_FOREGROUND);
5371        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5372        broadcastIntentLocked(null, null, intent,
5373                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5374                false, false,
5375                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5376    }
5377
5378    private final boolean killPackageProcessesLocked(String packageName, int appId,
5379            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5380            boolean doit, boolean evenPersistent, String reason) {
5381        ArrayList<ProcessRecord> procs = new ArrayList<>();
5382
5383        // Remove all processes this package may have touched: all with the
5384        // same UID (except for the system or root user), and all whose name
5385        // matches the package name.
5386        final int NP = mProcessNames.getMap().size();
5387        for (int ip=0; ip<NP; ip++) {
5388            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5389            final int NA = apps.size();
5390            for (int ia=0; ia<NA; ia++) {
5391                ProcessRecord app = apps.valueAt(ia);
5392                if (app.persistent && !evenPersistent) {
5393                    // we don't kill persistent processes
5394                    continue;
5395                }
5396                if (app.removed) {
5397                    if (doit) {
5398                        procs.add(app);
5399                    }
5400                    continue;
5401                }
5402
5403                // Skip process if it doesn't meet our oom adj requirement.
5404                if (app.setAdj < minOomAdj) {
5405                    continue;
5406                }
5407
5408                // If no package is specified, we call all processes under the
5409                // give user id.
5410                if (packageName == null) {
5411                    if (app.userId != userId) {
5412                        continue;
5413                    }
5414                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5415                        continue;
5416                    }
5417                // Package has been specified, we want to hit all processes
5418                // that match it.  We need to qualify this by the processes
5419                // that are running under the specified app and user ID.
5420                } else {
5421                    final boolean isDep = app.pkgDeps != null
5422                            && app.pkgDeps.contains(packageName);
5423                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5424                        continue;
5425                    }
5426                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5427                        continue;
5428                    }
5429                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5430                        continue;
5431                    }
5432                }
5433
5434                // Process has passed all conditions, kill it!
5435                if (!doit) {
5436                    return true;
5437                }
5438                app.removed = true;
5439                procs.add(app);
5440            }
5441        }
5442
5443        int N = procs.size();
5444        for (int i=0; i<N; i++) {
5445            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5446        }
5447        updateOomAdjLocked();
5448        return N > 0;
5449    }
5450
5451    private void cleanupDisabledPackageComponentsLocked(
5452            String packageName, int userId, String[] changedClasses) {
5453
5454        Set<String> disabledClasses = null;
5455        boolean packageDisabled = false;
5456        IPackageManager pm = AppGlobals.getPackageManager();
5457
5458        if (changedClasses == null) {
5459            // Nothing changed...
5460            return;
5461        }
5462
5463        // Determine enable/disable state of the package and its components.
5464        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5465        for (int i = changedClasses.length - 1; i >= 0; i--) {
5466            final String changedClass = changedClasses[i];
5467
5468            if (changedClass.equals(packageName)) {
5469                try {
5470                    // Entire package setting changed
5471                    enabled = pm.getApplicationEnabledSetting(packageName,
5472                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5473                } catch (RemoteException e) {
5474                    // Can't happen...
5475                }
5476                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5477                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5478                if (packageDisabled) {
5479                    // Entire package is disabled.
5480                    // No need to continue to check component states.
5481                    disabledClasses = null;
5482                    break;
5483                }
5484            } else {
5485                try {
5486                    enabled = pm.getComponentEnabledSetting(
5487                            new ComponentName(packageName, changedClass),
5488                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5489                } catch (RemoteException e) {
5490                    // Can't happen...
5491                }
5492                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5493                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5494                    if (disabledClasses == null) {
5495                        disabledClasses = new ArraySet<>(changedClasses.length);
5496                    }
5497                    disabledClasses.add(changedClass);
5498                }
5499            }
5500        }
5501
5502        if (!packageDisabled && disabledClasses == null) {
5503            // Nothing to do here...
5504            return;
5505        }
5506
5507        // Clean-up disabled activities.
5508        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5509                packageName, disabledClasses, true, false, userId) && mBooted) {
5510            mStackSupervisor.resumeTopActivitiesLocked();
5511            mStackSupervisor.scheduleIdleLocked();
5512        }
5513
5514        // Clean-up disabled tasks
5515        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5516
5517        // Clean-up disabled services.
5518        mServices.bringDownDisabledPackageServicesLocked(
5519                packageName, disabledClasses, userId, false, true);
5520
5521        // Clean-up disabled providers.
5522        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5523        mProviderMap.collectPackageProvidersLocked(
5524                packageName, disabledClasses, true, false, userId, providers);
5525        for (int i = providers.size() - 1; i >= 0; i--) {
5526            removeDyingProviderLocked(null, providers.get(i), true);
5527        }
5528
5529        // Clean-up disabled broadcast receivers.
5530        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5531            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5532                    packageName, disabledClasses, userId, true);
5533        }
5534
5535    }
5536
5537    private final boolean forceStopPackageLocked(String packageName, int appId,
5538            boolean callerWillRestart, boolean purgeCache, boolean doit,
5539            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5540        int i;
5541
5542        if (userId == UserHandle.USER_ALL && packageName == null) {
5543            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5544        }
5545
5546        if (appId < 0 && packageName != null) {
5547            try {
5548                appId = UserHandle.getAppId(
5549                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5550            } catch (RemoteException e) {
5551            }
5552        }
5553
5554        if (doit) {
5555            if (packageName != null) {
5556                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5557                        + " user=" + userId + ": " + reason);
5558            } else {
5559                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5560            }
5561
5562            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5563            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5564                SparseArray<Long> ba = pmap.valueAt(ip);
5565                for (i = ba.size() - 1; i >= 0; i--) {
5566                    boolean remove = false;
5567                    final int entUid = ba.keyAt(i);
5568                    if (packageName != null) {
5569                        if (userId == UserHandle.USER_ALL) {
5570                            if (UserHandle.getAppId(entUid) == appId) {
5571                                remove = true;
5572                            }
5573                        } else {
5574                            if (entUid == UserHandle.getUid(userId, appId)) {
5575                                remove = true;
5576                            }
5577                        }
5578                    } else if (UserHandle.getUserId(entUid) == userId) {
5579                        remove = true;
5580                    }
5581                    if (remove) {
5582                        ba.removeAt(i);
5583                    }
5584                }
5585                if (ba.size() == 0) {
5586                    pmap.removeAt(ip);
5587                }
5588            }
5589        }
5590
5591        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5592                -100, callerWillRestart, true, doit, evenPersistent,
5593                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5594
5595        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5596                packageName, null, doit, evenPersistent, userId)) {
5597            if (!doit) {
5598                return true;
5599            }
5600            didSomething = true;
5601        }
5602
5603        if (mServices.bringDownDisabledPackageServicesLocked(
5604                packageName, null, userId, evenPersistent, doit)) {
5605            if (!doit) {
5606                return true;
5607            }
5608            didSomething = true;
5609        }
5610
5611        if (packageName == null) {
5612            // Remove all sticky broadcasts from this user.
5613            mStickyBroadcasts.remove(userId);
5614        }
5615
5616        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5617        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5618                userId, providers)) {
5619            if (!doit) {
5620                return true;
5621            }
5622            didSomething = true;
5623        }
5624        for (i = providers.size() - 1; i >= 0; i--) {
5625            removeDyingProviderLocked(null, providers.get(i), true);
5626        }
5627
5628        // Remove transient permissions granted from/to this package/user
5629        removeUriPermissionsForPackageLocked(packageName, userId, false);
5630
5631        if (doit) {
5632            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5633                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5634                        packageName, null, userId, doit);
5635            }
5636        }
5637
5638        if (packageName == null || uninstalling) {
5639            // Remove pending intents.  For now we only do this when force
5640            // stopping users, because we have some problems when doing this
5641            // for packages -- app widgets are not currently cleaned up for
5642            // such packages, so they can be left with bad pending intents.
5643            if (mIntentSenderRecords.size() > 0) {
5644                Iterator<WeakReference<PendingIntentRecord>> it
5645                        = mIntentSenderRecords.values().iterator();
5646                while (it.hasNext()) {
5647                    WeakReference<PendingIntentRecord> wpir = it.next();
5648                    if (wpir == null) {
5649                        it.remove();
5650                        continue;
5651                    }
5652                    PendingIntentRecord pir = wpir.get();
5653                    if (pir == null) {
5654                        it.remove();
5655                        continue;
5656                    }
5657                    if (packageName == null) {
5658                        // Stopping user, remove all objects for the user.
5659                        if (pir.key.userId != userId) {
5660                            // Not the same user, skip it.
5661                            continue;
5662                        }
5663                    } else {
5664                        if (UserHandle.getAppId(pir.uid) != appId) {
5665                            // Different app id, skip it.
5666                            continue;
5667                        }
5668                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5669                            // Different user, skip it.
5670                            continue;
5671                        }
5672                        if (!pir.key.packageName.equals(packageName)) {
5673                            // Different package, skip it.
5674                            continue;
5675                        }
5676                    }
5677                    if (!doit) {
5678                        return true;
5679                    }
5680                    didSomething = true;
5681                    it.remove();
5682                    pir.canceled = true;
5683                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5684                        pir.key.activity.pendingResults.remove(pir.ref);
5685                    }
5686                }
5687            }
5688        }
5689
5690        if (doit) {
5691            if (purgeCache && packageName != null) {
5692                AttributeCache ac = AttributeCache.instance();
5693                if (ac != null) {
5694                    ac.removePackage(packageName);
5695                }
5696            }
5697            if (mBooted) {
5698                mStackSupervisor.resumeTopActivitiesLocked();
5699                mStackSupervisor.scheduleIdleLocked();
5700            }
5701        }
5702
5703        return didSomething;
5704    }
5705
5706    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5707        ProcessRecord old = mProcessNames.remove(name, uid);
5708        if (old != null) {
5709            old.uidRecord.numProcs--;
5710            if (old.uidRecord.numProcs == 0) {
5711                // No more processes using this uid, tell clients it is gone.
5712                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5713                        "No more processes in " + old.uidRecord);
5714                enqueueUidChangeLocked(old.uidRecord, true);
5715                mActiveUids.remove(uid);
5716            }
5717            old.uidRecord = null;
5718        }
5719        mIsolatedProcesses.remove(uid);
5720        return old;
5721    }
5722
5723    private final void addProcessNameLocked(ProcessRecord proc) {
5724        // We shouldn't already have a process under this name, but just in case we
5725        // need to clean up whatever may be there now.
5726        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5727        if (old != null) {
5728            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5729        }
5730        UidRecord uidRec = mActiveUids.get(proc.uid);
5731        if (uidRec == null) {
5732            uidRec = new UidRecord(proc.uid);
5733            // This is the first appearance of the uid, report it now!
5734            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5735                    "Creating new process uid: " + uidRec);
5736            mActiveUids.put(proc.uid, uidRec);
5737            enqueueUidChangeLocked(uidRec, false);
5738        }
5739        proc.uidRecord = uidRec;
5740        uidRec.numProcs++;
5741        mProcessNames.put(proc.processName, proc.uid, proc);
5742        if (proc.isolated) {
5743            mIsolatedProcesses.put(proc.uid, proc);
5744        }
5745    }
5746
5747    private final boolean removeProcessLocked(ProcessRecord app,
5748            boolean callerWillRestart, boolean allowRestart, String reason) {
5749        final String name = app.processName;
5750        final int uid = app.uid;
5751        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5752            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5753
5754        removeProcessNameLocked(name, uid);
5755        if (mHeavyWeightProcess == app) {
5756            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5757                    mHeavyWeightProcess.userId, 0));
5758            mHeavyWeightProcess = null;
5759        }
5760        boolean needRestart = false;
5761        if (app.pid > 0 && app.pid != MY_PID) {
5762            int pid = app.pid;
5763            synchronized (mPidsSelfLocked) {
5764                mPidsSelfLocked.remove(pid);
5765                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5766            }
5767            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5768            if (app.isolated) {
5769                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5770            }
5771            boolean willRestart = false;
5772            if (app.persistent && !app.isolated) {
5773                if (!callerWillRestart) {
5774                    willRestart = true;
5775                } else {
5776                    needRestart = true;
5777                }
5778            }
5779            app.kill(reason, true);
5780            handleAppDiedLocked(app, willRestart, allowRestart);
5781            if (willRestart) {
5782                removeLruProcessLocked(app);
5783                addAppLocked(app.info, false, null /* ABI override */);
5784            }
5785        } else {
5786            mRemovedProcesses.add(app);
5787        }
5788
5789        return needRestart;
5790    }
5791
5792    private final void processStartTimedOutLocked(ProcessRecord app) {
5793        final int pid = app.pid;
5794        boolean gone = false;
5795        synchronized (mPidsSelfLocked) {
5796            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5797            if (knownApp != null && knownApp.thread == null) {
5798                mPidsSelfLocked.remove(pid);
5799                gone = true;
5800            }
5801        }
5802
5803        if (gone) {
5804            Slog.w(TAG, "Process " + app + " failed to attach");
5805            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5806                    pid, app.uid, app.processName);
5807            removeProcessNameLocked(app.processName, app.uid);
5808            if (mHeavyWeightProcess == app) {
5809                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5810                        mHeavyWeightProcess.userId, 0));
5811                mHeavyWeightProcess = null;
5812            }
5813            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5814            if (app.isolated) {
5815                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5816            }
5817            // Take care of any launching providers waiting for this process.
5818            checkAppInLaunchingProvidersLocked(app, true);
5819            // Take care of any services that are waiting for the process.
5820            mServices.processStartTimedOutLocked(app);
5821            app.kill("start timeout", true);
5822            removeLruProcessLocked(app);
5823            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5824                Slog.w(TAG, "Unattached app died before backup, skipping");
5825                try {
5826                    IBackupManager bm = IBackupManager.Stub.asInterface(
5827                            ServiceManager.getService(Context.BACKUP_SERVICE));
5828                    bm.agentDisconnected(app.info.packageName);
5829                } catch (RemoteException e) {
5830                    // Can't happen; the backup manager is local
5831                }
5832            }
5833            if (isPendingBroadcastProcessLocked(pid)) {
5834                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5835                skipPendingBroadcastLocked(pid);
5836            }
5837        } else {
5838            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5839        }
5840    }
5841
5842    private final boolean attachApplicationLocked(IApplicationThread thread,
5843            int pid) {
5844
5845        // Find the application record that is being attached...  either via
5846        // the pid if we are running in multiple processes, or just pull the
5847        // next app record if we are emulating process with anonymous threads.
5848        ProcessRecord app;
5849        if (pid != MY_PID && pid >= 0) {
5850            synchronized (mPidsSelfLocked) {
5851                app = mPidsSelfLocked.get(pid);
5852            }
5853        } else {
5854            app = null;
5855        }
5856
5857        if (app == null) {
5858            Slog.w(TAG, "No pending application record for pid " + pid
5859                    + " (IApplicationThread " + thread + "); dropping process");
5860            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5861            if (pid > 0 && pid != MY_PID) {
5862                Process.killProcessQuiet(pid);
5863                //TODO: Process.killProcessGroup(app.info.uid, pid);
5864            } else {
5865                try {
5866                    thread.scheduleExit();
5867                } catch (Exception e) {
5868                    // Ignore exceptions.
5869                }
5870            }
5871            return false;
5872        }
5873
5874        // If this application record is still attached to a previous
5875        // process, clean it up now.
5876        if (app.thread != null) {
5877            handleAppDiedLocked(app, true, true);
5878        }
5879
5880        // Tell the process all about itself.
5881
5882        if (DEBUG_ALL) Slog.v(
5883                TAG, "Binding process pid " + pid + " to record " + app);
5884
5885        final String processName = app.processName;
5886        try {
5887            AppDeathRecipient adr = new AppDeathRecipient(
5888                    app, pid, thread);
5889            thread.asBinder().linkToDeath(adr, 0);
5890            app.deathRecipient = adr;
5891        } catch (RemoteException e) {
5892            app.resetPackageList(mProcessStats);
5893            startProcessLocked(app, "link fail", processName);
5894            return false;
5895        }
5896
5897        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5898
5899        app.makeActive(thread, mProcessStats);
5900        app.curAdj = app.setAdj = -100;
5901        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5902        app.forcingToForeground = null;
5903        updateProcessForegroundLocked(app, false, false);
5904        app.hasShownUi = false;
5905        app.debugging = false;
5906        app.cached = false;
5907        app.killedByAm = false;
5908
5909        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5910
5911        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5912        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5913
5914        if (!normalMode) {
5915            Slog.i(TAG, "Launching preboot mode app: " + app);
5916        }
5917
5918        if (DEBUG_ALL) Slog.v(
5919            TAG, "New app record " + app
5920            + " thread=" + thread.asBinder() + " pid=" + pid);
5921        try {
5922            int testMode = IApplicationThread.DEBUG_OFF;
5923            if (mDebugApp != null && mDebugApp.equals(processName)) {
5924                testMode = mWaitForDebugger
5925                    ? IApplicationThread.DEBUG_WAIT
5926                    : IApplicationThread.DEBUG_ON;
5927                app.debugging = true;
5928                if (mDebugTransient) {
5929                    mDebugApp = mOrigDebugApp;
5930                    mWaitForDebugger = mOrigWaitForDebugger;
5931                }
5932            }
5933            String profileFile = app.instrumentationProfileFile;
5934            ParcelFileDescriptor profileFd = null;
5935            int samplingInterval = 0;
5936            boolean profileAutoStop = false;
5937            if (mProfileApp != null && mProfileApp.equals(processName)) {
5938                mProfileProc = app;
5939                profileFile = mProfileFile;
5940                profileFd = mProfileFd;
5941                samplingInterval = mSamplingInterval;
5942                profileAutoStop = mAutoStopProfiler;
5943            }
5944            boolean enableOpenGlTrace = false;
5945            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5946                enableOpenGlTrace = true;
5947                mOpenGlTraceApp = null;
5948            }
5949
5950            // If the app is being launched for restore or full backup, set it up specially
5951            boolean isRestrictedBackupMode = false;
5952            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5953                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5954                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5955                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5956            }
5957
5958            ensurePackageDexOpt(app.instrumentationInfo != null
5959                    ? app.instrumentationInfo.packageName
5960                    : app.info.packageName);
5961            if (app.instrumentationClass != null) {
5962                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5963            }
5964            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
5965                    + processName + " with config " + mConfiguration);
5966            ApplicationInfo appInfo = app.instrumentationInfo != null
5967                    ? app.instrumentationInfo : app.info;
5968            app.compat = compatibilityInfoForPackageLocked(appInfo);
5969            if (profileFd != null) {
5970                profileFd = profileFd.dup();
5971            }
5972            ProfilerInfo profilerInfo = profileFile == null ? null
5973                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5974            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5975                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5976                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5977                    isRestrictedBackupMode || !normalMode, app.persistent,
5978                    new Configuration(mConfiguration), app.compat,
5979                    getCommonServicesLocked(app.isolated),
5980                    mCoreSettingsObserver.getCoreSettingsLocked());
5981            updateLruProcessLocked(app, false, null);
5982            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5983        } catch (Exception e) {
5984            // todo: Yikes!  What should we do?  For now we will try to
5985            // start another process, but that could easily get us in
5986            // an infinite loop of restarting processes...
5987            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5988
5989            app.resetPackageList(mProcessStats);
5990            app.unlinkDeathRecipient();
5991            startProcessLocked(app, "bind fail", processName);
5992            return false;
5993        }
5994
5995        // Remove this record from the list of starting applications.
5996        mPersistentStartingProcesses.remove(app);
5997        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
5998                "Attach application locked removing on hold: " + app);
5999        mProcessesOnHold.remove(app);
6000
6001        boolean badApp = false;
6002        boolean didSomething = false;
6003
6004        // See if the top visible activity is waiting to run in this process...
6005        if (normalMode) {
6006            try {
6007                if (mStackSupervisor.attachApplicationLocked(app)) {
6008                    didSomething = true;
6009                }
6010            } catch (Exception e) {
6011                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6012                badApp = true;
6013            }
6014        }
6015
6016        // Find any services that should be running in this process...
6017        if (!badApp) {
6018            try {
6019                didSomething |= mServices.attachApplicationLocked(app, processName);
6020            } catch (Exception e) {
6021                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6022                badApp = true;
6023            }
6024        }
6025
6026        // Check if a next-broadcast receiver is in this process...
6027        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6028            try {
6029                didSomething |= sendPendingBroadcastsLocked(app);
6030            } catch (Exception e) {
6031                // If the app died trying to launch the receiver we declare it 'bad'
6032                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6033                badApp = true;
6034            }
6035        }
6036
6037        // Check whether the next backup agent is in this process...
6038        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6039            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6040                    "New app is backup target, launching agent for " + app);
6041            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6042            try {
6043                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6044                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6045                        mBackupTarget.backupMode);
6046            } catch (Exception e) {
6047                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6048                badApp = true;
6049            }
6050        }
6051
6052        if (badApp) {
6053            app.kill("error during init", true);
6054            handleAppDiedLocked(app, false, true);
6055            return false;
6056        }
6057
6058        if (!didSomething) {
6059            updateOomAdjLocked();
6060        }
6061
6062        return true;
6063    }
6064
6065    @Override
6066    public final void attachApplication(IApplicationThread thread) {
6067        synchronized (this) {
6068            int callingPid = Binder.getCallingPid();
6069            final long origId = Binder.clearCallingIdentity();
6070            attachApplicationLocked(thread, callingPid);
6071            Binder.restoreCallingIdentity(origId);
6072        }
6073    }
6074
6075    @Override
6076    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6077        final long origId = Binder.clearCallingIdentity();
6078        synchronized (this) {
6079            ActivityStack stack = ActivityRecord.getStackLocked(token);
6080            if (stack != null) {
6081                ActivityRecord r =
6082                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6083                if (stopProfiling) {
6084                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6085                        try {
6086                            mProfileFd.close();
6087                        } catch (IOException e) {
6088                        }
6089                        clearProfilerLocked();
6090                    }
6091                }
6092            }
6093        }
6094        Binder.restoreCallingIdentity(origId);
6095    }
6096
6097    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6098        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6099                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6100    }
6101
6102    void enableScreenAfterBoot() {
6103        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6104                SystemClock.uptimeMillis());
6105        mWindowManager.enableScreenAfterBoot();
6106
6107        synchronized (this) {
6108            updateEventDispatchingLocked();
6109        }
6110    }
6111
6112    @Override
6113    public void showBootMessage(final CharSequence msg, final boolean always) {
6114        if (Binder.getCallingUid() != Process.myUid()) {
6115            // These days only the core system can call this, so apps can't get in
6116            // the way of what we show about running them.
6117        }
6118        mWindowManager.showBootMessage(msg, always);
6119    }
6120
6121    @Override
6122    public void keyguardWaitingForActivityDrawn() {
6123        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6124        final long token = Binder.clearCallingIdentity();
6125        try {
6126            synchronized (this) {
6127                if (DEBUG_LOCKSCREEN) logLockScreen("");
6128                mWindowManager.keyguardWaitingForActivityDrawn();
6129                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6130                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6131                    updateSleepIfNeededLocked();
6132                }
6133            }
6134        } finally {
6135            Binder.restoreCallingIdentity(token);
6136        }
6137    }
6138
6139    @Override
6140    public void keyguardGoingAway(boolean disableWindowAnimations,
6141            boolean keyguardGoingToNotificationShade) {
6142        enforceNotIsolatedCaller("keyguardGoingAway");
6143        final long token = Binder.clearCallingIdentity();
6144        try {
6145            synchronized (this) {
6146                if (DEBUG_LOCKSCREEN) logLockScreen("");
6147                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6148                        keyguardGoingToNotificationShade);
6149                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6150                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6151                    updateSleepIfNeededLocked();
6152                }
6153            }
6154        } finally {
6155            Binder.restoreCallingIdentity(token);
6156        }
6157    }
6158
6159    final void finishBooting() {
6160        synchronized (this) {
6161            if (!mBootAnimationComplete) {
6162                mCallFinishBooting = true;
6163                return;
6164            }
6165            mCallFinishBooting = false;
6166        }
6167
6168        ArraySet<String> completedIsas = new ArraySet<String>();
6169        for (String abi : Build.SUPPORTED_ABIS) {
6170            Process.establishZygoteConnectionForAbi(abi);
6171            final String instructionSet = VMRuntime.getInstructionSet(abi);
6172            if (!completedIsas.contains(instructionSet)) {
6173                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6174                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6175                }
6176                completedIsas.add(instructionSet);
6177            }
6178        }
6179
6180        IntentFilter pkgFilter = new IntentFilter();
6181        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6182        pkgFilter.addDataScheme("package");
6183        mContext.registerReceiver(new BroadcastReceiver() {
6184            @Override
6185            public void onReceive(Context context, Intent intent) {
6186                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6187                if (pkgs != null) {
6188                    for (String pkg : pkgs) {
6189                        synchronized (ActivityManagerService.this) {
6190                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6191                                    0, "query restart")) {
6192                                setResultCode(Activity.RESULT_OK);
6193                                return;
6194                            }
6195                        }
6196                    }
6197                }
6198            }
6199        }, pkgFilter);
6200
6201        IntentFilter dumpheapFilter = new IntentFilter();
6202        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6203        mContext.registerReceiver(new BroadcastReceiver() {
6204            @Override
6205            public void onReceive(Context context, Intent intent) {
6206                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6207                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6208                } else {
6209                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6210                }
6211            }
6212        }, dumpheapFilter);
6213
6214        // Let system services know.
6215        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6216
6217        synchronized (this) {
6218            // Ensure that any processes we had put on hold are now started
6219            // up.
6220            final int NP = mProcessesOnHold.size();
6221            if (NP > 0) {
6222                ArrayList<ProcessRecord> procs =
6223                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6224                for (int ip=0; ip<NP; ip++) {
6225                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6226                            + procs.get(ip));
6227                    startProcessLocked(procs.get(ip), "on-hold", null);
6228                }
6229            }
6230
6231            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6232                // Start looking for apps that are abusing wake locks.
6233                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6234                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6235                // Tell anyone interested that we are done booting!
6236                SystemProperties.set("sys.boot_completed", "1");
6237
6238                // And trigger dev.bootcomplete if we are not showing encryption progress
6239                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6240                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6241                    SystemProperties.set("dev.bootcomplete", "1");
6242                }
6243                for (int i=0; i<mStartedUsers.size(); i++) {
6244                    UserStartedState uss = mStartedUsers.valueAt(i);
6245                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6246                        uss.mState = UserStartedState.STATE_RUNNING;
6247                        final int userId = mStartedUsers.keyAt(i);
6248                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6249                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6250                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6251                        broadcastIntentLocked(null, null, intent, null,
6252                                new IIntentReceiver.Stub() {
6253                                    @Override
6254                                    public void performReceive(Intent intent, int resultCode,
6255                                            String data, Bundle extras, boolean ordered,
6256                                            boolean sticky, int sendingUser) {
6257                                        synchronized (ActivityManagerService.this) {
6258                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6259                                                    true, false);
6260                                        }
6261                                    }
6262                                },
6263                                0, null, null,
6264                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6265                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6266                                userId);
6267                    }
6268                }
6269                scheduleStartProfilesLocked();
6270            }
6271        }
6272    }
6273
6274    @Override
6275    public void bootAnimationComplete() {
6276        final boolean callFinishBooting;
6277        synchronized (this) {
6278            callFinishBooting = mCallFinishBooting;
6279            mBootAnimationComplete = true;
6280        }
6281        if (callFinishBooting) {
6282            finishBooting();
6283        }
6284    }
6285
6286    @Override
6287    public void systemBackupRestored() {
6288        synchronized (this) {
6289            if (mSystemReady) {
6290                mTaskPersister.restoreTasksFromOtherDeviceLocked();
6291            } else {
6292                Slog.w(TAG, "System backup restored before system is ready");
6293            }
6294        }
6295    }
6296
6297    final void ensureBootCompleted() {
6298        boolean booting;
6299        boolean enableScreen;
6300        synchronized (this) {
6301            booting = mBooting;
6302            mBooting = false;
6303            enableScreen = !mBooted;
6304            mBooted = true;
6305        }
6306
6307        if (booting) {
6308            finishBooting();
6309        }
6310
6311        if (enableScreen) {
6312            enableScreenAfterBoot();
6313        }
6314    }
6315
6316    @Override
6317    public final void activityResumed(IBinder token) {
6318        final long origId = Binder.clearCallingIdentity();
6319        synchronized(this) {
6320            ActivityStack stack = ActivityRecord.getStackLocked(token);
6321            if (stack != null) {
6322                ActivityRecord.activityResumedLocked(token);
6323            }
6324        }
6325        Binder.restoreCallingIdentity(origId);
6326    }
6327
6328    @Override
6329    public final void activityPaused(IBinder token) {
6330        final long origId = Binder.clearCallingIdentity();
6331        synchronized(this) {
6332            ActivityStack stack = ActivityRecord.getStackLocked(token);
6333            if (stack != null) {
6334                stack.activityPausedLocked(token, false);
6335            }
6336        }
6337        Binder.restoreCallingIdentity(origId);
6338    }
6339
6340    @Override
6341    public final void activityStopped(IBinder token, Bundle icicle,
6342            PersistableBundle persistentState, CharSequence description) {
6343        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6344
6345        // Refuse possible leaked file descriptors
6346        if (icicle != null && icicle.hasFileDescriptors()) {
6347            throw new IllegalArgumentException("File descriptors passed in Bundle");
6348        }
6349
6350        final long origId = Binder.clearCallingIdentity();
6351
6352        synchronized (this) {
6353            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6354            if (r != null) {
6355                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6356            }
6357        }
6358
6359        trimApplications();
6360
6361        Binder.restoreCallingIdentity(origId);
6362    }
6363
6364    @Override
6365    public final void activityDestroyed(IBinder token) {
6366        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6367        synchronized (this) {
6368            ActivityStack stack = ActivityRecord.getStackLocked(token);
6369            if (stack != null) {
6370                stack.activityDestroyedLocked(token, "activityDestroyed");
6371            }
6372        }
6373    }
6374
6375    @Override
6376    public final void backgroundResourcesReleased(IBinder token) {
6377        final long origId = Binder.clearCallingIdentity();
6378        try {
6379            synchronized (this) {
6380                ActivityStack stack = ActivityRecord.getStackLocked(token);
6381                if (stack != null) {
6382                    stack.backgroundResourcesReleased();
6383                }
6384            }
6385        } finally {
6386            Binder.restoreCallingIdentity(origId);
6387        }
6388    }
6389
6390    @Override
6391    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6392        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6393    }
6394
6395    @Override
6396    public final void notifyEnterAnimationComplete(IBinder token) {
6397        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6398    }
6399
6400    @Override
6401    public String getCallingPackage(IBinder token) {
6402        synchronized (this) {
6403            ActivityRecord r = getCallingRecordLocked(token);
6404            return r != null ? r.info.packageName : null;
6405        }
6406    }
6407
6408    @Override
6409    public ComponentName getCallingActivity(IBinder token) {
6410        synchronized (this) {
6411            ActivityRecord r = getCallingRecordLocked(token);
6412            return r != null ? r.intent.getComponent() : null;
6413        }
6414    }
6415
6416    private ActivityRecord getCallingRecordLocked(IBinder token) {
6417        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6418        if (r == null) {
6419            return null;
6420        }
6421        return r.resultTo;
6422    }
6423
6424    @Override
6425    public ComponentName getActivityClassForToken(IBinder token) {
6426        synchronized(this) {
6427            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6428            if (r == null) {
6429                return null;
6430            }
6431            return r.intent.getComponent();
6432        }
6433    }
6434
6435    @Override
6436    public String getPackageForToken(IBinder token) {
6437        synchronized(this) {
6438            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6439            if (r == null) {
6440                return null;
6441            }
6442            return r.packageName;
6443        }
6444    }
6445
6446    @Override
6447    public IIntentSender getIntentSender(int type,
6448            String packageName, IBinder token, String resultWho,
6449            int requestCode, Intent[] intents, String[] resolvedTypes,
6450            int flags, Bundle options, int userId) {
6451        enforceNotIsolatedCaller("getIntentSender");
6452        // Refuse possible leaked file descriptors
6453        if (intents != null) {
6454            if (intents.length < 1) {
6455                throw new IllegalArgumentException("Intents array length must be >= 1");
6456            }
6457            for (int i=0; i<intents.length; i++) {
6458                Intent intent = intents[i];
6459                if (intent != null) {
6460                    if (intent.hasFileDescriptors()) {
6461                        throw new IllegalArgumentException("File descriptors passed in Intent");
6462                    }
6463                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6464                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6465                        throw new IllegalArgumentException(
6466                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6467                    }
6468                    intents[i] = new Intent(intent);
6469                }
6470            }
6471            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6472                throw new IllegalArgumentException(
6473                        "Intent array length does not match resolvedTypes length");
6474            }
6475        }
6476        if (options != null) {
6477            if (options.hasFileDescriptors()) {
6478                throw new IllegalArgumentException("File descriptors passed in options");
6479            }
6480        }
6481
6482        synchronized(this) {
6483            int callingUid = Binder.getCallingUid();
6484            int origUserId = userId;
6485            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6486                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6487                    ALLOW_NON_FULL, "getIntentSender", null);
6488            if (origUserId == UserHandle.USER_CURRENT) {
6489                // We don't want to evaluate this until the pending intent is
6490                // actually executed.  However, we do want to always do the
6491                // security checking for it above.
6492                userId = UserHandle.USER_CURRENT;
6493            }
6494            try {
6495                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6496                    int uid = AppGlobals.getPackageManager()
6497                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6498                    if (!UserHandle.isSameApp(callingUid, uid)) {
6499                        String msg = "Permission Denial: getIntentSender() from pid="
6500                            + Binder.getCallingPid()
6501                            + ", uid=" + Binder.getCallingUid()
6502                            + ", (need uid=" + uid + ")"
6503                            + " is not allowed to send as package " + packageName;
6504                        Slog.w(TAG, msg);
6505                        throw new SecurityException(msg);
6506                    }
6507                }
6508
6509                return getIntentSenderLocked(type, packageName, callingUid, userId,
6510                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6511
6512            } catch (RemoteException e) {
6513                throw new SecurityException(e);
6514            }
6515        }
6516    }
6517
6518    IIntentSender getIntentSenderLocked(int type, String packageName,
6519            int callingUid, int userId, IBinder token, String resultWho,
6520            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6521            Bundle options) {
6522        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6523        ActivityRecord activity = null;
6524        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6525            activity = ActivityRecord.isInStackLocked(token);
6526            if (activity == null) {
6527                return null;
6528            }
6529            if (activity.finishing) {
6530                return null;
6531            }
6532        }
6533
6534        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6535        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6536        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6537        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6538                |PendingIntent.FLAG_UPDATE_CURRENT);
6539
6540        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6541                type, packageName, activity, resultWho,
6542                requestCode, intents, resolvedTypes, flags, options, userId);
6543        WeakReference<PendingIntentRecord> ref;
6544        ref = mIntentSenderRecords.get(key);
6545        PendingIntentRecord rec = ref != null ? ref.get() : null;
6546        if (rec != null) {
6547            if (!cancelCurrent) {
6548                if (updateCurrent) {
6549                    if (rec.key.requestIntent != null) {
6550                        rec.key.requestIntent.replaceExtras(intents != null ?
6551                                intents[intents.length - 1] : null);
6552                    }
6553                    if (intents != null) {
6554                        intents[intents.length-1] = rec.key.requestIntent;
6555                        rec.key.allIntents = intents;
6556                        rec.key.allResolvedTypes = resolvedTypes;
6557                    } else {
6558                        rec.key.allIntents = null;
6559                        rec.key.allResolvedTypes = null;
6560                    }
6561                }
6562                return rec;
6563            }
6564            rec.canceled = true;
6565            mIntentSenderRecords.remove(key);
6566        }
6567        if (noCreate) {
6568            return rec;
6569        }
6570        rec = new PendingIntentRecord(this, key, callingUid);
6571        mIntentSenderRecords.put(key, rec.ref);
6572        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6573            if (activity.pendingResults == null) {
6574                activity.pendingResults
6575                        = new HashSet<WeakReference<PendingIntentRecord>>();
6576            }
6577            activity.pendingResults.add(rec.ref);
6578        }
6579        return rec;
6580    }
6581
6582    @Override
6583    public void cancelIntentSender(IIntentSender sender) {
6584        if (!(sender instanceof PendingIntentRecord)) {
6585            return;
6586        }
6587        synchronized(this) {
6588            PendingIntentRecord rec = (PendingIntentRecord)sender;
6589            try {
6590                int uid = AppGlobals.getPackageManager()
6591                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6592                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6593                    String msg = "Permission Denial: cancelIntentSender() from pid="
6594                        + Binder.getCallingPid()
6595                        + ", uid=" + Binder.getCallingUid()
6596                        + " is not allowed to cancel packges "
6597                        + rec.key.packageName;
6598                    Slog.w(TAG, msg);
6599                    throw new SecurityException(msg);
6600                }
6601            } catch (RemoteException e) {
6602                throw new SecurityException(e);
6603            }
6604            cancelIntentSenderLocked(rec, true);
6605        }
6606    }
6607
6608    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6609        rec.canceled = true;
6610        mIntentSenderRecords.remove(rec.key);
6611        if (cleanActivity && rec.key.activity != null) {
6612            rec.key.activity.pendingResults.remove(rec.ref);
6613        }
6614    }
6615
6616    @Override
6617    public String getPackageForIntentSender(IIntentSender pendingResult) {
6618        if (!(pendingResult instanceof PendingIntentRecord)) {
6619            return null;
6620        }
6621        try {
6622            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6623            return res.key.packageName;
6624        } catch (ClassCastException e) {
6625        }
6626        return null;
6627    }
6628
6629    @Override
6630    public int getUidForIntentSender(IIntentSender sender) {
6631        if (sender instanceof PendingIntentRecord) {
6632            try {
6633                PendingIntentRecord res = (PendingIntentRecord)sender;
6634                return res.uid;
6635            } catch (ClassCastException e) {
6636            }
6637        }
6638        return -1;
6639    }
6640
6641    @Override
6642    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6643        if (!(pendingResult instanceof PendingIntentRecord)) {
6644            return false;
6645        }
6646        try {
6647            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6648            if (res.key.allIntents == null) {
6649                return false;
6650            }
6651            for (int i=0; i<res.key.allIntents.length; i++) {
6652                Intent intent = res.key.allIntents[i];
6653                if (intent.getPackage() != null && intent.getComponent() != null) {
6654                    return false;
6655                }
6656            }
6657            return true;
6658        } catch (ClassCastException e) {
6659        }
6660        return false;
6661    }
6662
6663    @Override
6664    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6665        if (!(pendingResult instanceof PendingIntentRecord)) {
6666            return false;
6667        }
6668        try {
6669            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6670            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6671                return true;
6672            }
6673            return false;
6674        } catch (ClassCastException e) {
6675        }
6676        return false;
6677    }
6678
6679    @Override
6680    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6681        if (!(pendingResult instanceof PendingIntentRecord)) {
6682            return null;
6683        }
6684        try {
6685            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6686            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6687        } catch (ClassCastException e) {
6688        }
6689        return null;
6690    }
6691
6692    @Override
6693    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6694        if (!(pendingResult instanceof PendingIntentRecord)) {
6695            return null;
6696        }
6697        try {
6698            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6699            synchronized (this) {
6700                return getTagForIntentSenderLocked(res, prefix);
6701            }
6702        } catch (ClassCastException e) {
6703        }
6704        return null;
6705    }
6706
6707    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6708        final Intent intent = res.key.requestIntent;
6709        if (intent != null) {
6710            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6711                    || res.lastTagPrefix.equals(prefix))) {
6712                return res.lastTag;
6713            }
6714            res.lastTagPrefix = prefix;
6715            final StringBuilder sb = new StringBuilder(128);
6716            if (prefix != null) {
6717                sb.append(prefix);
6718            }
6719            if (intent.getAction() != null) {
6720                sb.append(intent.getAction());
6721            } else if (intent.getComponent() != null) {
6722                intent.getComponent().appendShortString(sb);
6723            } else {
6724                sb.append("?");
6725            }
6726            return res.lastTag = sb.toString();
6727        }
6728        return null;
6729    }
6730
6731    @Override
6732    public void setProcessLimit(int max) {
6733        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6734                "setProcessLimit()");
6735        synchronized (this) {
6736            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6737            mProcessLimitOverride = max;
6738        }
6739        trimApplications();
6740    }
6741
6742    @Override
6743    public int getProcessLimit() {
6744        synchronized (this) {
6745            return mProcessLimitOverride;
6746        }
6747    }
6748
6749    void foregroundTokenDied(ForegroundToken token) {
6750        synchronized (ActivityManagerService.this) {
6751            synchronized (mPidsSelfLocked) {
6752                ForegroundToken cur
6753                    = mForegroundProcesses.get(token.pid);
6754                if (cur != token) {
6755                    return;
6756                }
6757                mForegroundProcesses.remove(token.pid);
6758                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6759                if (pr == null) {
6760                    return;
6761                }
6762                pr.forcingToForeground = null;
6763                updateProcessForegroundLocked(pr, false, false);
6764            }
6765            updateOomAdjLocked();
6766        }
6767    }
6768
6769    @Override
6770    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6771        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6772                "setProcessForeground()");
6773        synchronized(this) {
6774            boolean changed = false;
6775
6776            synchronized (mPidsSelfLocked) {
6777                ProcessRecord pr = mPidsSelfLocked.get(pid);
6778                if (pr == null && isForeground) {
6779                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6780                    return;
6781                }
6782                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6783                if (oldToken != null) {
6784                    oldToken.token.unlinkToDeath(oldToken, 0);
6785                    mForegroundProcesses.remove(pid);
6786                    if (pr != null) {
6787                        pr.forcingToForeground = null;
6788                    }
6789                    changed = true;
6790                }
6791                if (isForeground && token != null) {
6792                    ForegroundToken newToken = new ForegroundToken() {
6793                        @Override
6794                        public void binderDied() {
6795                            foregroundTokenDied(this);
6796                        }
6797                    };
6798                    newToken.pid = pid;
6799                    newToken.token = token;
6800                    try {
6801                        token.linkToDeath(newToken, 0);
6802                        mForegroundProcesses.put(pid, newToken);
6803                        pr.forcingToForeground = token;
6804                        changed = true;
6805                    } catch (RemoteException e) {
6806                        // If the process died while doing this, we will later
6807                        // do the cleanup with the process death link.
6808                    }
6809                }
6810            }
6811
6812            if (changed) {
6813                updateOomAdjLocked();
6814            }
6815        }
6816    }
6817
6818    // =========================================================
6819    // PROCESS INFO
6820    // =========================================================
6821
6822    static class ProcessInfoService extends IProcessInfoService.Stub {
6823        final ActivityManagerService mActivityManagerService;
6824        ProcessInfoService(ActivityManagerService activityManagerService) {
6825            mActivityManagerService = activityManagerService;
6826        }
6827
6828        @Override
6829        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6830            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6831        }
6832    }
6833
6834    /**
6835     * For each PID in the given input array, write the current process state
6836     * for that process into the output array, or -1 to indicate that no
6837     * process with the given PID exists.
6838     */
6839    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6840        if (pids == null) {
6841            throw new NullPointerException("pids");
6842        } else if (states == null) {
6843            throw new NullPointerException("states");
6844        } else if (pids.length != states.length) {
6845            throw new IllegalArgumentException("input and output arrays have different lengths!");
6846        }
6847
6848        synchronized (mPidsSelfLocked) {
6849            for (int i = 0; i < pids.length; i++) {
6850                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6851                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6852                        pr.curProcState;
6853            }
6854        }
6855    }
6856
6857    // =========================================================
6858    // PERMISSIONS
6859    // =========================================================
6860
6861    static class PermissionController extends IPermissionController.Stub {
6862        ActivityManagerService mActivityManagerService;
6863        PermissionController(ActivityManagerService activityManagerService) {
6864            mActivityManagerService = activityManagerService;
6865        }
6866
6867        @Override
6868        public boolean checkPermission(String permission, int pid, int uid) {
6869            return mActivityManagerService.checkPermission(permission, pid,
6870                    uid) == PackageManager.PERMISSION_GRANTED;
6871        }
6872
6873        @Override
6874        public String[] getPackagesForUid(int uid) {
6875            return mActivityManagerService.mContext.getPackageManager()
6876                    .getPackagesForUid(uid);
6877        }
6878
6879        @Override
6880        public boolean isRuntimePermission(String permission) {
6881            try {
6882                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
6883                        .getPermissionInfo(permission, 0);
6884                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
6885            } catch (NameNotFoundException nnfe) {
6886                Slog.e(TAG, "No such permission: "+ permission, nnfe);
6887            }
6888            return false;
6889        }
6890    }
6891
6892    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6893        @Override
6894        public int checkComponentPermission(String permission, int pid, int uid,
6895                int owningUid, boolean exported) {
6896            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6897                    owningUid, exported);
6898        }
6899
6900        @Override
6901        public Object getAMSLock() {
6902            return ActivityManagerService.this;
6903        }
6904    }
6905
6906    /**
6907     * This can be called with or without the global lock held.
6908     */
6909    int checkComponentPermission(String permission, int pid, int uid,
6910            int owningUid, boolean exported) {
6911        if (pid == MY_PID) {
6912            return PackageManager.PERMISSION_GRANTED;
6913        }
6914        return ActivityManager.checkComponentPermission(permission, uid,
6915                owningUid, exported);
6916    }
6917
6918    /**
6919     * As the only public entry point for permissions checking, this method
6920     * can enforce the semantic that requesting a check on a null global
6921     * permission is automatically denied.  (Internally a null permission
6922     * string is used when calling {@link #checkComponentPermission} in cases
6923     * when only uid-based security is needed.)
6924     *
6925     * This can be called with or without the global lock held.
6926     */
6927    @Override
6928    public int checkPermission(String permission, int pid, int uid) {
6929        if (permission == null) {
6930            return PackageManager.PERMISSION_DENIED;
6931        }
6932        return checkComponentPermission(permission, pid, uid, -1, true);
6933    }
6934
6935    @Override
6936    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6937        if (permission == null) {
6938            return PackageManager.PERMISSION_DENIED;
6939        }
6940
6941        // We might be performing an operation on behalf of an indirect binder
6942        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6943        // client identity accordingly before proceeding.
6944        Identity tlsIdentity = sCallerIdentity.get();
6945        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6946            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6947                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6948            uid = tlsIdentity.uid;
6949            pid = tlsIdentity.pid;
6950        }
6951
6952        return checkComponentPermission(permission, pid, uid, -1, true);
6953    }
6954
6955    /**
6956     * Binder IPC calls go through the public entry point.
6957     * This can be called with or without the global lock held.
6958     */
6959    int checkCallingPermission(String permission) {
6960        return checkPermission(permission,
6961                Binder.getCallingPid(),
6962                UserHandle.getAppId(Binder.getCallingUid()));
6963    }
6964
6965    /**
6966     * This can be called with or without the global lock held.
6967     */
6968    void enforceCallingPermission(String permission, String func) {
6969        if (checkCallingPermission(permission)
6970                == PackageManager.PERMISSION_GRANTED) {
6971            return;
6972        }
6973
6974        String msg = "Permission Denial: " + func + " from pid="
6975                + Binder.getCallingPid()
6976                + ", uid=" + Binder.getCallingUid()
6977                + " requires " + permission;
6978        Slog.w(TAG, msg);
6979        throw new SecurityException(msg);
6980    }
6981
6982    /**
6983     * Determine if UID is holding permissions required to access {@link Uri} in
6984     * the given {@link ProviderInfo}. Final permission checking is always done
6985     * in {@link ContentProvider}.
6986     */
6987    private final boolean checkHoldingPermissionsLocked(
6988            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6989        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6990                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6991        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6992            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6993                    != PERMISSION_GRANTED) {
6994                return false;
6995            }
6996        }
6997        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6998    }
6999
7000    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7001            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7002        if (pi.applicationInfo.uid == uid) {
7003            return true;
7004        } else if (!pi.exported) {
7005            return false;
7006        }
7007
7008        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7009        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7010        try {
7011            // check if target holds top-level <provider> permissions
7012            if (!readMet && pi.readPermission != null && considerUidPermissions
7013                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7014                readMet = true;
7015            }
7016            if (!writeMet && pi.writePermission != null && considerUidPermissions
7017                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7018                writeMet = true;
7019            }
7020
7021            // track if unprotected read/write is allowed; any denied
7022            // <path-permission> below removes this ability
7023            boolean allowDefaultRead = pi.readPermission == null;
7024            boolean allowDefaultWrite = pi.writePermission == null;
7025
7026            // check if target holds any <path-permission> that match uri
7027            final PathPermission[] pps = pi.pathPermissions;
7028            if (pps != null) {
7029                final String path = grantUri.uri.getPath();
7030                int i = pps.length;
7031                while (i > 0 && (!readMet || !writeMet)) {
7032                    i--;
7033                    PathPermission pp = pps[i];
7034                    if (pp.match(path)) {
7035                        if (!readMet) {
7036                            final String pprperm = pp.getReadPermission();
7037                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7038                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7039                                    + ": match=" + pp.match(path)
7040                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7041                            if (pprperm != null) {
7042                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7043                                        == PERMISSION_GRANTED) {
7044                                    readMet = true;
7045                                } else {
7046                                    allowDefaultRead = false;
7047                                }
7048                            }
7049                        }
7050                        if (!writeMet) {
7051                            final String ppwperm = pp.getWritePermission();
7052                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7053                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7054                                    + ": match=" + pp.match(path)
7055                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7056                            if (ppwperm != null) {
7057                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7058                                        == PERMISSION_GRANTED) {
7059                                    writeMet = true;
7060                                } else {
7061                                    allowDefaultWrite = false;
7062                                }
7063                            }
7064                        }
7065                    }
7066                }
7067            }
7068
7069            // grant unprotected <provider> read/write, if not blocked by
7070            // <path-permission> above
7071            if (allowDefaultRead) readMet = true;
7072            if (allowDefaultWrite) writeMet = true;
7073
7074        } catch (RemoteException e) {
7075            return false;
7076        }
7077
7078        return readMet && writeMet;
7079    }
7080
7081    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7082        ProviderInfo pi = null;
7083        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7084        if (cpr != null) {
7085            pi = cpr.info;
7086        } else {
7087            try {
7088                pi = AppGlobals.getPackageManager().resolveContentProvider(
7089                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7090            } catch (RemoteException ex) {
7091            }
7092        }
7093        return pi;
7094    }
7095
7096    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7097        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7098        if (targetUris != null) {
7099            return targetUris.get(grantUri);
7100        }
7101        return null;
7102    }
7103
7104    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7105            String targetPkg, int targetUid, GrantUri grantUri) {
7106        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7107        if (targetUris == null) {
7108            targetUris = Maps.newArrayMap();
7109            mGrantedUriPermissions.put(targetUid, targetUris);
7110        }
7111
7112        UriPermission perm = targetUris.get(grantUri);
7113        if (perm == null) {
7114            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7115            targetUris.put(grantUri, perm);
7116        }
7117
7118        return perm;
7119    }
7120
7121    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7122            final int modeFlags) {
7123        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7124        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7125                : UriPermission.STRENGTH_OWNED;
7126
7127        // Root gets to do everything.
7128        if (uid == 0) {
7129            return true;
7130        }
7131
7132        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7133        if (perms == null) return false;
7134
7135        // First look for exact match
7136        final UriPermission exactPerm = perms.get(grantUri);
7137        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7138            return true;
7139        }
7140
7141        // No exact match, look for prefixes
7142        final int N = perms.size();
7143        for (int i = 0; i < N; i++) {
7144            final UriPermission perm = perms.valueAt(i);
7145            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7146                    && perm.getStrength(modeFlags) >= minStrength) {
7147                return true;
7148            }
7149        }
7150
7151        return false;
7152    }
7153
7154    /**
7155     * @param uri This uri must NOT contain an embedded userId.
7156     * @param userId The userId in which the uri is to be resolved.
7157     */
7158    @Override
7159    public int checkUriPermission(Uri uri, int pid, int uid,
7160            final int modeFlags, int userId, IBinder callerToken) {
7161        enforceNotIsolatedCaller("checkUriPermission");
7162
7163        // Another redirected-binder-call permissions check as in
7164        // {@link checkPermissionWithToken}.
7165        Identity tlsIdentity = sCallerIdentity.get();
7166        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7167            uid = tlsIdentity.uid;
7168            pid = tlsIdentity.pid;
7169        }
7170
7171        // Our own process gets to do everything.
7172        if (pid == MY_PID) {
7173            return PackageManager.PERMISSION_GRANTED;
7174        }
7175        synchronized (this) {
7176            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7177                    ? PackageManager.PERMISSION_GRANTED
7178                    : PackageManager.PERMISSION_DENIED;
7179        }
7180    }
7181
7182    /**
7183     * Check if the targetPkg can be granted permission to access uri by
7184     * the callingUid using the given modeFlags.  Throws a security exception
7185     * if callingUid is not allowed to do this.  Returns the uid of the target
7186     * if the URI permission grant should be performed; returns -1 if it is not
7187     * needed (for example targetPkg already has permission to access the URI).
7188     * If you already know the uid of the target, you can supply it in
7189     * lastTargetUid else set that to -1.
7190     */
7191    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7192            final int modeFlags, int lastTargetUid) {
7193        if (!Intent.isAccessUriMode(modeFlags)) {
7194            return -1;
7195        }
7196
7197        if (targetPkg != null) {
7198            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7199                    "Checking grant " + targetPkg + " permission to " + grantUri);
7200        }
7201
7202        final IPackageManager pm = AppGlobals.getPackageManager();
7203
7204        // If this is not a content: uri, we can't do anything with it.
7205        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7206            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7207                    "Can't grant URI permission for non-content URI: " + grantUri);
7208            return -1;
7209        }
7210
7211        final String authority = grantUri.uri.getAuthority();
7212        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7213        if (pi == null) {
7214            Slog.w(TAG, "No content provider found for permission check: " +
7215                    grantUri.uri.toSafeString());
7216            return -1;
7217        }
7218
7219        int targetUid = lastTargetUid;
7220        if (targetUid < 0 && targetPkg != null) {
7221            try {
7222                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7223                if (targetUid < 0) {
7224                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7225                            "Can't grant URI permission no uid for: " + targetPkg);
7226                    return -1;
7227                }
7228            } catch (RemoteException ex) {
7229                return -1;
7230            }
7231        }
7232
7233        if (targetUid >= 0) {
7234            // First...  does the target actually need this permission?
7235            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7236                // No need to grant the target this permission.
7237                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7238                        "Target " + targetPkg + " already has full permission to " + grantUri);
7239                return -1;
7240            }
7241        } else {
7242            // First...  there is no target package, so can anyone access it?
7243            boolean allowed = pi.exported;
7244            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7245                if (pi.readPermission != null) {
7246                    allowed = false;
7247                }
7248            }
7249            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7250                if (pi.writePermission != null) {
7251                    allowed = false;
7252                }
7253            }
7254            if (allowed) {
7255                return -1;
7256            }
7257        }
7258
7259        /* There is a special cross user grant if:
7260         * - The target is on another user.
7261         * - Apps on the current user can access the uri without any uid permissions.
7262         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7263         * grant uri permissions.
7264         */
7265        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7266                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7267                modeFlags, false /*without considering the uid permissions*/);
7268
7269        // Second...  is the provider allowing granting of URI permissions?
7270        if (!specialCrossUserGrant) {
7271            if (!pi.grantUriPermissions) {
7272                throw new SecurityException("Provider " + pi.packageName
7273                        + "/" + pi.name
7274                        + " does not allow granting of Uri permissions (uri "
7275                        + grantUri + ")");
7276            }
7277            if (pi.uriPermissionPatterns != null) {
7278                final int N = pi.uriPermissionPatterns.length;
7279                boolean allowed = false;
7280                for (int i=0; i<N; i++) {
7281                    if (pi.uriPermissionPatterns[i] != null
7282                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7283                        allowed = true;
7284                        break;
7285                    }
7286                }
7287                if (!allowed) {
7288                    throw new SecurityException("Provider " + pi.packageName
7289                            + "/" + pi.name
7290                            + " does not allow granting of permission to path of Uri "
7291                            + grantUri);
7292                }
7293            }
7294        }
7295
7296        // Third...  does the caller itself have permission to access
7297        // this uri?
7298        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7299            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7300                // Require they hold a strong enough Uri permission
7301                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7302                    throw new SecurityException("Uid " + callingUid
7303                            + " does not have permission to uri " + grantUri);
7304                }
7305            }
7306        }
7307        return targetUid;
7308    }
7309
7310    /**
7311     * @param uri This uri must NOT contain an embedded userId.
7312     * @param userId The userId in which the uri is to be resolved.
7313     */
7314    @Override
7315    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7316            final int modeFlags, int userId) {
7317        enforceNotIsolatedCaller("checkGrantUriPermission");
7318        synchronized(this) {
7319            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7320                    new GrantUri(userId, uri, false), modeFlags, -1);
7321        }
7322    }
7323
7324    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7325            final int modeFlags, UriPermissionOwner owner) {
7326        if (!Intent.isAccessUriMode(modeFlags)) {
7327            return;
7328        }
7329
7330        // So here we are: the caller has the assumed permission
7331        // to the uri, and the target doesn't.  Let's now give this to
7332        // the target.
7333
7334        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7335                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7336
7337        final String authority = grantUri.uri.getAuthority();
7338        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7339        if (pi == null) {
7340            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7341            return;
7342        }
7343
7344        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7345            grantUri.prefix = true;
7346        }
7347        final UriPermission perm = findOrCreateUriPermissionLocked(
7348                pi.packageName, targetPkg, targetUid, grantUri);
7349        perm.grantModes(modeFlags, owner);
7350    }
7351
7352    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7353            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7354        if (targetPkg == null) {
7355            throw new NullPointerException("targetPkg");
7356        }
7357        int targetUid;
7358        final IPackageManager pm = AppGlobals.getPackageManager();
7359        try {
7360            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7361        } catch (RemoteException ex) {
7362            return;
7363        }
7364
7365        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7366                targetUid);
7367        if (targetUid < 0) {
7368            return;
7369        }
7370
7371        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7372                owner);
7373    }
7374
7375    static class NeededUriGrants extends ArrayList<GrantUri> {
7376        final String targetPkg;
7377        final int targetUid;
7378        final int flags;
7379
7380        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7381            this.targetPkg = targetPkg;
7382            this.targetUid = targetUid;
7383            this.flags = flags;
7384        }
7385    }
7386
7387    /**
7388     * Like checkGrantUriPermissionLocked, but takes an Intent.
7389     */
7390    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7391            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7392        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7393                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7394                + " clip=" + (intent != null ? intent.getClipData() : null)
7395                + " from " + intent + "; flags=0x"
7396                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7397
7398        if (targetPkg == null) {
7399            throw new NullPointerException("targetPkg");
7400        }
7401
7402        if (intent == null) {
7403            return null;
7404        }
7405        Uri data = intent.getData();
7406        ClipData clip = intent.getClipData();
7407        if (data == null && clip == null) {
7408            return null;
7409        }
7410        // Default userId for uris in the intent (if they don't specify it themselves)
7411        int contentUserHint = intent.getContentUserHint();
7412        if (contentUserHint == UserHandle.USER_CURRENT) {
7413            contentUserHint = UserHandle.getUserId(callingUid);
7414        }
7415        final IPackageManager pm = AppGlobals.getPackageManager();
7416        int targetUid;
7417        if (needed != null) {
7418            targetUid = needed.targetUid;
7419        } else {
7420            try {
7421                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7422            } catch (RemoteException ex) {
7423                return null;
7424            }
7425            if (targetUid < 0) {
7426                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7427                        "Can't grant URI permission no uid for: " + targetPkg
7428                        + " on user " + targetUserId);
7429                return null;
7430            }
7431        }
7432        if (data != null) {
7433            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7434            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7435                    targetUid);
7436            if (targetUid > 0) {
7437                if (needed == null) {
7438                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7439                }
7440                needed.add(grantUri);
7441            }
7442        }
7443        if (clip != null) {
7444            for (int i=0; i<clip.getItemCount(); i++) {
7445                Uri uri = clip.getItemAt(i).getUri();
7446                if (uri != null) {
7447                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7448                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7449                            targetUid);
7450                    if (targetUid > 0) {
7451                        if (needed == null) {
7452                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7453                        }
7454                        needed.add(grantUri);
7455                    }
7456                } else {
7457                    Intent clipIntent = clip.getItemAt(i).getIntent();
7458                    if (clipIntent != null) {
7459                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7460                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7461                        if (newNeeded != null) {
7462                            needed = newNeeded;
7463                        }
7464                    }
7465                }
7466            }
7467        }
7468
7469        return needed;
7470    }
7471
7472    /**
7473     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7474     */
7475    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7476            UriPermissionOwner owner) {
7477        if (needed != null) {
7478            for (int i=0; i<needed.size(); i++) {
7479                GrantUri grantUri = needed.get(i);
7480                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7481                        grantUri, needed.flags, owner);
7482            }
7483        }
7484    }
7485
7486    void grantUriPermissionFromIntentLocked(int callingUid,
7487            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7488        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7489                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7490        if (needed == null) {
7491            return;
7492        }
7493
7494        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7495    }
7496
7497    /**
7498     * @param uri This uri must NOT contain an embedded userId.
7499     * @param userId The userId in which the uri is to be resolved.
7500     */
7501    @Override
7502    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7503            final int modeFlags, int userId) {
7504        enforceNotIsolatedCaller("grantUriPermission");
7505        GrantUri grantUri = new GrantUri(userId, uri, false);
7506        synchronized(this) {
7507            final ProcessRecord r = getRecordForAppLocked(caller);
7508            if (r == null) {
7509                throw new SecurityException("Unable to find app for caller "
7510                        + caller
7511                        + " when granting permission to uri " + grantUri);
7512            }
7513            if (targetPkg == null) {
7514                throw new IllegalArgumentException("null target");
7515            }
7516            if (grantUri == null) {
7517                throw new IllegalArgumentException("null uri");
7518            }
7519
7520            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7521                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7522                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7523                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7524
7525            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7526                    UserHandle.getUserId(r.uid));
7527        }
7528    }
7529
7530    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7531        if (perm.modeFlags == 0) {
7532            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7533                    perm.targetUid);
7534            if (perms != null) {
7535                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7536                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7537
7538                perms.remove(perm.uri);
7539                if (perms.isEmpty()) {
7540                    mGrantedUriPermissions.remove(perm.targetUid);
7541                }
7542            }
7543        }
7544    }
7545
7546    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7547        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7548                "Revoking all granted permissions to " + grantUri);
7549
7550        final IPackageManager pm = AppGlobals.getPackageManager();
7551        final String authority = grantUri.uri.getAuthority();
7552        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7553        if (pi == null) {
7554            Slog.w(TAG, "No content provider found for permission revoke: "
7555                    + grantUri.toSafeString());
7556            return;
7557        }
7558
7559        // Does the caller have this permission on the URI?
7560        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7561            // If they don't have direct access to the URI, then revoke any
7562            // ownerless URI permissions that have been granted to them.
7563            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7564            if (perms != null) {
7565                boolean persistChanged = false;
7566                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7567                    final UriPermission perm = it.next();
7568                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7569                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7570                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7571                                "Revoking non-owned " + perm.targetUid
7572                                + " permission to " + perm.uri);
7573                        persistChanged |= perm.revokeModes(
7574                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7575                        if (perm.modeFlags == 0) {
7576                            it.remove();
7577                        }
7578                    }
7579                }
7580                if (perms.isEmpty()) {
7581                    mGrantedUriPermissions.remove(callingUid);
7582                }
7583                if (persistChanged) {
7584                    schedulePersistUriGrants();
7585                }
7586            }
7587            return;
7588        }
7589
7590        boolean persistChanged = false;
7591
7592        // Go through all of the permissions and remove any that match.
7593        int N = mGrantedUriPermissions.size();
7594        for (int i = 0; i < N; i++) {
7595            final int targetUid = mGrantedUriPermissions.keyAt(i);
7596            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7597
7598            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7599                final UriPermission perm = it.next();
7600                if (perm.uri.sourceUserId == grantUri.sourceUserId
7601                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7602                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7603                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7604                    persistChanged |= perm.revokeModes(
7605                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7606                    if (perm.modeFlags == 0) {
7607                        it.remove();
7608                    }
7609                }
7610            }
7611
7612            if (perms.isEmpty()) {
7613                mGrantedUriPermissions.remove(targetUid);
7614                N--;
7615                i--;
7616            }
7617        }
7618
7619        if (persistChanged) {
7620            schedulePersistUriGrants();
7621        }
7622    }
7623
7624    /**
7625     * @param uri This uri must NOT contain an embedded userId.
7626     * @param userId The userId in which the uri is to be resolved.
7627     */
7628    @Override
7629    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7630            int userId) {
7631        enforceNotIsolatedCaller("revokeUriPermission");
7632        synchronized(this) {
7633            final ProcessRecord r = getRecordForAppLocked(caller);
7634            if (r == null) {
7635                throw new SecurityException("Unable to find app for caller "
7636                        + caller
7637                        + " when revoking permission to uri " + uri);
7638            }
7639            if (uri == null) {
7640                Slog.w(TAG, "revokeUriPermission: null uri");
7641                return;
7642            }
7643
7644            if (!Intent.isAccessUriMode(modeFlags)) {
7645                return;
7646            }
7647
7648            final String authority = uri.getAuthority();
7649            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7650            if (pi == null) {
7651                Slog.w(TAG, "No content provider found for permission revoke: "
7652                        + uri.toSafeString());
7653                return;
7654            }
7655
7656            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7657        }
7658    }
7659
7660    /**
7661     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7662     * given package.
7663     *
7664     * @param packageName Package name to match, or {@code null} to apply to all
7665     *            packages.
7666     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7667     *            to all users.
7668     * @param persistable If persistable grants should be removed.
7669     */
7670    private void removeUriPermissionsForPackageLocked(
7671            String packageName, int userHandle, boolean persistable) {
7672        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7673            throw new IllegalArgumentException("Must narrow by either package or user");
7674        }
7675
7676        boolean persistChanged = false;
7677
7678        int N = mGrantedUriPermissions.size();
7679        for (int i = 0; i < N; i++) {
7680            final int targetUid = mGrantedUriPermissions.keyAt(i);
7681            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7682
7683            // Only inspect grants matching user
7684            if (userHandle == UserHandle.USER_ALL
7685                    || userHandle == UserHandle.getUserId(targetUid)) {
7686                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7687                    final UriPermission perm = it.next();
7688
7689                    // Only inspect grants matching package
7690                    if (packageName == null || perm.sourcePkg.equals(packageName)
7691                            || perm.targetPkg.equals(packageName)) {
7692                        persistChanged |= perm.revokeModes(persistable
7693                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7694
7695                        // Only remove when no modes remain; any persisted grants
7696                        // will keep this alive.
7697                        if (perm.modeFlags == 0) {
7698                            it.remove();
7699                        }
7700                    }
7701                }
7702
7703                if (perms.isEmpty()) {
7704                    mGrantedUriPermissions.remove(targetUid);
7705                    N--;
7706                    i--;
7707                }
7708            }
7709        }
7710
7711        if (persistChanged) {
7712            schedulePersistUriGrants();
7713        }
7714    }
7715
7716    @Override
7717    public IBinder newUriPermissionOwner(String name) {
7718        enforceNotIsolatedCaller("newUriPermissionOwner");
7719        synchronized(this) {
7720            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7721            return owner.getExternalTokenLocked();
7722        }
7723    }
7724
7725    /**
7726     * @param uri This uri must NOT contain an embedded userId.
7727     * @param sourceUserId The userId in which the uri is to be resolved.
7728     * @param targetUserId The userId of the app that receives the grant.
7729     */
7730    @Override
7731    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7732            final int modeFlags, int sourceUserId, int targetUserId) {
7733        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7734                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7735        synchronized(this) {
7736            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7737            if (owner == null) {
7738                throw new IllegalArgumentException("Unknown owner: " + token);
7739            }
7740            if (fromUid != Binder.getCallingUid()) {
7741                if (Binder.getCallingUid() != Process.myUid()) {
7742                    // Only system code can grant URI permissions on behalf
7743                    // of other users.
7744                    throw new SecurityException("nice try");
7745                }
7746            }
7747            if (targetPkg == null) {
7748                throw new IllegalArgumentException("null target");
7749            }
7750            if (uri == null) {
7751                throw new IllegalArgumentException("null uri");
7752            }
7753
7754            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7755                    modeFlags, owner, targetUserId);
7756        }
7757    }
7758
7759    /**
7760     * @param uri This uri must NOT contain an embedded userId.
7761     * @param userId The userId in which the uri is to be resolved.
7762     */
7763    @Override
7764    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7765        synchronized(this) {
7766            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7767            if (owner == null) {
7768                throw new IllegalArgumentException("Unknown owner: " + token);
7769            }
7770
7771            if (uri == null) {
7772                owner.removeUriPermissionsLocked(mode);
7773            } else {
7774                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7775            }
7776        }
7777    }
7778
7779    private void schedulePersistUriGrants() {
7780        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7781            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7782                    10 * DateUtils.SECOND_IN_MILLIS);
7783        }
7784    }
7785
7786    private void writeGrantedUriPermissions() {
7787        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7788
7789        // Snapshot permissions so we can persist without lock
7790        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7791        synchronized (this) {
7792            final int size = mGrantedUriPermissions.size();
7793            for (int i = 0; i < size; i++) {
7794                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7795                for (UriPermission perm : perms.values()) {
7796                    if (perm.persistedModeFlags != 0) {
7797                        persist.add(perm.snapshot());
7798                    }
7799                }
7800            }
7801        }
7802
7803        FileOutputStream fos = null;
7804        try {
7805            fos = mGrantFile.startWrite();
7806
7807            XmlSerializer out = new FastXmlSerializer();
7808            out.setOutput(fos, StandardCharsets.UTF_8.name());
7809            out.startDocument(null, true);
7810            out.startTag(null, TAG_URI_GRANTS);
7811            for (UriPermission.Snapshot perm : persist) {
7812                out.startTag(null, TAG_URI_GRANT);
7813                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7814                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7815                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7816                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7817                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7818                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7819                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7820                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7821                out.endTag(null, TAG_URI_GRANT);
7822            }
7823            out.endTag(null, TAG_URI_GRANTS);
7824            out.endDocument();
7825
7826            mGrantFile.finishWrite(fos);
7827        } catch (IOException e) {
7828            if (fos != null) {
7829                mGrantFile.failWrite(fos);
7830            }
7831        }
7832    }
7833
7834    private void readGrantedUriPermissionsLocked() {
7835        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7836
7837        final long now = System.currentTimeMillis();
7838
7839        FileInputStream fis = null;
7840        try {
7841            fis = mGrantFile.openRead();
7842            final XmlPullParser in = Xml.newPullParser();
7843            in.setInput(fis, StandardCharsets.UTF_8.name());
7844
7845            int type;
7846            while ((type = in.next()) != END_DOCUMENT) {
7847                final String tag = in.getName();
7848                if (type == START_TAG) {
7849                    if (TAG_URI_GRANT.equals(tag)) {
7850                        final int sourceUserId;
7851                        final int targetUserId;
7852                        final int userHandle = readIntAttribute(in,
7853                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7854                        if (userHandle != UserHandle.USER_NULL) {
7855                            // For backwards compatibility.
7856                            sourceUserId = userHandle;
7857                            targetUserId = userHandle;
7858                        } else {
7859                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7860                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7861                        }
7862                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7863                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7864                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7865                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7866                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7867                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7868
7869                        // Sanity check that provider still belongs to source package
7870                        final ProviderInfo pi = getProviderInfoLocked(
7871                                uri.getAuthority(), sourceUserId);
7872                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7873                            int targetUid = -1;
7874                            try {
7875                                targetUid = AppGlobals.getPackageManager()
7876                                        .getPackageUid(targetPkg, targetUserId);
7877                            } catch (RemoteException e) {
7878                            }
7879                            if (targetUid != -1) {
7880                                final UriPermission perm = findOrCreateUriPermissionLocked(
7881                                        sourcePkg, targetPkg, targetUid,
7882                                        new GrantUri(sourceUserId, uri, prefix));
7883                                perm.initPersistedModes(modeFlags, createdTime);
7884                            }
7885                        } else {
7886                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7887                                    + " but instead found " + pi);
7888                        }
7889                    }
7890                }
7891            }
7892        } catch (FileNotFoundException e) {
7893            // Missing grants is okay
7894        } catch (IOException e) {
7895            Slog.wtf(TAG, "Failed reading Uri grants", e);
7896        } catch (XmlPullParserException e) {
7897            Slog.wtf(TAG, "Failed reading Uri grants", e);
7898        } finally {
7899            IoUtils.closeQuietly(fis);
7900        }
7901    }
7902
7903    /**
7904     * @param uri This uri must NOT contain an embedded userId.
7905     * @param userId The userId in which the uri is to be resolved.
7906     */
7907    @Override
7908    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7909        enforceNotIsolatedCaller("takePersistableUriPermission");
7910
7911        Preconditions.checkFlagsArgument(modeFlags,
7912                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7913
7914        synchronized (this) {
7915            final int callingUid = Binder.getCallingUid();
7916            boolean persistChanged = false;
7917            GrantUri grantUri = new GrantUri(userId, uri, false);
7918
7919            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7920                    new GrantUri(userId, uri, false));
7921            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7922                    new GrantUri(userId, uri, true));
7923
7924            final boolean exactValid = (exactPerm != null)
7925                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7926            final boolean prefixValid = (prefixPerm != null)
7927                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7928
7929            if (!(exactValid || prefixValid)) {
7930                throw new SecurityException("No persistable permission grants found for UID "
7931                        + callingUid + " and Uri " + grantUri.toSafeString());
7932            }
7933
7934            if (exactValid) {
7935                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7936            }
7937            if (prefixValid) {
7938                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7939            }
7940
7941            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7942
7943            if (persistChanged) {
7944                schedulePersistUriGrants();
7945            }
7946        }
7947    }
7948
7949    /**
7950     * @param uri This uri must NOT contain an embedded userId.
7951     * @param userId The userId in which the uri is to be resolved.
7952     */
7953    @Override
7954    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7955        enforceNotIsolatedCaller("releasePersistableUriPermission");
7956
7957        Preconditions.checkFlagsArgument(modeFlags,
7958                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7959
7960        synchronized (this) {
7961            final int callingUid = Binder.getCallingUid();
7962            boolean persistChanged = false;
7963
7964            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7965                    new GrantUri(userId, uri, false));
7966            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7967                    new GrantUri(userId, uri, true));
7968            if (exactPerm == null && prefixPerm == null) {
7969                throw new SecurityException("No permission grants found for UID " + callingUid
7970                        + " and Uri " + uri.toSafeString());
7971            }
7972
7973            if (exactPerm != null) {
7974                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7975                removeUriPermissionIfNeededLocked(exactPerm);
7976            }
7977            if (prefixPerm != null) {
7978                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7979                removeUriPermissionIfNeededLocked(prefixPerm);
7980            }
7981
7982            if (persistChanged) {
7983                schedulePersistUriGrants();
7984            }
7985        }
7986    }
7987
7988    /**
7989     * Prune any older {@link UriPermission} for the given UID until outstanding
7990     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7991     *
7992     * @return if any mutations occured that require persisting.
7993     */
7994    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7995        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7996        if (perms == null) return false;
7997        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7998
7999        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8000        for (UriPermission perm : perms.values()) {
8001            if (perm.persistedModeFlags != 0) {
8002                persisted.add(perm);
8003            }
8004        }
8005
8006        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8007        if (trimCount <= 0) return false;
8008
8009        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8010        for (int i = 0; i < trimCount; i++) {
8011            final UriPermission perm = persisted.get(i);
8012
8013            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8014                    "Trimming grant created at " + perm.persistedCreateTime);
8015
8016            perm.releasePersistableModes(~0);
8017            removeUriPermissionIfNeededLocked(perm);
8018        }
8019
8020        return true;
8021    }
8022
8023    @Override
8024    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8025            String packageName, boolean incoming) {
8026        enforceNotIsolatedCaller("getPersistedUriPermissions");
8027        Preconditions.checkNotNull(packageName, "packageName");
8028
8029        final int callingUid = Binder.getCallingUid();
8030        final IPackageManager pm = AppGlobals.getPackageManager();
8031        try {
8032            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8033            if (packageUid != callingUid) {
8034                throw new SecurityException(
8035                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8036            }
8037        } catch (RemoteException e) {
8038            throw new SecurityException("Failed to verify package name ownership");
8039        }
8040
8041        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8042        synchronized (this) {
8043            if (incoming) {
8044                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8045                        callingUid);
8046                if (perms == null) {
8047                    Slog.w(TAG, "No permission grants found for " + packageName);
8048                } else {
8049                    for (UriPermission perm : perms.values()) {
8050                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8051                            result.add(perm.buildPersistedPublicApiObject());
8052                        }
8053                    }
8054                }
8055            } else {
8056                final int size = mGrantedUriPermissions.size();
8057                for (int i = 0; i < size; i++) {
8058                    final ArrayMap<GrantUri, UriPermission> perms =
8059                            mGrantedUriPermissions.valueAt(i);
8060                    for (UriPermission perm : perms.values()) {
8061                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8062                            result.add(perm.buildPersistedPublicApiObject());
8063                        }
8064                    }
8065                }
8066            }
8067        }
8068        return new ParceledListSlice<android.content.UriPermission>(result);
8069    }
8070
8071    @Override
8072    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8073        synchronized (this) {
8074            ProcessRecord app =
8075                who != null ? getRecordForAppLocked(who) : null;
8076            if (app == null) return;
8077
8078            Message msg = Message.obtain();
8079            msg.what = WAIT_FOR_DEBUGGER_MSG;
8080            msg.obj = app;
8081            msg.arg1 = waiting ? 1 : 0;
8082            mUiHandler.sendMessage(msg);
8083        }
8084    }
8085
8086    @Override
8087    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8088        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8089        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8090        outInfo.availMem = Process.getFreeMemory();
8091        outInfo.totalMem = Process.getTotalMemory();
8092        outInfo.threshold = homeAppMem;
8093        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8094        outInfo.hiddenAppThreshold = cachedAppMem;
8095        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8096                ProcessList.SERVICE_ADJ);
8097        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8098                ProcessList.VISIBLE_APP_ADJ);
8099        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8100                ProcessList.FOREGROUND_APP_ADJ);
8101    }
8102
8103    // =========================================================
8104    // TASK MANAGEMENT
8105    // =========================================================
8106
8107    @Override
8108    public List<IAppTask> getAppTasks(String callingPackage) {
8109        int callingUid = Binder.getCallingUid();
8110        long ident = Binder.clearCallingIdentity();
8111
8112        synchronized(this) {
8113            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8114            try {
8115                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8116
8117                final int N = mRecentTasks.size();
8118                for (int i = 0; i < N; i++) {
8119                    TaskRecord tr = mRecentTasks.get(i);
8120                    // Skip tasks that do not match the caller.  We don't need to verify
8121                    // callingPackage, because we are also limiting to callingUid and know
8122                    // that will limit to the correct security sandbox.
8123                    if (tr.effectiveUid != callingUid) {
8124                        continue;
8125                    }
8126                    Intent intent = tr.getBaseIntent();
8127                    if (intent == null ||
8128                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8129                        continue;
8130                    }
8131                    ActivityManager.RecentTaskInfo taskInfo =
8132                            createRecentTaskInfoFromTaskRecord(tr);
8133                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8134                    list.add(taskImpl);
8135                }
8136            } finally {
8137                Binder.restoreCallingIdentity(ident);
8138            }
8139            return list;
8140        }
8141    }
8142
8143    @Override
8144    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8145        final int callingUid = Binder.getCallingUid();
8146        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8147
8148        synchronized(this) {
8149            if (DEBUG_ALL) Slog.v(
8150                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8151
8152            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8153                    callingUid);
8154
8155            // TODO: Improve with MRU list from all ActivityStacks.
8156            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8157        }
8158
8159        return list;
8160    }
8161
8162    /**
8163     * Creates a new RecentTaskInfo from a TaskRecord.
8164     */
8165    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8166        // Update the task description to reflect any changes in the task stack
8167        tr.updateTaskDescription();
8168
8169        // Compose the recent task info
8170        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8171        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8172        rti.persistentId = tr.taskId;
8173        rti.baseIntent = new Intent(tr.getBaseIntent());
8174        rti.origActivity = tr.origActivity;
8175        rti.description = tr.lastDescription;
8176        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8177        rti.userId = tr.userId;
8178        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8179        rti.firstActiveTime = tr.firstActiveTime;
8180        rti.lastActiveTime = tr.lastActiveTime;
8181        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8182        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8183        rti.numActivities = 0;
8184
8185        ActivityRecord base = null;
8186        ActivityRecord top = null;
8187        ActivityRecord tmp;
8188
8189        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8190            tmp = tr.mActivities.get(i);
8191            if (tmp.finishing) {
8192                continue;
8193            }
8194            base = tmp;
8195            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8196                top = base;
8197            }
8198            rti.numActivities++;
8199        }
8200
8201        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8202        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8203
8204        return rti;
8205    }
8206
8207    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8208        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8209                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8210        if (!allowed) {
8211            if (checkPermission(android.Manifest.permission.GET_TASKS,
8212                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8213                // Temporary compatibility: some existing apps on the system image may
8214                // still be requesting the old permission and not switched to the new
8215                // one; if so, we'll still allow them full access.  This means we need
8216                // to see if they are holding the old permission and are a system app.
8217                try {
8218                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8219                        allowed = true;
8220                        Slog.w(TAG, caller + ": caller " + callingUid
8221                                + " is using old GET_TASKS but privileged; allowing");
8222                    }
8223                } catch (RemoteException e) {
8224                }
8225            }
8226        }
8227        if (!allowed) {
8228            Slog.w(TAG, caller + ": caller " + callingUid
8229                    + " does not hold REAL_GET_TASKS; limiting output");
8230        }
8231        return allowed;
8232    }
8233
8234    @Override
8235    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8236        final int callingUid = Binder.getCallingUid();
8237        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8238                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8239
8240        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8241        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8242        synchronized (this) {
8243            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8244                    callingUid);
8245            final boolean detailed = checkCallingPermission(
8246                    android.Manifest.permission.GET_DETAILED_TASKS)
8247                    == PackageManager.PERMISSION_GRANTED;
8248
8249            final int recentsCount = mRecentTasks.size();
8250            ArrayList<ActivityManager.RecentTaskInfo> res =
8251                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8252
8253            final Set<Integer> includedUsers;
8254            if (includeProfiles) {
8255                includedUsers = getProfileIdsLocked(userId);
8256            } else {
8257                includedUsers = new HashSet<>();
8258            }
8259            includedUsers.add(Integer.valueOf(userId));
8260
8261            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8262                TaskRecord tr = mRecentTasks.get(i);
8263                // Only add calling user or related users recent tasks
8264                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8265                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8266                    continue;
8267                }
8268
8269                // Return the entry if desired by the caller.  We always return
8270                // the first entry, because callers always expect this to be the
8271                // foreground app.  We may filter others if the caller has
8272                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8273                // we should exclude the entry.
8274
8275                if (i == 0
8276                        || withExcluded
8277                        || (tr.intent == null)
8278                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8279                                == 0)) {
8280                    if (!allowed) {
8281                        // If the caller doesn't have the GET_TASKS permission, then only
8282                        // allow them to see a small subset of tasks -- their own and home.
8283                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8284                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8285                            continue;
8286                        }
8287                    }
8288                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8289                        if (tr.stack != null && tr.stack.isHomeStack()) {
8290                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8291                                    "Skipping, home stack task: " + tr);
8292                            continue;
8293                        }
8294                    }
8295                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8296                        // Don't include auto remove tasks that are finished or finishing.
8297                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8298                                "Skipping, auto-remove without activity: " + tr);
8299                        continue;
8300                    }
8301                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8302                            && !tr.isAvailable) {
8303                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8304                                "Skipping, unavail real act: " + tr);
8305                        continue;
8306                    }
8307
8308                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8309                    if (!detailed) {
8310                        rti.baseIntent.replaceExtras((Bundle)null);
8311                    }
8312
8313                    res.add(rti);
8314                    maxNum--;
8315                }
8316            }
8317            return res;
8318        }
8319    }
8320
8321    @Override
8322    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8323        synchronized (this) {
8324            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8325                    "getTaskThumbnail()");
8326            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8327            if (tr != null) {
8328                return tr.getTaskThumbnailLocked();
8329            }
8330        }
8331        return null;
8332    }
8333
8334    @Override
8335    public int addAppTask(IBinder activityToken, Intent intent,
8336            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8337        final int callingUid = Binder.getCallingUid();
8338        final long callingIdent = Binder.clearCallingIdentity();
8339
8340        try {
8341            synchronized (this) {
8342                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8343                if (r == null) {
8344                    throw new IllegalArgumentException("Activity does not exist; token="
8345                            + activityToken);
8346                }
8347                ComponentName comp = intent.getComponent();
8348                if (comp == null) {
8349                    throw new IllegalArgumentException("Intent " + intent
8350                            + " must specify explicit component");
8351                }
8352                if (thumbnail.getWidth() != mThumbnailWidth
8353                        || thumbnail.getHeight() != mThumbnailHeight) {
8354                    throw new IllegalArgumentException("Bad thumbnail size: got "
8355                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8356                            + mThumbnailWidth + "x" + mThumbnailHeight);
8357                }
8358                if (intent.getSelector() != null) {
8359                    intent.setSelector(null);
8360                }
8361                if (intent.getSourceBounds() != null) {
8362                    intent.setSourceBounds(null);
8363                }
8364                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8365                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8366                        // The caller has added this as an auto-remove task...  that makes no
8367                        // sense, so turn off auto-remove.
8368                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8369                    }
8370                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8371                    // Must be a new task.
8372                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8373                }
8374                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8375                    mLastAddedTaskActivity = null;
8376                }
8377                ActivityInfo ainfo = mLastAddedTaskActivity;
8378                if (ainfo == null) {
8379                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8380                            comp, 0, UserHandle.getUserId(callingUid));
8381                    if (ainfo.applicationInfo.uid != callingUid) {
8382                        throw new SecurityException(
8383                                "Can't add task for another application: target uid="
8384                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8385                    }
8386                }
8387
8388                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8389                        intent, description);
8390
8391                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8392                if (trimIdx >= 0) {
8393                    // If this would have caused a trim, then we'll abort because that
8394                    // means it would be added at the end of the list but then just removed.
8395                    return INVALID_TASK_ID;
8396                }
8397
8398                final int N = mRecentTasks.size();
8399                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8400                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8401                    tr.removedFromRecents();
8402                }
8403
8404                task.inRecents = true;
8405                mRecentTasks.add(task);
8406                r.task.stack.addTask(task, false, false);
8407
8408                task.setLastThumbnail(thumbnail);
8409                task.freeLastThumbnail();
8410
8411                return task.taskId;
8412            }
8413        } finally {
8414            Binder.restoreCallingIdentity(callingIdent);
8415        }
8416    }
8417
8418    @Override
8419    public Point getAppTaskThumbnailSize() {
8420        synchronized (this) {
8421            return new Point(mThumbnailWidth,  mThumbnailHeight);
8422        }
8423    }
8424
8425    @Override
8426    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8427        synchronized (this) {
8428            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8429            if (r != null) {
8430                r.setTaskDescription(td);
8431                r.task.updateTaskDescription();
8432            }
8433        }
8434    }
8435
8436    @Override
8437    public void setTaskResizeable(int taskId, boolean resizeable) {
8438        synchronized (this) {
8439            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8440            if (task == null) {
8441                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8442                return;
8443            }
8444            if (task.mResizeable != resizeable) {
8445                task.mResizeable = resizeable;
8446                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8447                mStackSupervisor.resumeTopActivitiesLocked();
8448            }
8449        }
8450    }
8451
8452    @Override
8453    public void resizeTask(int taskId, Rect bounds) {
8454        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8455                "resizeTask()");
8456        long ident = Binder.clearCallingIdentity();
8457        try {
8458            synchronized (this) {
8459                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8460                if (task == null) {
8461                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8462                    return;
8463                }
8464                mStackSupervisor.resizeTaskLocked(task, bounds);
8465            }
8466        } finally {
8467            Binder.restoreCallingIdentity(ident);
8468        }
8469    }
8470
8471    @Override
8472    public Bitmap getTaskDescriptionIcon(String filename) {
8473        if (!FileUtils.isValidExtFilename(filename)
8474                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8475            throw new IllegalArgumentException("Bad filename: " + filename);
8476        }
8477        return mTaskPersister.getTaskDescriptionIcon(filename);
8478    }
8479
8480    @Override
8481    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8482            throws RemoteException {
8483        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8484                opts.getCustomInPlaceResId() == 0) {
8485            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8486                    "with valid animation");
8487        }
8488        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8489        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8490                opts.getCustomInPlaceResId());
8491        mWindowManager.executeAppTransition();
8492    }
8493
8494    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8495        mRecentTasks.remove(tr);
8496        tr.removedFromRecents();
8497        ComponentName component = tr.getBaseIntent().getComponent();
8498        if (component == null) {
8499            Slog.w(TAG, "No component for base intent of task: " + tr);
8500            return;
8501        }
8502
8503        if (!killProcess) {
8504            return;
8505        }
8506
8507        // Determine if the process(es) for this task should be killed.
8508        final String pkg = component.getPackageName();
8509        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8510        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8511        for (int i = 0; i < pmap.size(); i++) {
8512
8513            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8514            for (int j = 0; j < uids.size(); j++) {
8515                ProcessRecord proc = uids.valueAt(j);
8516                if (proc.userId != tr.userId) {
8517                    // Don't kill process for a different user.
8518                    continue;
8519                }
8520                if (proc == mHomeProcess) {
8521                    // Don't kill the home process along with tasks from the same package.
8522                    continue;
8523                }
8524                if (!proc.pkgList.containsKey(pkg)) {
8525                    // Don't kill process that is not associated with this task.
8526                    continue;
8527                }
8528
8529                for (int k = 0; k < proc.activities.size(); k++) {
8530                    TaskRecord otherTask = proc.activities.get(k).task;
8531                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8532                        // Don't kill process(es) that has an activity in a different task that is
8533                        // also in recents.
8534                        return;
8535                    }
8536                }
8537
8538                // Add process to kill list.
8539                procsToKill.add(proc);
8540            }
8541        }
8542
8543        // Find any running services associated with this app and stop if needed.
8544        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8545
8546        // Kill the running processes.
8547        for (int i = 0; i < procsToKill.size(); i++) {
8548            ProcessRecord pr = procsToKill.get(i);
8549            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8550                pr.kill("remove task", true);
8551            } else {
8552                pr.waitingToKill = "remove task";
8553            }
8554        }
8555    }
8556
8557    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8558        // Remove all tasks with activities in the specified package from the list of recent tasks
8559        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8560            TaskRecord tr = mRecentTasks.get(i);
8561            if (tr.userId != userId) continue;
8562
8563            ComponentName cn = tr.intent.getComponent();
8564            if (cn != null && cn.getPackageName().equals(packageName)) {
8565                // If the package name matches, remove the task.
8566                removeTaskByIdLocked(tr.taskId, true);
8567            }
8568        }
8569    }
8570
8571    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8572            int userId) {
8573
8574        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8575            TaskRecord tr = mRecentTasks.get(i);
8576            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8577                continue;
8578            }
8579
8580            ComponentName cn = tr.intent.getComponent();
8581            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8582                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8583            if (sameComponent) {
8584                removeTaskByIdLocked(tr.taskId, false);
8585            }
8586        }
8587    }
8588
8589    /**
8590     * Removes the task with the specified task id.
8591     *
8592     * @param taskId Identifier of the task to be removed.
8593     * @param killProcess Kill any process associated with the task if possible.
8594     * @return Returns true if the given task was found and removed.
8595     */
8596    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8597        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8598        if (tr != null) {
8599            tr.removeTaskActivitiesLocked();
8600            cleanUpRemovedTaskLocked(tr, killProcess);
8601            if (tr.isPersistable) {
8602                notifyTaskPersisterLocked(null, true);
8603            }
8604            return true;
8605        }
8606        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8607        return false;
8608    }
8609
8610    @Override
8611    public boolean removeTask(int taskId) {
8612        synchronized (this) {
8613            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8614                    "removeTask()");
8615            long ident = Binder.clearCallingIdentity();
8616            try {
8617                return removeTaskByIdLocked(taskId, true);
8618            } finally {
8619                Binder.restoreCallingIdentity(ident);
8620            }
8621        }
8622    }
8623
8624    /**
8625     * TODO: Add mController hook
8626     */
8627    @Override
8628    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8629        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8630
8631        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8632        synchronized(this) {
8633            moveTaskToFrontLocked(taskId, flags, options);
8634        }
8635    }
8636
8637    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8638        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8639                Binder.getCallingUid(), -1, -1, "Task to front")) {
8640            ActivityOptions.abort(options);
8641            return;
8642        }
8643        final long origId = Binder.clearCallingIdentity();
8644        try {
8645            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8646            if (task == null) {
8647                Slog.d(TAG, "Could not find task for id: "+ taskId);
8648                return;
8649            }
8650            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8651                mStackSupervisor.showLockTaskToast();
8652                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8653                return;
8654            }
8655            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8656            if (prev != null && prev.isRecentsActivity()) {
8657                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8658            }
8659            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8660        } finally {
8661            Binder.restoreCallingIdentity(origId);
8662        }
8663        ActivityOptions.abort(options);
8664    }
8665
8666    /**
8667     * Moves an activity, and all of the other activities within the same task, to the bottom
8668     * of the history stack.  The activity's order within the task is unchanged.
8669     *
8670     * @param token A reference to the activity we wish to move
8671     * @param nonRoot If false then this only works if the activity is the root
8672     *                of a task; if true it will work for any activity in a task.
8673     * @return Returns true if the move completed, false if not.
8674     */
8675    @Override
8676    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8677        enforceNotIsolatedCaller("moveActivityTaskToBack");
8678        synchronized(this) {
8679            final long origId = Binder.clearCallingIdentity();
8680            try {
8681                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8682                final TaskRecord task = mRecentTasks.taskForIdLocked(taskId);
8683                if (task != null) {
8684                    if (mStackSupervisor.isLockedTask(task)) {
8685                        mStackSupervisor.showLockTaskToast();
8686                        return false;
8687                    }
8688                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8689                }
8690            } finally {
8691                Binder.restoreCallingIdentity(origId);
8692            }
8693        }
8694        return false;
8695    }
8696
8697    @Override
8698    public void moveTaskBackwards(int task) {
8699        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8700                "moveTaskBackwards()");
8701
8702        synchronized(this) {
8703            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8704                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8705                return;
8706            }
8707            final long origId = Binder.clearCallingIdentity();
8708            moveTaskBackwardsLocked(task);
8709            Binder.restoreCallingIdentity(origId);
8710        }
8711    }
8712
8713    private final void moveTaskBackwardsLocked(int task) {
8714        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8715    }
8716
8717    @Override
8718    public IBinder getHomeActivityToken() throws RemoteException {
8719        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8720                "getHomeActivityToken()");
8721        synchronized (this) {
8722            return mStackSupervisor.getHomeActivityToken();
8723        }
8724    }
8725
8726    @Override
8727    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8728            IActivityContainerCallback callback) throws RemoteException {
8729        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8730                "createActivityContainer()");
8731        synchronized (this) {
8732            if (parentActivityToken == null) {
8733                throw new IllegalArgumentException("parent token must not be null");
8734            }
8735            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8736            if (r == null) {
8737                return null;
8738            }
8739            if (callback == null) {
8740                throw new IllegalArgumentException("callback must not be null");
8741            }
8742            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8743        }
8744    }
8745
8746    @Override
8747    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8748        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8749                "deleteActivityContainer()");
8750        synchronized (this) {
8751            mStackSupervisor.deleteActivityContainer(container);
8752        }
8753    }
8754
8755    @Override
8756    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8757        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8758                "createStackOnDisplay()");
8759        synchronized (this) {
8760            final int stackId = mStackSupervisor.getNextStackId();
8761            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8762            if (stack == null) {
8763                return null;
8764            }
8765            return stack.mActivityContainer;
8766        }
8767    }
8768
8769    @Override
8770    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8771        synchronized (this) {
8772            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8773            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8774                return stack.mActivityContainer.getDisplayId();
8775            }
8776            return Display.DEFAULT_DISPLAY;
8777        }
8778    }
8779
8780    @Override
8781    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8782        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8783                "moveTaskToStack()");
8784        if (stackId == HOME_STACK_ID) {
8785            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8786                    new RuntimeException("here").fillInStackTrace());
8787        }
8788        synchronized (this) {
8789            long ident = Binder.clearCallingIdentity();
8790            try {
8791                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8792                        + " to stackId=" + stackId + " toTop=" + toTop);
8793                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8794            } finally {
8795                Binder.restoreCallingIdentity(ident);
8796            }
8797        }
8798    }
8799
8800    @Override
8801    public void resizeStack(int stackId, Rect bounds) {
8802        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8803                "resizeStack()");
8804        long ident = Binder.clearCallingIdentity();
8805        try {
8806            synchronized (this) {
8807                mStackSupervisor.resizeStackLocked(stackId, bounds);
8808            }
8809        } finally {
8810            Binder.restoreCallingIdentity(ident);
8811        }
8812    }
8813
8814    @Override
8815    public List<StackInfo> getAllStackInfos() {
8816        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8817                "getAllStackInfos()");
8818        long ident = Binder.clearCallingIdentity();
8819        try {
8820            synchronized (this) {
8821                return mStackSupervisor.getAllStackInfosLocked();
8822            }
8823        } finally {
8824            Binder.restoreCallingIdentity(ident);
8825        }
8826    }
8827
8828    @Override
8829    public StackInfo getStackInfo(int stackId) {
8830        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8831                "getStackInfo()");
8832        long ident = Binder.clearCallingIdentity();
8833        try {
8834            synchronized (this) {
8835                return mStackSupervisor.getStackInfoLocked(stackId);
8836            }
8837        } finally {
8838            Binder.restoreCallingIdentity(ident);
8839        }
8840    }
8841
8842    @Override
8843    public boolean isInHomeStack(int taskId) {
8844        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8845                "getStackInfo()");
8846        long ident = Binder.clearCallingIdentity();
8847        try {
8848            synchronized (this) {
8849                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8850                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8851            }
8852        } finally {
8853            Binder.restoreCallingIdentity(ident);
8854        }
8855    }
8856
8857    @Override
8858    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8859        synchronized(this) {
8860            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8861        }
8862    }
8863
8864    @Override
8865    public void updatePreferredSetupActivity(ComponentName preferredActivity, int userId) {
8866        final int callingUid = Binder.getCallingUid();
8867        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8868            throw new SecurityException(
8869                    "updatePreferredSetupActivity called from non-system process");
8870        }
8871        synchronized (this) {
8872            if (preferredActivity == null) {
8873                mPreferredSetupActivities.delete(userId);
8874            } else {
8875                mPreferredSetupActivities.put(userId, preferredActivity);
8876            }
8877        }
8878    }
8879
8880    @Override
8881    public void updateDeviceOwner(String packageName) {
8882        final int callingUid = Binder.getCallingUid();
8883        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8884            throw new SecurityException("updateDeviceOwner called from non-system process");
8885        }
8886        synchronized (this) {
8887            mDeviceOwnerName = packageName;
8888        }
8889    }
8890
8891    @Override
8892    public void updateLockTaskPackages(int userId, String[] packages) {
8893        final int callingUid = Binder.getCallingUid();
8894        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8895            throw new SecurityException("updateLockTaskPackage called from non-system process");
8896        }
8897        synchronized (this) {
8898            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" + packages);
8899            mLockTaskPackages.put(userId, packages);
8900            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
8901        }
8902    }
8903
8904
8905    void startLockTaskModeLocked(TaskRecord task) {
8906        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
8907        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
8908            return;
8909        }
8910
8911        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
8912        // is initiated by system after the pinning request was shown and locked mode is initiated
8913        // by an authorized app directly
8914        final int callingUid = Binder.getCallingUid();
8915        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
8916        long ident = Binder.clearCallingIdentity();
8917        try {
8918            final ActivityStack stack = mStackSupervisor.getFocusedStack();
8919            if (!isSystemInitiated) {
8920                task.mLockTaskUid = callingUid;
8921                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
8922                    // startLockTask() called by app and task mode is lockTaskModeDefault.
8923                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
8924                    StatusBarManagerInternal statusBarManager =
8925                            LocalServices.getService(StatusBarManagerInternal.class);
8926                    if (statusBarManager != null) {
8927                        statusBarManager.showScreenPinningRequest();
8928                    }
8929                    return;
8930                }
8931
8932                if (stack == null || task != stack.topTask()) {
8933                    throw new IllegalArgumentException("Invalid task, not in foreground");
8934                }
8935            }
8936            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
8937                    "Locking fully");
8938            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
8939                    ActivityManager.LOCK_TASK_MODE_PINNED :
8940                    ActivityManager.LOCK_TASK_MODE_LOCKED,
8941                    "startLockTask");
8942        } finally {
8943            Binder.restoreCallingIdentity(ident);
8944        }
8945    }
8946
8947    @Override
8948    public void startLockTaskMode(int taskId) {
8949        synchronized (this) {
8950            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8951            if (task != null) {
8952                startLockTaskModeLocked(task);
8953            }
8954        }
8955    }
8956
8957    @Override
8958    public void startLockTaskMode(IBinder token) {
8959        synchronized (this) {
8960            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8961            if (r == null) {
8962                return;
8963            }
8964            final TaskRecord task = r.task;
8965            if (task != null) {
8966                startLockTaskModeLocked(task);
8967            }
8968        }
8969    }
8970
8971    @Override
8972    public void startLockTaskModeOnCurrent() throws RemoteException {
8973        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8974                "startLockTaskModeOnCurrent");
8975        long ident = Binder.clearCallingIdentity();
8976        try {
8977            synchronized (this) {
8978                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
8979                if (r != null) {
8980                    startLockTaskModeLocked(r.task);
8981                }
8982            }
8983        } finally {
8984            Binder.restoreCallingIdentity(ident);
8985        }
8986    }
8987
8988    @Override
8989    public void stopLockTaskMode() {
8990        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
8991        if (lockTask == null) {
8992            // Our work here is done.
8993            return;
8994        }
8995        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
8996        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
8997                Binder.getCallingUid() != lockTask.mLockTaskUid) {
8998            throw new SecurityException("Invalid uid, expected " + lockTask.mLockTaskUid);
8999        }
9000        long ident = Binder.clearCallingIdentity();
9001        try {
9002            Log.d(TAG, "stopLockTaskMode");
9003            // Stop lock task
9004            synchronized (this) {
9005                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9006                        "stopLockTask");
9007            }
9008        } finally {
9009            Binder.restoreCallingIdentity(ident);
9010        }
9011    }
9012
9013    @Override
9014    public void stopLockTaskModeOnCurrent() throws RemoteException {
9015        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9016                "stopLockTaskModeOnCurrent");
9017        long ident = Binder.clearCallingIdentity();
9018        try {
9019            stopLockTaskMode();
9020        } finally {
9021            Binder.restoreCallingIdentity(ident);
9022        }
9023    }
9024
9025    @Override
9026    public boolean isInLockTaskMode() {
9027        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9028    }
9029
9030    @Override
9031    public int getLockTaskModeState() {
9032        synchronized (this) {
9033            return mStackSupervisor.getLockTaskModeState();
9034        }
9035    }
9036
9037    @Override
9038    public void showLockTaskEscapeMessage(IBinder token) {
9039        synchronized (this) {
9040            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9041            if (r == null) {
9042                return;
9043            }
9044            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9045        }
9046    }
9047
9048    // =========================================================
9049    // CONTENT PROVIDERS
9050    // =========================================================
9051
9052    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9053        List<ProviderInfo> providers = null;
9054        try {
9055            providers = AppGlobals.getPackageManager().
9056                queryContentProviders(app.processName, app.uid,
9057                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9058        } catch (RemoteException ex) {
9059        }
9060        if (DEBUG_MU) Slog.v(TAG_MU,
9061                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9062        int userId = app.userId;
9063        if (providers != null) {
9064            int N = providers.size();
9065            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9066            for (int i=0; i<N; i++) {
9067                ProviderInfo cpi =
9068                    (ProviderInfo)providers.get(i);
9069                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9070                        cpi.name, cpi.flags);
9071                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9072                    // This is a singleton provider, but a user besides the
9073                    // default user is asking to initialize a process it runs
9074                    // in...  well, no, it doesn't actually run in this process,
9075                    // it runs in the process of the default user.  Get rid of it.
9076                    providers.remove(i);
9077                    N--;
9078                    i--;
9079                    continue;
9080                }
9081
9082                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9083                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9084                if (cpr == null) {
9085                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9086                    mProviderMap.putProviderByClass(comp, cpr);
9087                }
9088                if (DEBUG_MU) Slog.v(TAG_MU,
9089                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9090                app.pubProviders.put(cpi.name, cpr);
9091                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9092                    // Don't add this if it is a platform component that is marked
9093                    // to run in multiple processes, because this is actually
9094                    // part of the framework so doesn't make sense to track as a
9095                    // separate apk in the process.
9096                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9097                            mProcessStats);
9098                }
9099                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9100            }
9101        }
9102        return providers;
9103    }
9104
9105    /**
9106     * Check if {@link ProcessRecord} has a possible chance at accessing the
9107     * given {@link ProviderInfo}. Final permission checking is always done
9108     * in {@link ContentProvider}.
9109     */
9110    private final String checkContentProviderPermissionLocked(
9111            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9112        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9113        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9114        boolean checkedGrants = false;
9115        if (checkUser) {
9116            // Looking for cross-user grants before enforcing the typical cross-users permissions
9117            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9118            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9119                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9120                    return null;
9121                }
9122                checkedGrants = true;
9123            }
9124            userId = handleIncomingUser(callingPid, callingUid, userId,
9125                    false, ALLOW_NON_FULL,
9126                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9127            if (userId != tmpTargetUserId) {
9128                // When we actually went to determine the final targer user ID, this ended
9129                // up different than our initial check for the authority.  This is because
9130                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9131                // SELF.  So we need to re-check the grants again.
9132                checkedGrants = false;
9133            }
9134        }
9135        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9136                cpi.applicationInfo.uid, cpi.exported)
9137                == PackageManager.PERMISSION_GRANTED) {
9138            return null;
9139        }
9140        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9141                cpi.applicationInfo.uid, cpi.exported)
9142                == PackageManager.PERMISSION_GRANTED) {
9143            return null;
9144        }
9145
9146        PathPermission[] pps = cpi.pathPermissions;
9147        if (pps != null) {
9148            int i = pps.length;
9149            while (i > 0) {
9150                i--;
9151                PathPermission pp = pps[i];
9152                String pprperm = pp.getReadPermission();
9153                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9154                        cpi.applicationInfo.uid, cpi.exported)
9155                        == PackageManager.PERMISSION_GRANTED) {
9156                    return null;
9157                }
9158                String ppwperm = pp.getWritePermission();
9159                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9160                        cpi.applicationInfo.uid, cpi.exported)
9161                        == PackageManager.PERMISSION_GRANTED) {
9162                    return null;
9163                }
9164            }
9165        }
9166        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9167            return null;
9168        }
9169
9170        String msg;
9171        if (!cpi.exported) {
9172            msg = "Permission Denial: opening provider " + cpi.name
9173                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9174                    + ", uid=" + callingUid + ") that is not exported from uid "
9175                    + cpi.applicationInfo.uid;
9176        } else {
9177            msg = "Permission Denial: opening provider " + cpi.name
9178                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9179                    + ", uid=" + callingUid + ") requires "
9180                    + cpi.readPermission + " or " + cpi.writePermission;
9181        }
9182        Slog.w(TAG, msg);
9183        return msg;
9184    }
9185
9186    /**
9187     * Returns if the ContentProvider has granted a uri to callingUid
9188     */
9189    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9190        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9191        if (perms != null) {
9192            for (int i=perms.size()-1; i>=0; i--) {
9193                GrantUri grantUri = perms.keyAt(i);
9194                if (grantUri.sourceUserId == userId || !checkUser) {
9195                    if (matchesProvider(grantUri.uri, cpi)) {
9196                        return true;
9197                    }
9198                }
9199            }
9200        }
9201        return false;
9202    }
9203
9204    /**
9205     * Returns true if the uri authority is one of the authorities specified in the provider.
9206     */
9207    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9208        String uriAuth = uri.getAuthority();
9209        String cpiAuth = cpi.authority;
9210        if (cpiAuth.indexOf(';') == -1) {
9211            return cpiAuth.equals(uriAuth);
9212        }
9213        String[] cpiAuths = cpiAuth.split(";");
9214        int length = cpiAuths.length;
9215        for (int i = 0; i < length; i++) {
9216            if (cpiAuths[i].equals(uriAuth)) return true;
9217        }
9218        return false;
9219    }
9220
9221    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9222            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9223        if (r != null) {
9224            for (int i=0; i<r.conProviders.size(); i++) {
9225                ContentProviderConnection conn = r.conProviders.get(i);
9226                if (conn.provider == cpr) {
9227                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9228                            "Adding provider requested by "
9229                            + r.processName + " from process "
9230                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9231                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9232                    if (stable) {
9233                        conn.stableCount++;
9234                        conn.numStableIncs++;
9235                    } else {
9236                        conn.unstableCount++;
9237                        conn.numUnstableIncs++;
9238                    }
9239                    return conn;
9240                }
9241            }
9242            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9243            if (stable) {
9244                conn.stableCount = 1;
9245                conn.numStableIncs = 1;
9246            } else {
9247                conn.unstableCount = 1;
9248                conn.numUnstableIncs = 1;
9249            }
9250            cpr.connections.add(conn);
9251            r.conProviders.add(conn);
9252            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9253            return conn;
9254        }
9255        cpr.addExternalProcessHandleLocked(externalProcessToken);
9256        return null;
9257    }
9258
9259    boolean decProviderCountLocked(ContentProviderConnection conn,
9260            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9261        if (conn != null) {
9262            cpr = conn.provider;
9263            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9264                    "Removing provider requested by "
9265                    + conn.client.processName + " from process "
9266                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9267                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9268            if (stable) {
9269                conn.stableCount--;
9270            } else {
9271                conn.unstableCount--;
9272            }
9273            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9274                cpr.connections.remove(conn);
9275                conn.client.conProviders.remove(conn);
9276                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9277                return true;
9278            }
9279            return false;
9280        }
9281        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9282        return false;
9283    }
9284
9285    private void checkTime(long startTime, String where) {
9286        long now = SystemClock.elapsedRealtime();
9287        if ((now-startTime) > 1000) {
9288            // If we are taking more than a second, log about it.
9289            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9290        }
9291    }
9292
9293    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9294            String name, IBinder token, boolean stable, int userId) {
9295        ContentProviderRecord cpr;
9296        ContentProviderConnection conn = null;
9297        ProviderInfo cpi = null;
9298
9299        synchronized(this) {
9300            long startTime = SystemClock.elapsedRealtime();
9301
9302            ProcessRecord r = null;
9303            if (caller != null) {
9304                r = getRecordForAppLocked(caller);
9305                if (r == null) {
9306                    throw new SecurityException(
9307                            "Unable to find app for caller " + caller
9308                          + " (pid=" + Binder.getCallingPid()
9309                          + ") when getting content provider " + name);
9310                }
9311            }
9312
9313            boolean checkCrossUser = true;
9314
9315            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9316
9317            // First check if this content provider has been published...
9318            cpr = mProviderMap.getProviderByName(name, userId);
9319            // If that didn't work, check if it exists for user 0 and then
9320            // verify that it's a singleton provider before using it.
9321            if (cpr == null && userId != UserHandle.USER_OWNER) {
9322                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9323                if (cpr != null) {
9324                    cpi = cpr.info;
9325                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9326                            cpi.name, cpi.flags)
9327                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9328                        userId = UserHandle.USER_OWNER;
9329                        checkCrossUser = false;
9330                    } else {
9331                        cpr = null;
9332                        cpi = null;
9333                    }
9334                }
9335            }
9336
9337            boolean providerRunning = cpr != null;
9338            if (providerRunning) {
9339                cpi = cpr.info;
9340                String msg;
9341                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9342                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9343                        != null) {
9344                    throw new SecurityException(msg);
9345                }
9346                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9347
9348                if (r != null && cpr.canRunHere(r)) {
9349                    // This provider has been published or is in the process
9350                    // of being published...  but it is also allowed to run
9351                    // in the caller's process, so don't make a connection
9352                    // and just let the caller instantiate its own instance.
9353                    ContentProviderHolder holder = cpr.newHolder(null);
9354                    // don't give caller the provider object, it needs
9355                    // to make its own.
9356                    holder.provider = null;
9357                    return holder;
9358                }
9359
9360                final long origId = Binder.clearCallingIdentity();
9361
9362                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9363
9364                // In this case the provider instance already exists, so we can
9365                // return it right away.
9366                conn = incProviderCountLocked(r, cpr, token, stable);
9367                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9368                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9369                        // If this is a perceptible app accessing the provider,
9370                        // make sure to count it as being accessed and thus
9371                        // back up on the LRU list.  This is good because
9372                        // content providers are often expensive to start.
9373                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9374                        updateLruProcessLocked(cpr.proc, false, null);
9375                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9376                    }
9377                }
9378
9379                if (cpr.proc != null) {
9380                    if (false) {
9381                        if (cpr.name.flattenToShortString().equals(
9382                                "com.android.providers.calendar/.CalendarProvider2")) {
9383                            Slog.v(TAG, "****************** KILLING "
9384                                + cpr.name.flattenToShortString());
9385                            Process.killProcess(cpr.proc.pid);
9386                        }
9387                    }
9388                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9389                    boolean success = updateOomAdjLocked(cpr.proc);
9390                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9391                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9392                    // NOTE: there is still a race here where a signal could be
9393                    // pending on the process even though we managed to update its
9394                    // adj level.  Not sure what to do about this, but at least
9395                    // the race is now smaller.
9396                    if (!success) {
9397                        // Uh oh...  it looks like the provider's process
9398                        // has been killed on us.  We need to wait for a new
9399                        // process to be started, and make sure its death
9400                        // doesn't kill our process.
9401                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9402                                + " is crashing; detaching " + r);
9403                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9404                        checkTime(startTime, "getContentProviderImpl: before appDied");
9405                        appDiedLocked(cpr.proc);
9406                        checkTime(startTime, "getContentProviderImpl: after appDied");
9407                        if (!lastRef) {
9408                            // This wasn't the last ref our process had on
9409                            // the provider...  we have now been killed, bail.
9410                            return null;
9411                        }
9412                        providerRunning = false;
9413                        conn = null;
9414                    }
9415                }
9416
9417                Binder.restoreCallingIdentity(origId);
9418            }
9419
9420            boolean singleton;
9421            if (!providerRunning) {
9422                try {
9423                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9424                    cpi = AppGlobals.getPackageManager().
9425                        resolveContentProvider(name,
9426                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9427                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9428                } catch (RemoteException ex) {
9429                }
9430                if (cpi == null) {
9431                    return null;
9432                }
9433                // If the provider is a singleton AND
9434                // (it's a call within the same user || the provider is a
9435                // privileged app)
9436                // Then allow connecting to the singleton provider
9437                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9438                        cpi.name, cpi.flags)
9439                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9440                if (singleton) {
9441                    userId = UserHandle.USER_OWNER;
9442                }
9443                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9444                checkTime(startTime, "getContentProviderImpl: got app info for user");
9445
9446                String msg;
9447                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9448                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9449                        != null) {
9450                    throw new SecurityException(msg);
9451                }
9452                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9453
9454                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9455                        && !cpi.processName.equals("system")) {
9456                    // If this content provider does not run in the system
9457                    // process, and the system is not yet ready to run other
9458                    // processes, then fail fast instead of hanging.
9459                    throw new IllegalArgumentException(
9460                            "Attempt to launch content provider before system ready");
9461                }
9462
9463                // Make sure that the user who owns this provider is running.  If not,
9464                // we don't want to allow it to run.
9465                if (!isUserRunningLocked(userId, false)) {
9466                    Slog.w(TAG, "Unable to launch app "
9467                            + cpi.applicationInfo.packageName + "/"
9468                            + cpi.applicationInfo.uid + " for provider "
9469                            + name + ": user " + userId + " is stopped");
9470                    return null;
9471                }
9472
9473                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9474                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9475                cpr = mProviderMap.getProviderByClass(comp, userId);
9476                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9477                final boolean firstClass = cpr == null;
9478                if (firstClass) {
9479                    final long ident = Binder.clearCallingIdentity();
9480                    try {
9481                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9482                        ApplicationInfo ai =
9483                            AppGlobals.getPackageManager().
9484                                getApplicationInfo(
9485                                        cpi.applicationInfo.packageName,
9486                                        STOCK_PM_FLAGS, userId);
9487                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9488                        if (ai == null) {
9489                            Slog.w(TAG, "No package info for content provider "
9490                                    + cpi.name);
9491                            return null;
9492                        }
9493                        ai = getAppInfoForUser(ai, userId);
9494                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9495                    } catch (RemoteException ex) {
9496                        // pm is in same process, this will never happen.
9497                    } finally {
9498                        Binder.restoreCallingIdentity(ident);
9499                    }
9500                }
9501
9502                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9503
9504                if (r != null && cpr.canRunHere(r)) {
9505                    // If this is a multiprocess provider, then just return its
9506                    // info and allow the caller to instantiate it.  Only do
9507                    // this if the provider is the same user as the caller's
9508                    // process, or can run as root (so can be in any process).
9509                    return cpr.newHolder(null);
9510                }
9511
9512                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9513                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9514                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9515
9516                // This is single process, and our app is now connecting to it.
9517                // See if we are already in the process of launching this
9518                // provider.
9519                final int N = mLaunchingProviders.size();
9520                int i;
9521                for (i = 0; i < N; i++) {
9522                    if (mLaunchingProviders.get(i) == cpr) {
9523                        break;
9524                    }
9525                }
9526
9527                // If the provider is not already being launched, then get it
9528                // started.
9529                if (i >= N) {
9530                    final long origId = Binder.clearCallingIdentity();
9531
9532                    try {
9533                        // Content provider is now in use, its package can't be stopped.
9534                        try {
9535                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9536                            AppGlobals.getPackageManager().setPackageStoppedState(
9537                                    cpr.appInfo.packageName, false, userId);
9538                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9539                        } catch (RemoteException e) {
9540                        } catch (IllegalArgumentException e) {
9541                            Slog.w(TAG, "Failed trying to unstop package "
9542                                    + cpr.appInfo.packageName + ": " + e);
9543                        }
9544
9545                        // Use existing process if already started
9546                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9547                        ProcessRecord proc = getProcessRecordLocked(
9548                                cpi.processName, cpr.appInfo.uid, false);
9549                        if (proc != null && proc.thread != null) {
9550                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9551                                    "Installing in existing process " + proc);
9552                            if (!proc.pubProviders.containsKey(cpi.name)) {
9553                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9554                                proc.pubProviders.put(cpi.name, cpr);
9555                                try {
9556                                    proc.thread.scheduleInstallProvider(cpi);
9557                                } catch (RemoteException e) {
9558                                }
9559                            }
9560                        } else {
9561                            checkTime(startTime, "getContentProviderImpl: before start process");
9562                            proc = startProcessLocked(cpi.processName,
9563                                    cpr.appInfo, false, 0, "content provider",
9564                                    new ComponentName(cpi.applicationInfo.packageName,
9565                                            cpi.name), false, false, false);
9566                            checkTime(startTime, "getContentProviderImpl: after start process");
9567                            if (proc == null) {
9568                                Slog.w(TAG, "Unable to launch app "
9569                                        + cpi.applicationInfo.packageName + "/"
9570                                        + cpi.applicationInfo.uid + " for provider "
9571                                        + name + ": process is bad");
9572                                return null;
9573                            }
9574                        }
9575                        cpr.launchingApp = proc;
9576                        mLaunchingProviders.add(cpr);
9577                    } finally {
9578                        Binder.restoreCallingIdentity(origId);
9579                    }
9580                }
9581
9582                checkTime(startTime, "getContentProviderImpl: updating data structures");
9583
9584                // Make sure the provider is published (the same provider class
9585                // may be published under multiple names).
9586                if (firstClass) {
9587                    mProviderMap.putProviderByClass(comp, cpr);
9588                }
9589
9590                mProviderMap.putProviderByName(name, cpr);
9591                conn = incProviderCountLocked(r, cpr, token, stable);
9592                if (conn != null) {
9593                    conn.waiting = true;
9594                }
9595            }
9596            checkTime(startTime, "getContentProviderImpl: done!");
9597        }
9598
9599        // Wait for the provider to be published...
9600        synchronized (cpr) {
9601            while (cpr.provider == null) {
9602                if (cpr.launchingApp == null) {
9603                    Slog.w(TAG, "Unable to launch app "
9604                            + cpi.applicationInfo.packageName + "/"
9605                            + cpi.applicationInfo.uid + " for provider "
9606                            + name + ": launching app became null");
9607                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9608                            UserHandle.getUserId(cpi.applicationInfo.uid),
9609                            cpi.applicationInfo.packageName,
9610                            cpi.applicationInfo.uid, name);
9611                    return null;
9612                }
9613                try {
9614                    if (DEBUG_MU) Slog.v(TAG_MU,
9615                            "Waiting to start provider " + cpr
9616                            + " launchingApp=" + cpr.launchingApp);
9617                    if (conn != null) {
9618                        conn.waiting = true;
9619                    }
9620                    cpr.wait();
9621                } catch (InterruptedException ex) {
9622                } finally {
9623                    if (conn != null) {
9624                        conn.waiting = false;
9625                    }
9626                }
9627            }
9628        }
9629        return cpr != null ? cpr.newHolder(conn) : null;
9630    }
9631
9632    @Override
9633    public final ContentProviderHolder getContentProvider(
9634            IApplicationThread caller, String name, int userId, boolean stable) {
9635        enforceNotIsolatedCaller("getContentProvider");
9636        if (caller == null) {
9637            String msg = "null IApplicationThread when getting content provider "
9638                    + name;
9639            Slog.w(TAG, msg);
9640            throw new SecurityException(msg);
9641        }
9642        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9643        // with cross-user grant.
9644        return getContentProviderImpl(caller, name, null, stable, userId);
9645    }
9646
9647    public ContentProviderHolder getContentProviderExternal(
9648            String name, int userId, IBinder token) {
9649        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9650            "Do not have permission in call getContentProviderExternal()");
9651        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9652                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9653        return getContentProviderExternalUnchecked(name, token, userId);
9654    }
9655
9656    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9657            IBinder token, int userId) {
9658        return getContentProviderImpl(null, name, token, true, userId);
9659    }
9660
9661    /**
9662     * Drop a content provider from a ProcessRecord's bookkeeping
9663     */
9664    public void removeContentProvider(IBinder connection, boolean stable) {
9665        enforceNotIsolatedCaller("removeContentProvider");
9666        long ident = Binder.clearCallingIdentity();
9667        try {
9668            synchronized (this) {
9669                ContentProviderConnection conn;
9670                try {
9671                    conn = (ContentProviderConnection)connection;
9672                } catch (ClassCastException e) {
9673                    String msg ="removeContentProvider: " + connection
9674                            + " not a ContentProviderConnection";
9675                    Slog.w(TAG, msg);
9676                    throw new IllegalArgumentException(msg);
9677                }
9678                if (conn == null) {
9679                    throw new NullPointerException("connection is null");
9680                }
9681                if (decProviderCountLocked(conn, null, null, stable)) {
9682                    updateOomAdjLocked();
9683                }
9684            }
9685        } finally {
9686            Binder.restoreCallingIdentity(ident);
9687        }
9688    }
9689
9690    public void removeContentProviderExternal(String name, IBinder token) {
9691        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9692            "Do not have permission in call removeContentProviderExternal()");
9693        int userId = UserHandle.getCallingUserId();
9694        long ident = Binder.clearCallingIdentity();
9695        try {
9696            removeContentProviderExternalUnchecked(name, token, userId);
9697        } finally {
9698            Binder.restoreCallingIdentity(ident);
9699        }
9700    }
9701
9702    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9703        synchronized (this) {
9704            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9705            if(cpr == null) {
9706                //remove from mProvidersByClass
9707                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9708                return;
9709            }
9710
9711            //update content provider record entry info
9712            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9713            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9714            if (localCpr.hasExternalProcessHandles()) {
9715                if (localCpr.removeExternalProcessHandleLocked(token)) {
9716                    updateOomAdjLocked();
9717                } else {
9718                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9719                            + " with no external reference for token: "
9720                            + token + ".");
9721                }
9722            } else {
9723                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9724                        + " with no external references.");
9725            }
9726        }
9727    }
9728
9729    public final void publishContentProviders(IApplicationThread caller,
9730            List<ContentProviderHolder> providers) {
9731        if (providers == null) {
9732            return;
9733        }
9734
9735        enforceNotIsolatedCaller("publishContentProviders");
9736        synchronized (this) {
9737            final ProcessRecord r = getRecordForAppLocked(caller);
9738            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9739            if (r == null) {
9740                throw new SecurityException(
9741                        "Unable to find app for caller " + caller
9742                      + " (pid=" + Binder.getCallingPid()
9743                      + ") when publishing content providers");
9744            }
9745
9746            final long origId = Binder.clearCallingIdentity();
9747
9748            final int N = providers.size();
9749            for (int i=0; i<N; i++) {
9750                ContentProviderHolder src = providers.get(i);
9751                if (src == null || src.info == null || src.provider == null) {
9752                    continue;
9753                }
9754                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9755                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9756                if (dst != null) {
9757                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9758                    mProviderMap.putProviderByClass(comp, dst);
9759                    String names[] = dst.info.authority.split(";");
9760                    for (int j = 0; j < names.length; j++) {
9761                        mProviderMap.putProviderByName(names[j], dst);
9762                    }
9763
9764                    int NL = mLaunchingProviders.size();
9765                    int j;
9766                    for (j=0; j<NL; j++) {
9767                        if (mLaunchingProviders.get(j) == dst) {
9768                            mLaunchingProviders.remove(j);
9769                            j--;
9770                            NL--;
9771                        }
9772                    }
9773                    synchronized (dst) {
9774                        dst.provider = src.provider;
9775                        dst.proc = r;
9776                        dst.notifyAll();
9777                    }
9778                    updateOomAdjLocked(r);
9779                }
9780            }
9781
9782            Binder.restoreCallingIdentity(origId);
9783        }
9784    }
9785
9786    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9787        ContentProviderConnection conn;
9788        try {
9789            conn = (ContentProviderConnection)connection;
9790        } catch (ClassCastException e) {
9791            String msg ="refContentProvider: " + connection
9792                    + " not a ContentProviderConnection";
9793            Slog.w(TAG, msg);
9794            throw new IllegalArgumentException(msg);
9795        }
9796        if (conn == null) {
9797            throw new NullPointerException("connection is null");
9798        }
9799
9800        synchronized (this) {
9801            if (stable > 0) {
9802                conn.numStableIncs += stable;
9803            }
9804            stable = conn.stableCount + stable;
9805            if (stable < 0) {
9806                throw new IllegalStateException("stableCount < 0: " + stable);
9807            }
9808
9809            if (unstable > 0) {
9810                conn.numUnstableIncs += unstable;
9811            }
9812            unstable = conn.unstableCount + unstable;
9813            if (unstable < 0) {
9814                throw new IllegalStateException("unstableCount < 0: " + unstable);
9815            }
9816
9817            if ((stable+unstable) <= 0) {
9818                throw new IllegalStateException("ref counts can't go to zero here: stable="
9819                        + stable + " unstable=" + unstable);
9820            }
9821            conn.stableCount = stable;
9822            conn.unstableCount = unstable;
9823            return !conn.dead;
9824        }
9825    }
9826
9827    public void unstableProviderDied(IBinder connection) {
9828        ContentProviderConnection conn;
9829        try {
9830            conn = (ContentProviderConnection)connection;
9831        } catch (ClassCastException e) {
9832            String msg ="refContentProvider: " + connection
9833                    + " not a ContentProviderConnection";
9834            Slog.w(TAG, msg);
9835            throw new IllegalArgumentException(msg);
9836        }
9837        if (conn == null) {
9838            throw new NullPointerException("connection is null");
9839        }
9840
9841        // Safely retrieve the content provider associated with the connection.
9842        IContentProvider provider;
9843        synchronized (this) {
9844            provider = conn.provider.provider;
9845        }
9846
9847        if (provider == null) {
9848            // Um, yeah, we're way ahead of you.
9849            return;
9850        }
9851
9852        // Make sure the caller is being honest with us.
9853        if (provider.asBinder().pingBinder()) {
9854            // Er, no, still looks good to us.
9855            synchronized (this) {
9856                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9857                        + " says " + conn + " died, but we don't agree");
9858                return;
9859            }
9860        }
9861
9862        // Well look at that!  It's dead!
9863        synchronized (this) {
9864            if (conn.provider.provider != provider) {
9865                // But something changed...  good enough.
9866                return;
9867            }
9868
9869            ProcessRecord proc = conn.provider.proc;
9870            if (proc == null || proc.thread == null) {
9871                // Seems like the process is already cleaned up.
9872                return;
9873            }
9874
9875            // As far as we're concerned, this is just like receiving a
9876            // death notification...  just a bit prematurely.
9877            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9878                    + ") early provider death");
9879            final long ident = Binder.clearCallingIdentity();
9880            try {
9881                appDiedLocked(proc);
9882            } finally {
9883                Binder.restoreCallingIdentity(ident);
9884            }
9885        }
9886    }
9887
9888    @Override
9889    public void appNotRespondingViaProvider(IBinder connection) {
9890        enforceCallingPermission(
9891                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9892
9893        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9894        if (conn == null) {
9895            Slog.w(TAG, "ContentProviderConnection is null");
9896            return;
9897        }
9898
9899        final ProcessRecord host = conn.provider.proc;
9900        if (host == null) {
9901            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9902            return;
9903        }
9904
9905        final long token = Binder.clearCallingIdentity();
9906        try {
9907            appNotResponding(host, null, null, false, "ContentProvider not responding");
9908        } finally {
9909            Binder.restoreCallingIdentity(token);
9910        }
9911    }
9912
9913    public final void installSystemProviders() {
9914        List<ProviderInfo> providers;
9915        synchronized (this) {
9916            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9917            providers = generateApplicationProvidersLocked(app);
9918            if (providers != null) {
9919                for (int i=providers.size()-1; i>=0; i--) {
9920                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9921                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9922                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9923                                + ": not system .apk");
9924                        providers.remove(i);
9925                    }
9926                }
9927            }
9928        }
9929        if (providers != null) {
9930            mSystemThread.installSystemProviders(providers);
9931        }
9932
9933        mCoreSettingsObserver = new CoreSettingsObserver(this);
9934
9935        //mUsageStatsService.monitorPackages();
9936    }
9937
9938    /**
9939     * Allows apps to retrieve the MIME type of a URI.
9940     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9941     * users, then it does not need permission to access the ContentProvider.
9942     * Either, it needs cross-user uri grants.
9943     *
9944     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9945     *
9946     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9947     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9948     */
9949    public String getProviderMimeType(Uri uri, int userId) {
9950        enforceNotIsolatedCaller("getProviderMimeType");
9951        final String name = uri.getAuthority();
9952        int callingUid = Binder.getCallingUid();
9953        int callingPid = Binder.getCallingPid();
9954        long ident = 0;
9955        boolean clearedIdentity = false;
9956        userId = unsafeConvertIncomingUser(userId);
9957        if (canClearIdentity(callingPid, callingUid, userId)) {
9958            clearedIdentity = true;
9959            ident = Binder.clearCallingIdentity();
9960        }
9961        ContentProviderHolder holder = null;
9962        try {
9963            holder = getContentProviderExternalUnchecked(name, null, userId);
9964            if (holder != null) {
9965                return holder.provider.getType(uri);
9966            }
9967        } catch (RemoteException e) {
9968            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9969            return null;
9970        } finally {
9971            // We need to clear the identity to call removeContentProviderExternalUnchecked
9972            if (!clearedIdentity) {
9973                ident = Binder.clearCallingIdentity();
9974            }
9975            try {
9976                if (holder != null) {
9977                    removeContentProviderExternalUnchecked(name, null, userId);
9978                }
9979            } finally {
9980                Binder.restoreCallingIdentity(ident);
9981            }
9982        }
9983
9984        return null;
9985    }
9986
9987    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9988        if (UserHandle.getUserId(callingUid) == userId) {
9989            return true;
9990        }
9991        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9992                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9993                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9994                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9995                return true;
9996        }
9997        return false;
9998    }
9999
10000    // =========================================================
10001    // GLOBAL MANAGEMENT
10002    // =========================================================
10003
10004    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10005            boolean isolated, int isolatedUid) {
10006        String proc = customProcess != null ? customProcess : info.processName;
10007        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10008        final int userId = UserHandle.getUserId(info.uid);
10009        int uid = info.uid;
10010        if (isolated) {
10011            if (isolatedUid == 0) {
10012                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10013                while (true) {
10014                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10015                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10016                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10017                    }
10018                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10019                    mNextIsolatedProcessUid++;
10020                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10021                        // No process for this uid, use it.
10022                        break;
10023                    }
10024                    stepsLeft--;
10025                    if (stepsLeft <= 0) {
10026                        return null;
10027                    }
10028                }
10029            } else {
10030                // Special case for startIsolatedProcess (internal only), where
10031                // the uid of the isolated process is specified by the caller.
10032                uid = isolatedUid;
10033            }
10034        }
10035        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10036        if (!mBooted && !mBooting
10037                && userId == UserHandle.USER_OWNER
10038                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10039            r.persistent = true;
10040        }
10041        addProcessNameLocked(r);
10042        return r;
10043    }
10044
10045    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10046            String abiOverride) {
10047        ProcessRecord app;
10048        if (!isolated) {
10049            app = getProcessRecordLocked(info.processName, info.uid, true);
10050        } else {
10051            app = null;
10052        }
10053
10054        if (app == null) {
10055            app = newProcessRecordLocked(info, null, isolated, 0);
10056            updateLruProcessLocked(app, false, null);
10057            updateOomAdjLocked();
10058        }
10059
10060        // This package really, really can not be stopped.
10061        try {
10062            AppGlobals.getPackageManager().setPackageStoppedState(
10063                    info.packageName, false, UserHandle.getUserId(app.uid));
10064        } catch (RemoteException e) {
10065        } catch (IllegalArgumentException e) {
10066            Slog.w(TAG, "Failed trying to unstop package "
10067                    + info.packageName + ": " + e);
10068        }
10069
10070        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10071            app.persistent = true;
10072            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10073        }
10074        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10075            mPersistentStartingProcesses.add(app);
10076            startProcessLocked(app, "added application", app.processName, abiOverride,
10077                    null /* entryPoint */, null /* entryPointArgs */);
10078        }
10079
10080        return app;
10081    }
10082
10083    public void unhandledBack() {
10084        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10085                "unhandledBack()");
10086
10087        synchronized(this) {
10088            final long origId = Binder.clearCallingIdentity();
10089            try {
10090                getFocusedStack().unhandledBackLocked();
10091            } finally {
10092                Binder.restoreCallingIdentity(origId);
10093            }
10094        }
10095    }
10096
10097    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10098        enforceNotIsolatedCaller("openContentUri");
10099        final int userId = UserHandle.getCallingUserId();
10100        String name = uri.getAuthority();
10101        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10102        ParcelFileDescriptor pfd = null;
10103        if (cph != null) {
10104            // We record the binder invoker's uid in thread-local storage before
10105            // going to the content provider to open the file.  Later, in the code
10106            // that handles all permissions checks, we look for this uid and use
10107            // that rather than the Activity Manager's own uid.  The effect is that
10108            // we do the check against the caller's permissions even though it looks
10109            // to the content provider like the Activity Manager itself is making
10110            // the request.
10111            Binder token = new Binder();
10112            sCallerIdentity.set(new Identity(
10113                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10114            try {
10115                pfd = cph.provider.openFile(null, uri, "r", null, token);
10116            } catch (FileNotFoundException e) {
10117                // do nothing; pfd will be returned null
10118            } finally {
10119                // Ensure that whatever happens, we clean up the identity state
10120                sCallerIdentity.remove();
10121                // Ensure we're done with the provider.
10122                removeContentProviderExternalUnchecked(name, null, userId);
10123            }
10124        } else {
10125            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10126        }
10127        return pfd;
10128    }
10129
10130    // Actually is sleeping or shutting down or whatever else in the future
10131    // is an inactive state.
10132    public boolean isSleepingOrShuttingDown() {
10133        return isSleeping() || mShuttingDown;
10134    }
10135
10136    public boolean isSleeping() {
10137        return mSleeping;
10138    }
10139
10140    void onWakefulnessChanged(int wakefulness) {
10141        synchronized(this) {
10142            mWakefulness = wakefulness;
10143            updateSleepIfNeededLocked();
10144        }
10145    }
10146
10147    void finishRunningVoiceLocked() {
10148        if (mRunningVoice != null) {
10149            mRunningVoice = null;
10150            updateSleepIfNeededLocked();
10151        }
10152    }
10153
10154    void updateSleepIfNeededLocked() {
10155        if (mSleeping && !shouldSleepLocked()) {
10156            mSleeping = false;
10157            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10158            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10159            updateOomAdjLocked();
10160        } else if (!mSleeping && shouldSleepLocked()) {
10161            mSleeping = true;
10162            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10163            mStackSupervisor.goingToSleepLocked();
10164            updateOomAdjLocked();
10165
10166            // Initialize the wake times of all processes.
10167            checkExcessivePowerUsageLocked(false);
10168            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10169            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10170            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10171        }
10172    }
10173
10174    private boolean shouldSleepLocked() {
10175        // Resume applications while running a voice interactor.
10176        if (mRunningVoice != null) {
10177            return false;
10178        }
10179
10180        // TODO: Transform the lock screen state into a sleep token instead.
10181        switch (mWakefulness) {
10182            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10183            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10184            case PowerManagerInternal.WAKEFULNESS_DOZING:
10185                // Pause applications whenever the lock screen is shown or any sleep
10186                // tokens have been acquired.
10187                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10188            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10189            default:
10190                // If we're asleep then pause applications unconditionally.
10191                return true;
10192        }
10193    }
10194
10195    /** Pokes the task persister. */
10196    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10197        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10198            // Never persist the home stack.
10199            return;
10200        }
10201        mTaskPersister.wakeup(task, flush);
10202    }
10203
10204    /** Notifies all listeners when the task stack has changed. */
10205    void notifyTaskStackChangedLocked() {
10206        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10207        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10208        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10209    }
10210
10211    @Override
10212    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10213        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10214    }
10215
10216    @Override
10217    public boolean shutdown(int timeout) {
10218        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10219                != PackageManager.PERMISSION_GRANTED) {
10220            throw new SecurityException("Requires permission "
10221                    + android.Manifest.permission.SHUTDOWN);
10222        }
10223
10224        boolean timedout = false;
10225
10226        synchronized(this) {
10227            mShuttingDown = true;
10228            updateEventDispatchingLocked();
10229            timedout = mStackSupervisor.shutdownLocked(timeout);
10230        }
10231
10232        mAppOpsService.shutdown();
10233        if (mUsageStatsService != null) {
10234            mUsageStatsService.prepareShutdown();
10235        }
10236        mBatteryStatsService.shutdown();
10237        synchronized (this) {
10238            mProcessStats.shutdownLocked();
10239            notifyTaskPersisterLocked(null, true);
10240        }
10241
10242        return timedout;
10243    }
10244
10245    public final void activitySlept(IBinder token) {
10246        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10247
10248        final long origId = Binder.clearCallingIdentity();
10249
10250        synchronized (this) {
10251            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10252            if (r != null) {
10253                mStackSupervisor.activitySleptLocked(r);
10254            }
10255        }
10256
10257        Binder.restoreCallingIdentity(origId);
10258    }
10259
10260    private String lockScreenShownToString() {
10261        switch (mLockScreenShown) {
10262            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10263            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10264            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10265            default: return "Unknown=" + mLockScreenShown;
10266        }
10267    }
10268
10269    void logLockScreen(String msg) {
10270        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10271                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10272                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10273                + " mSleeping=" + mSleeping);
10274    }
10275
10276    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10277        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10278        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10279            if (mRunningVoice == null) {
10280                mVoiceWakeLock.acquire();
10281                updateSleepIfNeededLocked();
10282            }
10283            mRunningVoice = session;
10284        }
10285    }
10286
10287    private void updateEventDispatchingLocked() {
10288        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10289    }
10290
10291    public void setLockScreenShown(boolean shown) {
10292        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10293                != PackageManager.PERMISSION_GRANTED) {
10294            throw new SecurityException("Requires permission "
10295                    + android.Manifest.permission.DEVICE_POWER);
10296        }
10297
10298        synchronized(this) {
10299            long ident = Binder.clearCallingIdentity();
10300            try {
10301                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10302                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10303                updateSleepIfNeededLocked();
10304            } finally {
10305                Binder.restoreCallingIdentity(ident);
10306            }
10307        }
10308    }
10309
10310    @Override
10311    public void stopAppSwitches() {
10312        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10313                != PackageManager.PERMISSION_GRANTED) {
10314            throw new SecurityException("Requires permission "
10315                    + android.Manifest.permission.STOP_APP_SWITCHES);
10316        }
10317
10318        synchronized(this) {
10319            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10320                    + APP_SWITCH_DELAY_TIME;
10321            mDidAppSwitch = false;
10322            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10323            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10324            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10325        }
10326    }
10327
10328    public void resumeAppSwitches() {
10329        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10330                != PackageManager.PERMISSION_GRANTED) {
10331            throw new SecurityException("Requires permission "
10332                    + android.Manifest.permission.STOP_APP_SWITCHES);
10333        }
10334
10335        synchronized(this) {
10336            // Note that we don't execute any pending app switches... we will
10337            // let those wait until either the timeout, or the next start
10338            // activity request.
10339            mAppSwitchesAllowedTime = 0;
10340        }
10341    }
10342
10343    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10344            int callingPid, int callingUid, String name) {
10345        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10346            return true;
10347        }
10348
10349        int perm = checkComponentPermission(
10350                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10351                sourceUid, -1, true);
10352        if (perm == PackageManager.PERMISSION_GRANTED) {
10353            return true;
10354        }
10355
10356        // If the actual IPC caller is different from the logical source, then
10357        // also see if they are allowed to control app switches.
10358        if (callingUid != -1 && callingUid != sourceUid) {
10359            perm = checkComponentPermission(
10360                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10361                    callingUid, -1, true);
10362            if (perm == PackageManager.PERMISSION_GRANTED) {
10363                return true;
10364            }
10365        }
10366
10367        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10368        return false;
10369    }
10370
10371    public void setDebugApp(String packageName, boolean waitForDebugger,
10372            boolean persistent) {
10373        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10374                "setDebugApp()");
10375
10376        long ident = Binder.clearCallingIdentity();
10377        try {
10378            // Note that this is not really thread safe if there are multiple
10379            // callers into it at the same time, but that's not a situation we
10380            // care about.
10381            if (persistent) {
10382                final ContentResolver resolver = mContext.getContentResolver();
10383                Settings.Global.putString(
10384                    resolver, Settings.Global.DEBUG_APP,
10385                    packageName);
10386                Settings.Global.putInt(
10387                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10388                    waitForDebugger ? 1 : 0);
10389            }
10390
10391            synchronized (this) {
10392                if (!persistent) {
10393                    mOrigDebugApp = mDebugApp;
10394                    mOrigWaitForDebugger = mWaitForDebugger;
10395                }
10396                mDebugApp = packageName;
10397                mWaitForDebugger = waitForDebugger;
10398                mDebugTransient = !persistent;
10399                if (packageName != null) {
10400                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10401                            false, UserHandle.USER_ALL, "set debug app");
10402                }
10403            }
10404        } finally {
10405            Binder.restoreCallingIdentity(ident);
10406        }
10407    }
10408
10409    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10410        synchronized (this) {
10411            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10412            if (!isDebuggable) {
10413                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10414                    throw new SecurityException("Process not debuggable: " + app.packageName);
10415                }
10416            }
10417
10418            mOpenGlTraceApp = processName;
10419        }
10420    }
10421
10422    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10423        synchronized (this) {
10424            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10425            if (!isDebuggable) {
10426                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10427                    throw new SecurityException("Process not debuggable: " + app.packageName);
10428                }
10429            }
10430            mProfileApp = processName;
10431            mProfileFile = profilerInfo.profileFile;
10432            if (mProfileFd != null) {
10433                try {
10434                    mProfileFd.close();
10435                } catch (IOException e) {
10436                }
10437                mProfileFd = null;
10438            }
10439            mProfileFd = profilerInfo.profileFd;
10440            mSamplingInterval = profilerInfo.samplingInterval;
10441            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10442            mProfileType = 0;
10443        }
10444    }
10445
10446    @Override
10447    public void setAlwaysFinish(boolean enabled) {
10448        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10449                "setAlwaysFinish()");
10450
10451        Settings.Global.putInt(
10452                mContext.getContentResolver(),
10453                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10454
10455        synchronized (this) {
10456            mAlwaysFinishActivities = enabled;
10457        }
10458    }
10459
10460    @Override
10461    public void setActivityController(IActivityController controller) {
10462        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10463                "setActivityController()");
10464        synchronized (this) {
10465            mController = controller;
10466            Watchdog.getInstance().setActivityController(controller);
10467        }
10468    }
10469
10470    @Override
10471    public void setUserIsMonkey(boolean userIsMonkey) {
10472        synchronized (this) {
10473            synchronized (mPidsSelfLocked) {
10474                final int callingPid = Binder.getCallingPid();
10475                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10476                if (precessRecord == null) {
10477                    throw new SecurityException("Unknown process: " + callingPid);
10478                }
10479                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10480                    throw new SecurityException("Only an instrumentation process "
10481                            + "with a UiAutomation can call setUserIsMonkey");
10482                }
10483            }
10484            mUserIsMonkey = userIsMonkey;
10485        }
10486    }
10487
10488    @Override
10489    public boolean isUserAMonkey() {
10490        synchronized (this) {
10491            // If there is a controller also implies the user is a monkey.
10492            return (mUserIsMonkey || mController != null);
10493        }
10494    }
10495
10496    public void requestBugReport() {
10497        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10498        SystemProperties.set("ctl.start", "bugreport");
10499    }
10500
10501    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10502        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10503    }
10504
10505    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10506        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10507            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10508        }
10509        return KEY_DISPATCHING_TIMEOUT;
10510    }
10511
10512    @Override
10513    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10514        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10515                != PackageManager.PERMISSION_GRANTED) {
10516            throw new SecurityException("Requires permission "
10517                    + android.Manifest.permission.FILTER_EVENTS);
10518        }
10519        ProcessRecord proc;
10520        long timeout;
10521        synchronized (this) {
10522            synchronized (mPidsSelfLocked) {
10523                proc = mPidsSelfLocked.get(pid);
10524            }
10525            timeout = getInputDispatchingTimeoutLocked(proc);
10526        }
10527
10528        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10529            return -1;
10530        }
10531
10532        return timeout;
10533    }
10534
10535    /**
10536     * Handle input dispatching timeouts.
10537     * Returns whether input dispatching should be aborted or not.
10538     */
10539    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10540            final ActivityRecord activity, final ActivityRecord parent,
10541            final boolean aboveSystem, String reason) {
10542        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10543                != PackageManager.PERMISSION_GRANTED) {
10544            throw new SecurityException("Requires permission "
10545                    + android.Manifest.permission.FILTER_EVENTS);
10546        }
10547
10548        final String annotation;
10549        if (reason == null) {
10550            annotation = "Input dispatching timed out";
10551        } else {
10552            annotation = "Input dispatching timed out (" + reason + ")";
10553        }
10554
10555        if (proc != null) {
10556            synchronized (this) {
10557                if (proc.debugging) {
10558                    return false;
10559                }
10560
10561                if (mDidDexOpt) {
10562                    // Give more time since we were dexopting.
10563                    mDidDexOpt = false;
10564                    return false;
10565                }
10566
10567                if (proc.instrumentationClass != null) {
10568                    Bundle info = new Bundle();
10569                    info.putString("shortMsg", "keyDispatchingTimedOut");
10570                    info.putString("longMsg", annotation);
10571                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10572                    return true;
10573                }
10574            }
10575            mHandler.post(new Runnable() {
10576                @Override
10577                public void run() {
10578                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10579                }
10580            });
10581        }
10582
10583        return true;
10584    }
10585
10586    @Override
10587    public Bundle getAssistContextExtras(int requestType) {
10588        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10589                UserHandle.getCallingUserId());
10590        if (pae == null) {
10591            return null;
10592        }
10593        synchronized (pae) {
10594            while (!pae.haveResult) {
10595                try {
10596                    pae.wait();
10597                } catch (InterruptedException e) {
10598                }
10599            }
10600        }
10601        synchronized (this) {
10602            buildAssistBundleLocked(pae, pae.result);
10603            mPendingAssistExtras.remove(pae);
10604            mHandler.removeCallbacks(pae);
10605        }
10606        return pae.extras;
10607    }
10608
10609    @Override
10610    public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
10611        enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId());
10612    }
10613
10614    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10615            IResultReceiver receiver, int userHandle) {
10616        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10617                "enqueueAssistContext()");
10618        synchronized (this) {
10619            ActivityRecord activity = getFocusedStack().topActivity();
10620            if (activity == null) {
10621                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10622                return null;
10623            }
10624            if (activity.app == null || activity.app.thread == null) {
10625                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10626                return null;
10627            }
10628            if (activity.app.pid == Binder.getCallingPid()) {
10629                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10630                return null;
10631            }
10632            PendingAssistExtras pae;
10633            Bundle extras = new Bundle();
10634            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10635            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10636            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10637            try {
10638                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10639                        requestType);
10640                mPendingAssistExtras.add(pae);
10641                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10642            } catch (RemoteException e) {
10643                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10644                return null;
10645            }
10646            return pae;
10647        }
10648    }
10649
10650    void pendingAssistExtrasTimedOutLocked(PendingAssistExtras pae) {
10651        mPendingAssistExtras.remove(pae);
10652        if (pae.receiver != null) {
10653            // Caller wants result sent back to them.
10654            try {
10655                pae.receiver.send(0, null);
10656            } catch (RemoteException e) {
10657            }
10658        }
10659    }
10660
10661    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10662        if (result != null) {
10663            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10664        }
10665        if (pae.hint != null) {
10666            pae.extras.putBoolean(pae.hint, true);
10667        }
10668    }
10669
10670    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10671        PendingAssistExtras pae = (PendingAssistExtras)token;
10672        synchronized (pae) {
10673            pae.result = extras;
10674            pae.haveResult = true;
10675            pae.notifyAll();
10676            if (pae.intent == null && pae.receiver == null) {
10677                // Caller is just waiting for the result.
10678                return;
10679            }
10680        }
10681
10682        // We are now ready to launch the assist activity.
10683        synchronized (this) {
10684            buildAssistBundleLocked(pae, extras);
10685            boolean exists = mPendingAssistExtras.remove(pae);
10686            mHandler.removeCallbacks(pae);
10687            if (!exists) {
10688                // Timed out.
10689                return;
10690            }
10691            if (pae.receiver != null) {
10692                // Caller wants result sent back to them.
10693                try {
10694                    pae.receiver.send(0, pae.extras);
10695                } catch (RemoteException e) {
10696                }
10697                return;
10698            }
10699        }
10700        pae.intent.replaceExtras(pae.extras);
10701        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10702                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10703                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10704        closeSystemDialogs("assist");
10705        try {
10706            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10707        } catch (ActivityNotFoundException e) {
10708            Slog.w(TAG, "No activity to handle assist action.", e);
10709        }
10710    }
10711
10712    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10713        return enqueueAssistContext(requestType, intent, hint, null, userHandle) != null;
10714    }
10715
10716    public void registerProcessObserver(IProcessObserver observer) {
10717        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10718                "registerProcessObserver()");
10719        synchronized (this) {
10720            mProcessObservers.register(observer);
10721        }
10722    }
10723
10724    @Override
10725    public void unregisterProcessObserver(IProcessObserver observer) {
10726        synchronized (this) {
10727            mProcessObservers.unregister(observer);
10728        }
10729    }
10730
10731    public void registerUidObserver(IUidObserver observer) {
10732        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10733                "registerUidObserver()");
10734        synchronized (this) {
10735            mUidObservers.register(observer);
10736        }
10737    }
10738
10739    @Override
10740    public void unregisterUidObserver(IUidObserver observer) {
10741        synchronized (this) {
10742            mUidObservers.unregister(observer);
10743        }
10744    }
10745
10746    @Override
10747    public boolean convertFromTranslucent(IBinder token) {
10748        final long origId = Binder.clearCallingIdentity();
10749        try {
10750            synchronized (this) {
10751                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10752                if (r == null) {
10753                    return false;
10754                }
10755                final boolean translucentChanged = r.changeWindowTranslucency(true);
10756                if (translucentChanged) {
10757                    r.task.stack.releaseBackgroundResources(r);
10758                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10759                }
10760                mWindowManager.setAppFullscreen(token, true);
10761                return translucentChanged;
10762            }
10763        } finally {
10764            Binder.restoreCallingIdentity(origId);
10765        }
10766    }
10767
10768    @Override
10769    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10770        final long origId = Binder.clearCallingIdentity();
10771        try {
10772            synchronized (this) {
10773                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10774                if (r == null) {
10775                    return false;
10776                }
10777                int index = r.task.mActivities.lastIndexOf(r);
10778                if (index > 0) {
10779                    ActivityRecord under = r.task.mActivities.get(index - 1);
10780                    under.returningOptions = options;
10781                }
10782                final boolean translucentChanged = r.changeWindowTranslucency(false);
10783                if (translucentChanged) {
10784                    r.task.stack.convertActivityToTranslucent(r);
10785                }
10786                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10787                mWindowManager.setAppFullscreen(token, false);
10788                return translucentChanged;
10789            }
10790        } finally {
10791            Binder.restoreCallingIdentity(origId);
10792        }
10793    }
10794
10795    @Override
10796    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10797        final long origId = Binder.clearCallingIdentity();
10798        try {
10799            synchronized (this) {
10800                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10801                if (r != null) {
10802                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10803                }
10804            }
10805            return false;
10806        } finally {
10807            Binder.restoreCallingIdentity(origId);
10808        }
10809    }
10810
10811    @Override
10812    public boolean isBackgroundVisibleBehind(IBinder token) {
10813        final long origId = Binder.clearCallingIdentity();
10814        try {
10815            synchronized (this) {
10816                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10817                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10818                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10819                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10820                return visible;
10821            }
10822        } finally {
10823            Binder.restoreCallingIdentity(origId);
10824        }
10825    }
10826
10827    @Override
10828    public ActivityOptions getActivityOptions(IBinder token) {
10829        final long origId = Binder.clearCallingIdentity();
10830        try {
10831            synchronized (this) {
10832                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10833                if (r != null) {
10834                    final ActivityOptions activityOptions = r.pendingOptions;
10835                    r.pendingOptions = null;
10836                    return activityOptions;
10837                }
10838                return null;
10839            }
10840        } finally {
10841            Binder.restoreCallingIdentity(origId);
10842        }
10843    }
10844
10845    @Override
10846    public void setImmersive(IBinder token, boolean immersive) {
10847        synchronized(this) {
10848            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10849            if (r == null) {
10850                throw new IllegalArgumentException();
10851            }
10852            r.immersive = immersive;
10853
10854            // update associated state if we're frontmost
10855            if (r == mFocusedActivity) {
10856                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
10857                applyUpdateLockStateLocked(r);
10858            }
10859        }
10860    }
10861
10862    @Override
10863    public boolean isImmersive(IBinder token) {
10864        synchronized (this) {
10865            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10866            if (r == null) {
10867                throw new IllegalArgumentException();
10868            }
10869            return r.immersive;
10870        }
10871    }
10872
10873    public boolean isTopActivityImmersive() {
10874        enforceNotIsolatedCaller("startActivity");
10875        synchronized (this) {
10876            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10877            return (r != null) ? r.immersive : false;
10878        }
10879    }
10880
10881    @Override
10882    public boolean isTopOfTask(IBinder token) {
10883        synchronized (this) {
10884            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10885            if (r == null) {
10886                throw new IllegalArgumentException();
10887            }
10888            return r.task.getTopActivity() == r;
10889        }
10890    }
10891
10892    public final void enterSafeMode() {
10893        synchronized(this) {
10894            // It only makes sense to do this before the system is ready
10895            // and started launching other packages.
10896            if (!mSystemReady) {
10897                try {
10898                    AppGlobals.getPackageManager().enterSafeMode();
10899                } catch (RemoteException e) {
10900                }
10901            }
10902
10903            mSafeMode = true;
10904        }
10905    }
10906
10907    public final void showSafeModeOverlay() {
10908        View v = LayoutInflater.from(mContext).inflate(
10909                com.android.internal.R.layout.safe_mode, null);
10910        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10911        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10912        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10913        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10914        lp.gravity = Gravity.BOTTOM | Gravity.START;
10915        lp.format = v.getBackground().getOpacity();
10916        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10917                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10918        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10919        ((WindowManager)mContext.getSystemService(
10920                Context.WINDOW_SERVICE)).addView(v, lp);
10921    }
10922
10923    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
10924        if (!(sender instanceof PendingIntentRecord)) {
10925            return;
10926        }
10927        final PendingIntentRecord rec = (PendingIntentRecord)sender;
10928        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10929        synchronized (stats) {
10930            if (mBatteryStatsService.isOnBattery()) {
10931                mBatteryStatsService.enforceCallingPermission();
10932                int MY_UID = Binder.getCallingUid();
10933                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10934                BatteryStatsImpl.Uid.Pkg pkg =
10935                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10936                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10937                pkg.noteWakeupAlarmLocked(tag);
10938            }
10939        }
10940    }
10941
10942    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
10943        if (!(sender instanceof PendingIntentRecord)) {
10944            return;
10945        }
10946        final PendingIntentRecord rec = (PendingIntentRecord)sender;
10947        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10948        synchronized (stats) {
10949            mBatteryStatsService.enforceCallingPermission();
10950            int MY_UID = Binder.getCallingUid();
10951            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10952            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
10953        }
10954    }
10955
10956    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
10957        if (!(sender instanceof PendingIntentRecord)) {
10958            return;
10959        }
10960        final PendingIntentRecord rec = (PendingIntentRecord)sender;
10961        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10962        synchronized (stats) {
10963            mBatteryStatsService.enforceCallingPermission();
10964            int MY_UID = Binder.getCallingUid();
10965            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10966            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
10967        }
10968    }
10969
10970    public boolean killPids(int[] pids, String pReason, boolean secure) {
10971        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10972            throw new SecurityException("killPids only available to the system");
10973        }
10974        String reason = (pReason == null) ? "Unknown" : pReason;
10975        // XXX Note: don't acquire main activity lock here, because the window
10976        // manager calls in with its locks held.
10977
10978        boolean killed = false;
10979        synchronized (mPidsSelfLocked) {
10980            int[] types = new int[pids.length];
10981            int worstType = 0;
10982            for (int i=0; i<pids.length; i++) {
10983                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10984                if (proc != null) {
10985                    int type = proc.setAdj;
10986                    types[i] = type;
10987                    if (type > worstType) {
10988                        worstType = type;
10989                    }
10990                }
10991            }
10992
10993            // If the worst oom_adj is somewhere in the cached proc LRU range,
10994            // then constrain it so we will kill all cached procs.
10995            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10996                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10997                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10998            }
10999
11000            // If this is not a secure call, don't let it kill processes that
11001            // are important.
11002            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11003                worstType = ProcessList.SERVICE_ADJ;
11004            }
11005
11006            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11007            for (int i=0; i<pids.length; i++) {
11008                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11009                if (proc == null) {
11010                    continue;
11011                }
11012                int adj = proc.setAdj;
11013                if (adj >= worstType && !proc.killedByAm) {
11014                    proc.kill(reason, true);
11015                    killed = true;
11016                }
11017            }
11018        }
11019        return killed;
11020    }
11021
11022    @Override
11023    public void killUid(int uid, String reason) {
11024        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11025        synchronized (this) {
11026            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
11027                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
11028                    reason != null ? reason : "kill uid");
11029        }
11030    }
11031
11032    @Override
11033    public boolean killProcessesBelowForeground(String reason) {
11034        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11035            throw new SecurityException("killProcessesBelowForeground() only available to system");
11036        }
11037
11038        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11039    }
11040
11041    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11042        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11043            throw new SecurityException("killProcessesBelowAdj() only available to system");
11044        }
11045
11046        boolean killed = false;
11047        synchronized (mPidsSelfLocked) {
11048            final int size = mPidsSelfLocked.size();
11049            for (int i = 0; i < size; i++) {
11050                final int pid = mPidsSelfLocked.keyAt(i);
11051                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11052                if (proc == null) continue;
11053
11054                final int adj = proc.setAdj;
11055                if (adj > belowAdj && !proc.killedByAm) {
11056                    proc.kill(reason, true);
11057                    killed = true;
11058                }
11059            }
11060        }
11061        return killed;
11062    }
11063
11064    @Override
11065    public void hang(final IBinder who, boolean allowRestart) {
11066        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11067                != PackageManager.PERMISSION_GRANTED) {
11068            throw new SecurityException("Requires permission "
11069                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11070        }
11071
11072        final IBinder.DeathRecipient death = new DeathRecipient() {
11073            @Override
11074            public void binderDied() {
11075                synchronized (this) {
11076                    notifyAll();
11077                }
11078            }
11079        };
11080
11081        try {
11082            who.linkToDeath(death, 0);
11083        } catch (RemoteException e) {
11084            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11085            return;
11086        }
11087
11088        synchronized (this) {
11089            Watchdog.getInstance().setAllowRestart(allowRestart);
11090            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11091            synchronized (death) {
11092                while (who.isBinderAlive()) {
11093                    try {
11094                        death.wait();
11095                    } catch (InterruptedException e) {
11096                    }
11097                }
11098            }
11099            Watchdog.getInstance().setAllowRestart(true);
11100        }
11101    }
11102
11103    @Override
11104    public void restart() {
11105        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11106                != PackageManager.PERMISSION_GRANTED) {
11107            throw new SecurityException("Requires permission "
11108                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11109        }
11110
11111        Log.i(TAG, "Sending shutdown broadcast...");
11112
11113        BroadcastReceiver br = new BroadcastReceiver() {
11114            @Override public void onReceive(Context context, Intent intent) {
11115                // Now the broadcast is done, finish up the low-level shutdown.
11116                Log.i(TAG, "Shutting down activity manager...");
11117                shutdown(10000);
11118                Log.i(TAG, "Shutdown complete, restarting!");
11119                Process.killProcess(Process.myPid());
11120                System.exit(10);
11121            }
11122        };
11123
11124        // First send the high-level shut down broadcast.
11125        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11126        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11127        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11128        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11129        mContext.sendOrderedBroadcastAsUser(intent,
11130                UserHandle.ALL, null, br, mHandler, 0, null, null);
11131        */
11132        br.onReceive(mContext, intent);
11133    }
11134
11135    private long getLowRamTimeSinceIdle(long now) {
11136        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11137    }
11138
11139    @Override
11140    public void performIdleMaintenance() {
11141        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11142                != PackageManager.PERMISSION_GRANTED) {
11143            throw new SecurityException("Requires permission "
11144                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11145        }
11146
11147        synchronized (this) {
11148            final long now = SystemClock.uptimeMillis();
11149            final long timeSinceLastIdle = now - mLastIdleTime;
11150            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11151            mLastIdleTime = now;
11152            mLowRamTimeSinceLastIdle = 0;
11153            if (mLowRamStartTime != 0) {
11154                mLowRamStartTime = now;
11155            }
11156
11157            StringBuilder sb = new StringBuilder(128);
11158            sb.append("Idle maintenance over ");
11159            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11160            sb.append(" low RAM for ");
11161            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11162            Slog.i(TAG, sb.toString());
11163
11164            // If at least 1/3 of our time since the last idle period has been spent
11165            // with RAM low, then we want to kill processes.
11166            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11167
11168            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11169                ProcessRecord proc = mLruProcesses.get(i);
11170                if (proc.notCachedSinceIdle) {
11171                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11172                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11173                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11174                        if (doKilling && proc.initialIdlePss != 0
11175                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11176                            sb = new StringBuilder(128);
11177                            sb.append("Kill");
11178                            sb.append(proc.processName);
11179                            sb.append(" in idle maint: pss=");
11180                            sb.append(proc.lastPss);
11181                            sb.append(", initialPss=");
11182                            sb.append(proc.initialIdlePss);
11183                            sb.append(", period=");
11184                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11185                            sb.append(", lowRamPeriod=");
11186                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11187                            Slog.wtfQuiet(TAG, sb.toString());
11188                            proc.kill("idle maint (pss " + proc.lastPss
11189                                    + " from " + proc.initialIdlePss + ")", true);
11190                        }
11191                    }
11192                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11193                    proc.notCachedSinceIdle = true;
11194                    proc.initialIdlePss = 0;
11195                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11196                            mTestPssMode, isSleeping(), now);
11197                }
11198            }
11199
11200            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11201            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11202        }
11203    }
11204
11205    private void retrieveSettings() {
11206        final ContentResolver resolver = mContext.getContentResolver();
11207        String debugApp = Settings.Global.getString(
11208            resolver, Settings.Global.DEBUG_APP);
11209        boolean waitForDebugger = Settings.Global.getInt(
11210            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11211        boolean alwaysFinishActivities = Settings.Global.getInt(
11212            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11213        boolean forceRtl = Settings.Global.getInt(
11214                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11215        // Transfer any global setting for forcing RTL layout, into a System Property
11216        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11217
11218        Configuration configuration = new Configuration();
11219        Settings.System.getConfiguration(resolver, configuration);
11220        if (forceRtl) {
11221            // This will take care of setting the correct layout direction flags
11222            configuration.setLayoutDirection(configuration.locale);
11223        }
11224
11225        synchronized (this) {
11226            mDebugApp = mOrigDebugApp = debugApp;
11227            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11228            mAlwaysFinishActivities = alwaysFinishActivities;
11229            // This happens before any activities are started, so we can
11230            // change mConfiguration in-place.
11231            updateConfigurationLocked(configuration, null, false, true);
11232            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11233                    "Initial config: " + mConfiguration);
11234        }
11235    }
11236
11237    /** Loads resources after the current configuration has been set. */
11238    private void loadResourcesOnSystemReady() {
11239        final Resources res = mContext.getResources();
11240        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11241        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11242        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11243    }
11244
11245    public boolean testIsSystemReady() {
11246        // no need to synchronize(this) just to read & return the value
11247        return mSystemReady;
11248    }
11249
11250    private static File getCalledPreBootReceiversFile() {
11251        File dataDir = Environment.getDataDirectory();
11252        File systemDir = new File(dataDir, "system");
11253        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11254        return fname;
11255    }
11256
11257    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11258        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11259        File file = getCalledPreBootReceiversFile();
11260        FileInputStream fis = null;
11261        try {
11262            fis = new FileInputStream(file);
11263            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11264            int fvers = dis.readInt();
11265            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11266                String vers = dis.readUTF();
11267                String codename = dis.readUTF();
11268                String build = dis.readUTF();
11269                if (android.os.Build.VERSION.RELEASE.equals(vers)
11270                        && android.os.Build.VERSION.CODENAME.equals(codename)
11271                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11272                    int num = dis.readInt();
11273                    while (num > 0) {
11274                        num--;
11275                        String pkg = dis.readUTF();
11276                        String cls = dis.readUTF();
11277                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11278                    }
11279                }
11280            }
11281        } catch (FileNotFoundException e) {
11282        } catch (IOException e) {
11283            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11284        } finally {
11285            if (fis != null) {
11286                try {
11287                    fis.close();
11288                } catch (IOException e) {
11289                }
11290            }
11291        }
11292        return lastDoneReceivers;
11293    }
11294
11295    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11296        File file = getCalledPreBootReceiversFile();
11297        FileOutputStream fos = null;
11298        DataOutputStream dos = null;
11299        try {
11300            fos = new FileOutputStream(file);
11301            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11302            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11303            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11304            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11305            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11306            dos.writeInt(list.size());
11307            for (int i=0; i<list.size(); i++) {
11308                dos.writeUTF(list.get(i).getPackageName());
11309                dos.writeUTF(list.get(i).getClassName());
11310            }
11311        } catch (IOException e) {
11312            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11313            file.delete();
11314        } finally {
11315            FileUtils.sync(fos);
11316            if (dos != null) {
11317                try {
11318                    dos.close();
11319                } catch (IOException e) {
11320                    // TODO Auto-generated catch block
11321                    e.printStackTrace();
11322                }
11323            }
11324        }
11325    }
11326
11327    final class PreBootContinuation extends IIntentReceiver.Stub {
11328        final Intent intent;
11329        final Runnable onFinishCallback;
11330        final ArrayList<ComponentName> doneReceivers;
11331        final List<ResolveInfo> ris;
11332        final int[] users;
11333        int lastRi = -1;
11334        int curRi = 0;
11335        int curUser = 0;
11336
11337        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11338                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11339            intent = _intent;
11340            onFinishCallback = _onFinishCallback;
11341            doneReceivers = _doneReceivers;
11342            ris = _ris;
11343            users = _users;
11344        }
11345
11346        void go() {
11347            if (lastRi != curRi) {
11348                ActivityInfo ai = ris.get(curRi).activityInfo;
11349                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11350                intent.setComponent(comp);
11351                doneReceivers.add(comp);
11352                lastRi = curRi;
11353                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11354                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11355            }
11356            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11357                    + " for user " + users[curUser]);
11358            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11359            broadcastIntentLocked(null, null, intent, null, this,
11360                    0, null, null, null, AppOpsManager.OP_NONE,
11361                    true, false, MY_PID, Process.SYSTEM_UID,
11362                    users[curUser]);
11363        }
11364
11365        public void performReceive(Intent intent, int resultCode,
11366                String data, Bundle extras, boolean ordered,
11367                boolean sticky, int sendingUser) {
11368            curUser++;
11369            if (curUser >= users.length) {
11370                curUser = 0;
11371                curRi++;
11372                if (curRi >= ris.size()) {
11373                    // All done sending broadcasts!
11374                    if (onFinishCallback != null) {
11375                        // The raw IIntentReceiver interface is called
11376                        // with the AM lock held, so redispatch to
11377                        // execute our code without the lock.
11378                        mHandler.post(onFinishCallback);
11379                    }
11380                    return;
11381                }
11382            }
11383            go();
11384        }
11385    }
11386
11387    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11388            ArrayList<ComponentName> doneReceivers, int userId) {
11389        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11390        List<ResolveInfo> ris = null;
11391        try {
11392            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11393                    intent, null, 0, userId);
11394        } catch (RemoteException e) {
11395        }
11396        if (ris == null) {
11397            return false;
11398        }
11399        for (int i=ris.size()-1; i>=0; i--) {
11400            if ((ris.get(i).activityInfo.applicationInfo.flags
11401                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11402                ris.remove(i);
11403            }
11404        }
11405        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11406
11407        // For User 0, load the version number. When delivering to a new user, deliver
11408        // to all receivers.
11409        if (userId == UserHandle.USER_OWNER) {
11410            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11411            for (int i=0; i<ris.size(); i++) {
11412                ActivityInfo ai = ris.get(i).activityInfo;
11413                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11414                if (false && lastDoneReceivers.contains(comp)) {
11415                    // We already did the pre boot receiver for this app with the current
11416                    // platform version, so don't do it again...
11417                    ris.remove(i);
11418                    i--;
11419                    // ...however, do keep it as one that has been done, so we don't
11420                    // forget about it when rewriting the file of last done receivers.
11421                    doneReceivers.add(comp);
11422                }
11423            }
11424        }
11425
11426        if (ris.size() <= 0) {
11427            return false;
11428        }
11429
11430        // If primary user, send broadcast to all available users, else just to userId
11431        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11432                : new int[] { userId };
11433        if (users.length <= 0) {
11434            return false;
11435        }
11436
11437        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11438                ris, users);
11439        cont.go();
11440        return true;
11441    }
11442
11443    public void systemReady(final Runnable goingCallback) {
11444        synchronized(this) {
11445            if (mSystemReady) {
11446                // If we're done calling all the receivers, run the next "boot phase" passed in
11447                // by the SystemServer
11448                if (goingCallback != null) {
11449                    goingCallback.run();
11450                }
11451                return;
11452            }
11453
11454            // Make sure we have the current profile info, since it is needed for
11455            // security checks.
11456            updateCurrentProfileIdsLocked();
11457
11458            mRecentTasks.clear();
11459            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11460            mTaskPersister.restoreTasksFromOtherDeviceLocked();
11461            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11462            mTaskPersister.startPersisting();
11463
11464            // Check to see if there are any update receivers to run.
11465            if (!mDidUpdate) {
11466                if (mWaitingUpdate) {
11467                    return;
11468                }
11469                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11470                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11471                    public void run() {
11472                        synchronized (ActivityManagerService.this) {
11473                            mDidUpdate = true;
11474                        }
11475                        showBootMessage(mContext.getText(
11476                                R.string.android_upgrading_complete),
11477                                false);
11478                        writeLastDonePreBootReceivers(doneReceivers);
11479                        systemReady(goingCallback);
11480                    }
11481                }, doneReceivers, UserHandle.USER_OWNER);
11482
11483                if (mWaitingUpdate) {
11484                    return;
11485                }
11486                mDidUpdate = true;
11487            }
11488
11489            mAppOpsService.systemReady();
11490            mSystemReady = true;
11491        }
11492
11493        ArrayList<ProcessRecord> procsToKill = null;
11494        synchronized(mPidsSelfLocked) {
11495            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11496                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11497                if (!isAllowedWhileBooting(proc.info)){
11498                    if (procsToKill == null) {
11499                        procsToKill = new ArrayList<ProcessRecord>();
11500                    }
11501                    procsToKill.add(proc);
11502                }
11503            }
11504        }
11505
11506        synchronized(this) {
11507            if (procsToKill != null) {
11508                for (int i=procsToKill.size()-1; i>=0; i--) {
11509                    ProcessRecord proc = procsToKill.get(i);
11510                    Slog.i(TAG, "Removing system update proc: " + proc);
11511                    removeProcessLocked(proc, true, false, "system update done");
11512                }
11513            }
11514
11515            // Now that we have cleaned up any update processes, we
11516            // are ready to start launching real processes and know that
11517            // we won't trample on them any more.
11518            mProcessesReady = true;
11519        }
11520
11521        Slog.i(TAG, "System now ready");
11522        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11523            SystemClock.uptimeMillis());
11524
11525        synchronized(this) {
11526            // Make sure we have no pre-ready processes sitting around.
11527
11528            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11529                ResolveInfo ri = mContext.getPackageManager()
11530                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11531                                STOCK_PM_FLAGS);
11532                CharSequence errorMsg = null;
11533                if (ri != null) {
11534                    ActivityInfo ai = ri.activityInfo;
11535                    ApplicationInfo app = ai.applicationInfo;
11536                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11537                        mTopAction = Intent.ACTION_FACTORY_TEST;
11538                        mTopData = null;
11539                        mTopComponent = new ComponentName(app.packageName,
11540                                ai.name);
11541                    } else {
11542                        errorMsg = mContext.getResources().getText(
11543                                com.android.internal.R.string.factorytest_not_system);
11544                    }
11545                } else {
11546                    errorMsg = mContext.getResources().getText(
11547                            com.android.internal.R.string.factorytest_no_action);
11548                }
11549                if (errorMsg != null) {
11550                    mTopAction = null;
11551                    mTopData = null;
11552                    mTopComponent = null;
11553                    Message msg = Message.obtain();
11554                    msg.what = SHOW_FACTORY_ERROR_MSG;
11555                    msg.getData().putCharSequence("msg", errorMsg);
11556                    mUiHandler.sendMessage(msg);
11557                }
11558            }
11559        }
11560
11561        retrieveSettings();
11562        loadResourcesOnSystemReady();
11563
11564        synchronized (this) {
11565            readGrantedUriPermissionsLocked();
11566        }
11567
11568        if (goingCallback != null) goingCallback.run();
11569
11570        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11571                Integer.toString(mCurrentUserId), mCurrentUserId);
11572        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11573                Integer.toString(mCurrentUserId), mCurrentUserId);
11574        mSystemServiceManager.startUser(mCurrentUserId);
11575
11576        synchronized (this) {
11577            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11578                try {
11579                    List apps = AppGlobals.getPackageManager().
11580                        getPersistentApplications(STOCK_PM_FLAGS);
11581                    if (apps != null) {
11582                        int N = apps.size();
11583                        int i;
11584                        for (i=0; i<N; i++) {
11585                            ApplicationInfo info
11586                                = (ApplicationInfo)apps.get(i);
11587                            if (info != null &&
11588                                    !info.packageName.equals("android")) {
11589                                addAppLocked(info, false, null /* ABI override */);
11590                            }
11591                        }
11592                    }
11593                } catch (RemoteException ex) {
11594                    // pm is in same process, this will never happen.
11595                }
11596            }
11597
11598            // Start up initial activity.
11599            mBooting = true;
11600            startHomeActivityLocked(mCurrentUserId, "systemReady");
11601
11602            try {
11603                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11604                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11605                            + " data partition or your device will be unstable.");
11606                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11607                }
11608            } catch (RemoteException e) {
11609            }
11610
11611            if (!Build.isBuildConsistent()) {
11612                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11613                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11614            }
11615
11616            long ident = Binder.clearCallingIdentity();
11617            try {
11618                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11619                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11620                        | Intent.FLAG_RECEIVER_FOREGROUND);
11621                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11622                broadcastIntentLocked(null, null, intent,
11623                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11624                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11625                intent = new Intent(Intent.ACTION_USER_STARTING);
11626                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11627                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11628                broadcastIntentLocked(null, null, intent,
11629                        null, new IIntentReceiver.Stub() {
11630                            @Override
11631                            public void performReceive(Intent intent, int resultCode, String data,
11632                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11633                                    throws RemoteException {
11634                            }
11635                        }, 0, null, null,
11636                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11637                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11638            } catch (Throwable t) {
11639                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11640            } finally {
11641                Binder.restoreCallingIdentity(ident);
11642            }
11643            mStackSupervisor.resumeTopActivitiesLocked();
11644            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11645        }
11646    }
11647
11648    private boolean makeAppCrashingLocked(ProcessRecord app,
11649            String shortMsg, String longMsg, String stackTrace) {
11650        app.crashing = true;
11651        app.crashingReport = generateProcessError(app,
11652                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11653        startAppProblemLocked(app);
11654        app.stopFreezingAllLocked();
11655        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11656    }
11657
11658    private void makeAppNotRespondingLocked(ProcessRecord app,
11659            String activity, String shortMsg, String longMsg) {
11660        app.notResponding = true;
11661        app.notRespondingReport = generateProcessError(app,
11662                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11663                activity, shortMsg, longMsg, null);
11664        startAppProblemLocked(app);
11665        app.stopFreezingAllLocked();
11666    }
11667
11668    /**
11669     * Generate a process error record, suitable for attachment to a ProcessRecord.
11670     *
11671     * @param app The ProcessRecord in which the error occurred.
11672     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11673     *                      ActivityManager.AppErrorStateInfo
11674     * @param activity The activity associated with the crash, if known.
11675     * @param shortMsg Short message describing the crash.
11676     * @param longMsg Long message describing the crash.
11677     * @param stackTrace Full crash stack trace, may be null.
11678     *
11679     * @return Returns a fully-formed AppErrorStateInfo record.
11680     */
11681    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11682            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11683        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11684
11685        report.condition = condition;
11686        report.processName = app.processName;
11687        report.pid = app.pid;
11688        report.uid = app.info.uid;
11689        report.tag = activity;
11690        report.shortMsg = shortMsg;
11691        report.longMsg = longMsg;
11692        report.stackTrace = stackTrace;
11693
11694        return report;
11695    }
11696
11697    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11698        synchronized (this) {
11699            app.crashing = false;
11700            app.crashingReport = null;
11701            app.notResponding = false;
11702            app.notRespondingReport = null;
11703            if (app.anrDialog == fromDialog) {
11704                app.anrDialog = null;
11705            }
11706            if (app.waitDialog == fromDialog) {
11707                app.waitDialog = null;
11708            }
11709            if (app.pid > 0 && app.pid != MY_PID) {
11710                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11711                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11712                app.kill("user request after error", true);
11713            }
11714        }
11715    }
11716
11717    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11718            String shortMsg, String longMsg, String stackTrace) {
11719        long now = SystemClock.uptimeMillis();
11720
11721        Long crashTime;
11722        if (!app.isolated) {
11723            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11724        } else {
11725            crashTime = null;
11726        }
11727        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11728            // This process loses!
11729            Slog.w(TAG, "Process " + app.info.processName
11730                    + " has crashed too many times: killing!");
11731            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11732                    app.userId, app.info.processName, app.uid);
11733            mStackSupervisor.handleAppCrashLocked(app);
11734            if (!app.persistent) {
11735                // We don't want to start this process again until the user
11736                // explicitly does so...  but for persistent process, we really
11737                // need to keep it running.  If a persistent process is actually
11738                // repeatedly crashing, then badness for everyone.
11739                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11740                        app.info.processName);
11741                if (!app.isolated) {
11742                    // XXX We don't have a way to mark isolated processes
11743                    // as bad, since they don't have a peristent identity.
11744                    mBadProcesses.put(app.info.processName, app.uid,
11745                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11746                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11747                }
11748                app.bad = true;
11749                app.removed = true;
11750                // Don't let services in this process be restarted and potentially
11751                // annoy the user repeatedly.  Unless it is persistent, since those
11752                // processes run critical code.
11753                removeProcessLocked(app, false, false, "crash");
11754                mStackSupervisor.resumeTopActivitiesLocked();
11755                return false;
11756            }
11757            mStackSupervisor.resumeTopActivitiesLocked();
11758        } else {
11759            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11760        }
11761
11762        // Bump up the crash count of any services currently running in the proc.
11763        for (int i=app.services.size()-1; i>=0; i--) {
11764            // Any services running in the application need to be placed
11765            // back in the pending list.
11766            ServiceRecord sr = app.services.valueAt(i);
11767            sr.crashCount++;
11768        }
11769
11770        // If the crashing process is what we consider to be the "home process" and it has been
11771        // replaced by a third-party app, clear the package preferred activities from packages
11772        // with a home activity running in the process to prevent a repeatedly crashing app
11773        // from blocking the user to manually clear the list.
11774        final ArrayList<ActivityRecord> activities = app.activities;
11775        if (app == mHomeProcess && activities.size() > 0
11776                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11777            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11778                final ActivityRecord r = activities.get(activityNdx);
11779                if (r.isHomeActivity()) {
11780                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11781                    try {
11782                        ActivityThread.getPackageManager()
11783                                .clearPackagePreferredActivities(r.packageName);
11784                    } catch (RemoteException c) {
11785                        // pm is in same process, this will never happen.
11786                    }
11787                }
11788            }
11789        }
11790
11791        if (!app.isolated) {
11792            // XXX Can't keep track of crash times for isolated processes,
11793            // because they don't have a perisistent identity.
11794            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11795        }
11796
11797        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11798        return true;
11799    }
11800
11801    void startAppProblemLocked(ProcessRecord app) {
11802        // If this app is not running under the current user, then we
11803        // can't give it a report button because that would require
11804        // launching the report UI under a different user.
11805        app.errorReportReceiver = null;
11806
11807        for (int userId : mCurrentProfileIds) {
11808            if (app.userId == userId) {
11809                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11810                        mContext, app.info.packageName, app.info.flags);
11811            }
11812        }
11813        skipCurrentReceiverLocked(app);
11814    }
11815
11816    void skipCurrentReceiverLocked(ProcessRecord app) {
11817        for (BroadcastQueue queue : mBroadcastQueues) {
11818            queue.skipCurrentReceiverLocked(app);
11819        }
11820    }
11821
11822    /**
11823     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11824     * The application process will exit immediately after this call returns.
11825     * @param app object of the crashing app, null for the system server
11826     * @param crashInfo describing the exception
11827     */
11828    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11829        ProcessRecord r = findAppProcess(app, "Crash");
11830        final String processName = app == null ? "system_server"
11831                : (r == null ? "unknown" : r.processName);
11832
11833        handleApplicationCrashInner("crash", r, processName, crashInfo);
11834    }
11835
11836    /* Native crash reporting uses this inner version because it needs to be somewhat
11837     * decoupled from the AM-managed cleanup lifecycle
11838     */
11839    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11840            ApplicationErrorReport.CrashInfo crashInfo) {
11841        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11842                UserHandle.getUserId(Binder.getCallingUid()), processName,
11843                r == null ? -1 : r.info.flags,
11844                crashInfo.exceptionClassName,
11845                crashInfo.exceptionMessage,
11846                crashInfo.throwFileName,
11847                crashInfo.throwLineNumber);
11848
11849        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11850
11851        crashApplication(r, crashInfo);
11852    }
11853
11854    public void handleApplicationStrictModeViolation(
11855            IBinder app,
11856            int violationMask,
11857            StrictMode.ViolationInfo info) {
11858        ProcessRecord r = findAppProcess(app, "StrictMode");
11859        if (r == null) {
11860            return;
11861        }
11862
11863        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11864            Integer stackFingerprint = info.hashCode();
11865            boolean logIt = true;
11866            synchronized (mAlreadyLoggedViolatedStacks) {
11867                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11868                    logIt = false;
11869                    // TODO: sub-sample into EventLog for these, with
11870                    // the info.durationMillis?  Then we'd get
11871                    // the relative pain numbers, without logging all
11872                    // the stack traces repeatedly.  We'd want to do
11873                    // likewise in the client code, which also does
11874                    // dup suppression, before the Binder call.
11875                } else {
11876                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11877                        mAlreadyLoggedViolatedStacks.clear();
11878                    }
11879                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11880                }
11881            }
11882            if (logIt) {
11883                logStrictModeViolationToDropBox(r, info);
11884            }
11885        }
11886
11887        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11888            AppErrorResult result = new AppErrorResult();
11889            synchronized (this) {
11890                final long origId = Binder.clearCallingIdentity();
11891
11892                Message msg = Message.obtain();
11893                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11894                HashMap<String, Object> data = new HashMap<String, Object>();
11895                data.put("result", result);
11896                data.put("app", r);
11897                data.put("violationMask", violationMask);
11898                data.put("info", info);
11899                msg.obj = data;
11900                mUiHandler.sendMessage(msg);
11901
11902                Binder.restoreCallingIdentity(origId);
11903            }
11904            int res = result.get();
11905            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11906        }
11907    }
11908
11909    // Depending on the policy in effect, there could be a bunch of
11910    // these in quick succession so we try to batch these together to
11911    // minimize disk writes, number of dropbox entries, and maximize
11912    // compression, by having more fewer, larger records.
11913    private void logStrictModeViolationToDropBox(
11914            ProcessRecord process,
11915            StrictMode.ViolationInfo info) {
11916        if (info == null) {
11917            return;
11918        }
11919        final boolean isSystemApp = process == null ||
11920                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11921                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11922        final String processName = process == null ? "unknown" : process.processName;
11923        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11924        final DropBoxManager dbox = (DropBoxManager)
11925                mContext.getSystemService(Context.DROPBOX_SERVICE);
11926
11927        // Exit early if the dropbox isn't configured to accept this report type.
11928        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11929
11930        boolean bufferWasEmpty;
11931        boolean needsFlush;
11932        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11933        synchronized (sb) {
11934            bufferWasEmpty = sb.length() == 0;
11935            appendDropBoxProcessHeaders(process, processName, sb);
11936            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11937            sb.append("System-App: ").append(isSystemApp).append("\n");
11938            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11939            if (info.violationNumThisLoop != 0) {
11940                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11941            }
11942            if (info.numAnimationsRunning != 0) {
11943                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11944            }
11945            if (info.broadcastIntentAction != null) {
11946                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11947            }
11948            if (info.durationMillis != -1) {
11949                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11950            }
11951            if (info.numInstances != -1) {
11952                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11953            }
11954            if (info.tags != null) {
11955                for (String tag : info.tags) {
11956                    sb.append("Span-Tag: ").append(tag).append("\n");
11957                }
11958            }
11959            sb.append("\n");
11960            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11961                sb.append(info.crashInfo.stackTrace);
11962                sb.append("\n");
11963            }
11964            if (info.message != null) {
11965                sb.append(info.message);
11966                sb.append("\n");
11967            }
11968
11969            // Only buffer up to ~64k.  Various logging bits truncate
11970            // things at 128k.
11971            needsFlush = (sb.length() > 64 * 1024);
11972        }
11973
11974        // Flush immediately if the buffer's grown too large, or this
11975        // is a non-system app.  Non-system apps are isolated with a
11976        // different tag & policy and not batched.
11977        //
11978        // Batching is useful during internal testing with
11979        // StrictMode settings turned up high.  Without batching,
11980        // thousands of separate files could be created on boot.
11981        if (!isSystemApp || needsFlush) {
11982            new Thread("Error dump: " + dropboxTag) {
11983                @Override
11984                public void run() {
11985                    String report;
11986                    synchronized (sb) {
11987                        report = sb.toString();
11988                        sb.delete(0, sb.length());
11989                        sb.trimToSize();
11990                    }
11991                    if (report.length() != 0) {
11992                        dbox.addText(dropboxTag, report);
11993                    }
11994                }
11995            }.start();
11996            return;
11997        }
11998
11999        // System app batching:
12000        if (!bufferWasEmpty) {
12001            // An existing dropbox-writing thread is outstanding, so
12002            // we don't need to start it up.  The existing thread will
12003            // catch the buffer appends we just did.
12004            return;
12005        }
12006
12007        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12008        // (After this point, we shouldn't access AMS internal data structures.)
12009        new Thread("Error dump: " + dropboxTag) {
12010            @Override
12011            public void run() {
12012                // 5 second sleep to let stacks arrive and be batched together
12013                try {
12014                    Thread.sleep(5000);  // 5 seconds
12015                } catch (InterruptedException e) {}
12016
12017                String errorReport;
12018                synchronized (mStrictModeBuffer) {
12019                    errorReport = mStrictModeBuffer.toString();
12020                    if (errorReport.length() == 0) {
12021                        return;
12022                    }
12023                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12024                    mStrictModeBuffer.trimToSize();
12025                }
12026                dbox.addText(dropboxTag, errorReport);
12027            }
12028        }.start();
12029    }
12030
12031    /**
12032     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12033     * @param app object of the crashing app, null for the system server
12034     * @param tag reported by the caller
12035     * @param system whether this wtf is coming from the system
12036     * @param crashInfo describing the context of the error
12037     * @return true if the process should exit immediately (WTF is fatal)
12038     */
12039    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12040            final ApplicationErrorReport.CrashInfo crashInfo) {
12041        final int callingUid = Binder.getCallingUid();
12042        final int callingPid = Binder.getCallingPid();
12043
12044        if (system) {
12045            // If this is coming from the system, we could very well have low-level
12046            // system locks held, so we want to do this all asynchronously.  And we
12047            // never want this to become fatal, so there is that too.
12048            mHandler.post(new Runnable() {
12049                @Override public void run() {
12050                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12051                }
12052            });
12053            return false;
12054        }
12055
12056        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12057                crashInfo);
12058
12059        if (r != null && r.pid != Process.myPid() &&
12060                Settings.Global.getInt(mContext.getContentResolver(),
12061                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12062            crashApplication(r, crashInfo);
12063            return true;
12064        } else {
12065            return false;
12066        }
12067    }
12068
12069    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12070            final ApplicationErrorReport.CrashInfo crashInfo) {
12071        final ProcessRecord r = findAppProcess(app, "WTF");
12072        final String processName = app == null ? "system_server"
12073                : (r == null ? "unknown" : r.processName);
12074
12075        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12076                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12077
12078        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12079
12080        return r;
12081    }
12082
12083    /**
12084     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12085     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12086     */
12087    private ProcessRecord findAppProcess(IBinder app, String reason) {
12088        if (app == null) {
12089            return null;
12090        }
12091
12092        synchronized (this) {
12093            final int NP = mProcessNames.getMap().size();
12094            for (int ip=0; ip<NP; ip++) {
12095                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12096                final int NA = apps.size();
12097                for (int ia=0; ia<NA; ia++) {
12098                    ProcessRecord p = apps.valueAt(ia);
12099                    if (p.thread != null && p.thread.asBinder() == app) {
12100                        return p;
12101                    }
12102                }
12103            }
12104
12105            Slog.w(TAG, "Can't find mystery application for " + reason
12106                    + " from pid=" + Binder.getCallingPid()
12107                    + " uid=" + Binder.getCallingUid() + ": " + app);
12108            return null;
12109        }
12110    }
12111
12112    /**
12113     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12114     * to append various headers to the dropbox log text.
12115     */
12116    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12117            StringBuilder sb) {
12118        // Watchdog thread ends up invoking this function (with
12119        // a null ProcessRecord) to add the stack file to dropbox.
12120        // Do not acquire a lock on this (am) in such cases, as it
12121        // could cause a potential deadlock, if and when watchdog
12122        // is invoked due to unavailability of lock on am and it
12123        // would prevent watchdog from killing system_server.
12124        if (process == null) {
12125            sb.append("Process: ").append(processName).append("\n");
12126            return;
12127        }
12128        // Note: ProcessRecord 'process' is guarded by the service
12129        // instance.  (notably process.pkgList, which could otherwise change
12130        // concurrently during execution of this method)
12131        synchronized (this) {
12132            sb.append("Process: ").append(processName).append("\n");
12133            int flags = process.info.flags;
12134            IPackageManager pm = AppGlobals.getPackageManager();
12135            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12136            for (int ip=0; ip<process.pkgList.size(); ip++) {
12137                String pkg = process.pkgList.keyAt(ip);
12138                sb.append("Package: ").append(pkg);
12139                try {
12140                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12141                    if (pi != null) {
12142                        sb.append(" v").append(pi.versionCode);
12143                        if (pi.versionName != null) {
12144                            sb.append(" (").append(pi.versionName).append(")");
12145                        }
12146                    }
12147                } catch (RemoteException e) {
12148                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12149                }
12150                sb.append("\n");
12151            }
12152        }
12153    }
12154
12155    private static String processClass(ProcessRecord process) {
12156        if (process == null || process.pid == MY_PID) {
12157            return "system_server";
12158        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12159            return "system_app";
12160        } else {
12161            return "data_app";
12162        }
12163    }
12164
12165    /**
12166     * Write a description of an error (crash, WTF, ANR) to the drop box.
12167     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12168     * @param process which caused the error, null means the system server
12169     * @param activity which triggered the error, null if unknown
12170     * @param parent activity related to the error, null if unknown
12171     * @param subject line related to the error, null if absent
12172     * @param report in long form describing the error, null if absent
12173     * @param logFile to include in the report, null if none
12174     * @param crashInfo giving an application stack trace, null if absent
12175     */
12176    public void addErrorToDropBox(String eventType,
12177            ProcessRecord process, String processName, ActivityRecord activity,
12178            ActivityRecord parent, String subject,
12179            final String report, final File logFile,
12180            final ApplicationErrorReport.CrashInfo crashInfo) {
12181        // NOTE -- this must never acquire the ActivityManagerService lock,
12182        // otherwise the watchdog may be prevented from resetting the system.
12183
12184        final String dropboxTag = processClass(process) + "_" + eventType;
12185        final DropBoxManager dbox = (DropBoxManager)
12186                mContext.getSystemService(Context.DROPBOX_SERVICE);
12187
12188        // Exit early if the dropbox isn't configured to accept this report type.
12189        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12190
12191        final StringBuilder sb = new StringBuilder(1024);
12192        appendDropBoxProcessHeaders(process, processName, sb);
12193        if (activity != null) {
12194            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12195        }
12196        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12197            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12198        }
12199        if (parent != null && parent != activity) {
12200            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12201        }
12202        if (subject != null) {
12203            sb.append("Subject: ").append(subject).append("\n");
12204        }
12205        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12206        if (Debug.isDebuggerConnected()) {
12207            sb.append("Debugger: Connected\n");
12208        }
12209        sb.append("\n");
12210
12211        // Do the rest in a worker thread to avoid blocking the caller on I/O
12212        // (After this point, we shouldn't access AMS internal data structures.)
12213        Thread worker = new Thread("Error dump: " + dropboxTag) {
12214            @Override
12215            public void run() {
12216                if (report != null) {
12217                    sb.append(report);
12218                }
12219                if (logFile != null) {
12220                    try {
12221                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12222                                    "\n\n[[TRUNCATED]]"));
12223                    } catch (IOException e) {
12224                        Slog.e(TAG, "Error reading " + logFile, e);
12225                    }
12226                }
12227                if (crashInfo != null && crashInfo.stackTrace != null) {
12228                    sb.append(crashInfo.stackTrace);
12229                }
12230
12231                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12232                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12233                if (lines > 0) {
12234                    sb.append("\n");
12235
12236                    // Merge several logcat streams, and take the last N lines
12237                    InputStreamReader input = null;
12238                    try {
12239                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12240                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12241                                "-b", "crash",
12242                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12243
12244                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12245                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12246                        input = new InputStreamReader(logcat.getInputStream());
12247
12248                        int num;
12249                        char[] buf = new char[8192];
12250                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12251                    } catch (IOException e) {
12252                        Slog.e(TAG, "Error running logcat", e);
12253                    } finally {
12254                        if (input != null) try { input.close(); } catch (IOException e) {}
12255                    }
12256                }
12257
12258                dbox.addText(dropboxTag, sb.toString());
12259            }
12260        };
12261
12262        if (process == null) {
12263            // If process is null, we are being called from some internal code
12264            // and may be about to die -- run this synchronously.
12265            worker.run();
12266        } else {
12267            worker.start();
12268        }
12269    }
12270
12271    /**
12272     * Bring up the "unexpected error" dialog box for a crashing app.
12273     * Deal with edge cases (intercepts from instrumented applications,
12274     * ActivityController, error intent receivers, that sort of thing).
12275     * @param r the application crashing
12276     * @param crashInfo describing the failure
12277     */
12278    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12279        long timeMillis = System.currentTimeMillis();
12280        String shortMsg = crashInfo.exceptionClassName;
12281        String longMsg = crashInfo.exceptionMessage;
12282        String stackTrace = crashInfo.stackTrace;
12283        if (shortMsg != null && longMsg != null) {
12284            longMsg = shortMsg + ": " + longMsg;
12285        } else if (shortMsg != null) {
12286            longMsg = shortMsg;
12287        }
12288
12289        AppErrorResult result = new AppErrorResult();
12290        synchronized (this) {
12291            if (mController != null) {
12292                try {
12293                    String name = r != null ? r.processName : null;
12294                    int pid = r != null ? r.pid : Binder.getCallingPid();
12295                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12296                    if (!mController.appCrashed(name, pid,
12297                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12298                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12299                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12300                            Slog.w(TAG, "Skip killing native crashed app " + name
12301                                    + "(" + pid + ") during testing");
12302                        } else {
12303                            Slog.w(TAG, "Force-killing crashed app " + name
12304                                    + " at watcher's request");
12305                            if (r != null) {
12306                                r.kill("crash", true);
12307                            } else {
12308                                // Huh.
12309                                Process.killProcess(pid);
12310                                Process.killProcessGroup(uid, pid);
12311                            }
12312                        }
12313                        return;
12314                    }
12315                } catch (RemoteException e) {
12316                    mController = null;
12317                    Watchdog.getInstance().setActivityController(null);
12318                }
12319            }
12320
12321            final long origId = Binder.clearCallingIdentity();
12322
12323            // If this process is running instrumentation, finish it.
12324            if (r != null && r.instrumentationClass != null) {
12325                Slog.w(TAG, "Error in app " + r.processName
12326                      + " running instrumentation " + r.instrumentationClass + ":");
12327                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12328                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12329                Bundle info = new Bundle();
12330                info.putString("shortMsg", shortMsg);
12331                info.putString("longMsg", longMsg);
12332                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12333                Binder.restoreCallingIdentity(origId);
12334                return;
12335            }
12336
12337            // Log crash in battery stats.
12338            if (r != null) {
12339                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12340            }
12341
12342            // If we can't identify the process or it's already exceeded its crash quota,
12343            // quit right away without showing a crash dialog.
12344            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12345                Binder.restoreCallingIdentity(origId);
12346                return;
12347            }
12348
12349            Message msg = Message.obtain();
12350            msg.what = SHOW_ERROR_MSG;
12351            HashMap data = new HashMap();
12352            data.put("result", result);
12353            data.put("app", r);
12354            msg.obj = data;
12355            mUiHandler.sendMessage(msg);
12356
12357            Binder.restoreCallingIdentity(origId);
12358        }
12359
12360        int res = result.get();
12361
12362        Intent appErrorIntent = null;
12363        synchronized (this) {
12364            if (r != null && !r.isolated) {
12365                // XXX Can't keep track of crash time for isolated processes,
12366                // since they don't have a persistent identity.
12367                mProcessCrashTimes.put(r.info.processName, r.uid,
12368                        SystemClock.uptimeMillis());
12369            }
12370            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12371                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12372            }
12373        }
12374
12375        if (appErrorIntent != null) {
12376            try {
12377                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12378            } catch (ActivityNotFoundException e) {
12379                Slog.w(TAG, "bug report receiver dissappeared", e);
12380            }
12381        }
12382    }
12383
12384    Intent createAppErrorIntentLocked(ProcessRecord r,
12385            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12386        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12387        if (report == null) {
12388            return null;
12389        }
12390        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12391        result.setComponent(r.errorReportReceiver);
12392        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12393        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12394        return result;
12395    }
12396
12397    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12398            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12399        if (r.errorReportReceiver == null) {
12400            return null;
12401        }
12402
12403        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12404            return null;
12405        }
12406
12407        ApplicationErrorReport report = new ApplicationErrorReport();
12408        report.packageName = r.info.packageName;
12409        report.installerPackageName = r.errorReportReceiver.getPackageName();
12410        report.processName = r.processName;
12411        report.time = timeMillis;
12412        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12413
12414        if (r.crashing || r.forceCrashReport) {
12415            report.type = ApplicationErrorReport.TYPE_CRASH;
12416            report.crashInfo = crashInfo;
12417        } else if (r.notResponding) {
12418            report.type = ApplicationErrorReport.TYPE_ANR;
12419            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12420
12421            report.anrInfo.activity = r.notRespondingReport.tag;
12422            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12423            report.anrInfo.info = r.notRespondingReport.longMsg;
12424        }
12425
12426        return report;
12427    }
12428
12429    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12430        enforceNotIsolatedCaller("getProcessesInErrorState");
12431        // assume our apps are happy - lazy create the list
12432        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12433
12434        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12435                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12436        int userId = UserHandle.getUserId(Binder.getCallingUid());
12437
12438        synchronized (this) {
12439
12440            // iterate across all processes
12441            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12442                ProcessRecord app = mLruProcesses.get(i);
12443                if (!allUsers && app.userId != userId) {
12444                    continue;
12445                }
12446                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12447                    // This one's in trouble, so we'll generate a report for it
12448                    // crashes are higher priority (in case there's a crash *and* an anr)
12449                    ActivityManager.ProcessErrorStateInfo report = null;
12450                    if (app.crashing) {
12451                        report = app.crashingReport;
12452                    } else if (app.notResponding) {
12453                        report = app.notRespondingReport;
12454                    }
12455
12456                    if (report != null) {
12457                        if (errList == null) {
12458                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12459                        }
12460                        errList.add(report);
12461                    } else {
12462                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12463                                " crashing = " + app.crashing +
12464                                " notResponding = " + app.notResponding);
12465                    }
12466                }
12467            }
12468        }
12469
12470        return errList;
12471    }
12472
12473    static int procStateToImportance(int procState, int memAdj,
12474            ActivityManager.RunningAppProcessInfo currApp) {
12475        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12476        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12477            currApp.lru = memAdj;
12478        } else {
12479            currApp.lru = 0;
12480        }
12481        return imp;
12482    }
12483
12484    private void fillInProcMemInfo(ProcessRecord app,
12485            ActivityManager.RunningAppProcessInfo outInfo) {
12486        outInfo.pid = app.pid;
12487        outInfo.uid = app.info.uid;
12488        if (mHeavyWeightProcess == app) {
12489            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12490        }
12491        if (app.persistent) {
12492            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12493        }
12494        if (app.activities.size() > 0) {
12495            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12496        }
12497        outInfo.lastTrimLevel = app.trimMemoryLevel;
12498        int adj = app.curAdj;
12499        int procState = app.curProcState;
12500        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12501        outInfo.importanceReasonCode = app.adjTypeCode;
12502        outInfo.processState = app.curProcState;
12503    }
12504
12505    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12506        enforceNotIsolatedCaller("getRunningAppProcesses");
12507
12508        final int callingUid = Binder.getCallingUid();
12509
12510        // Lazy instantiation of list
12511        List<ActivityManager.RunningAppProcessInfo> runList = null;
12512        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12513                callingUid) == PackageManager.PERMISSION_GRANTED;
12514        final int userId = UserHandle.getUserId(callingUid);
12515        final boolean allUids = isGetTasksAllowed(
12516                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12517
12518        synchronized (this) {
12519            // Iterate across all processes
12520            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12521                ProcessRecord app = mLruProcesses.get(i);
12522                if ((!allUsers && app.userId != userId)
12523                        || (!allUids && app.uid != callingUid)) {
12524                    continue;
12525                }
12526                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12527                    // Generate process state info for running application
12528                    ActivityManager.RunningAppProcessInfo currApp =
12529                        new ActivityManager.RunningAppProcessInfo(app.processName,
12530                                app.pid, app.getPackageList());
12531                    fillInProcMemInfo(app, currApp);
12532                    if (app.adjSource instanceof ProcessRecord) {
12533                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12534                        currApp.importanceReasonImportance =
12535                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12536                                        app.adjSourceProcState);
12537                    } else if (app.adjSource instanceof ActivityRecord) {
12538                        ActivityRecord r = (ActivityRecord)app.adjSource;
12539                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12540                    }
12541                    if (app.adjTarget instanceof ComponentName) {
12542                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12543                    }
12544                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12545                    //        + " lru=" + currApp.lru);
12546                    if (runList == null) {
12547                        runList = new ArrayList<>();
12548                    }
12549                    runList.add(currApp);
12550                }
12551            }
12552        }
12553        return runList;
12554    }
12555
12556    public List<ApplicationInfo> getRunningExternalApplications() {
12557        enforceNotIsolatedCaller("getRunningExternalApplications");
12558        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12559        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12560        if (runningApps != null && runningApps.size() > 0) {
12561            Set<String> extList = new HashSet<String>();
12562            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12563                if (app.pkgList != null) {
12564                    for (String pkg : app.pkgList) {
12565                        extList.add(pkg);
12566                    }
12567                }
12568            }
12569            IPackageManager pm = AppGlobals.getPackageManager();
12570            for (String pkg : extList) {
12571                try {
12572                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12573                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12574                        retList.add(info);
12575                    }
12576                } catch (RemoteException e) {
12577                }
12578            }
12579        }
12580        return retList;
12581    }
12582
12583    @Override
12584    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12585        enforceNotIsolatedCaller("getMyMemoryState");
12586        synchronized (this) {
12587            ProcessRecord proc;
12588            synchronized (mPidsSelfLocked) {
12589                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12590            }
12591            fillInProcMemInfo(proc, outInfo);
12592        }
12593    }
12594
12595    @Override
12596    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12597        if (checkCallingPermission(android.Manifest.permission.DUMP)
12598                != PackageManager.PERMISSION_GRANTED) {
12599            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12600                    + Binder.getCallingPid()
12601                    + ", uid=" + Binder.getCallingUid()
12602                    + " without permission "
12603                    + android.Manifest.permission.DUMP);
12604            return;
12605        }
12606
12607        boolean dumpAll = false;
12608        boolean dumpClient = false;
12609        String dumpPackage = null;
12610
12611        int opti = 0;
12612        while (opti < args.length) {
12613            String opt = args[opti];
12614            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12615                break;
12616            }
12617            opti++;
12618            if ("-a".equals(opt)) {
12619                dumpAll = true;
12620            } else if ("-c".equals(opt)) {
12621                dumpClient = true;
12622            } else if ("-p".equals(opt)) {
12623                if (opti < args.length) {
12624                    dumpPackage = args[opti];
12625                    opti++;
12626                } else {
12627                    pw.println("Error: -p option requires package argument");
12628                    return;
12629                }
12630                dumpClient = true;
12631            } else if ("-h".equals(opt)) {
12632                pw.println("Activity manager dump options:");
12633                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12634                pw.println("  cmd may be one of:");
12635                pw.println("    a[ctivities]: activity stack state");
12636                pw.println("    r[recents]: recent activities state");
12637                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12638                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12639                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12640                pw.println("    o[om]: out of memory management");
12641                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12642                pw.println("    provider [COMP_SPEC]: provider client-side state");
12643                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12644                pw.println("    as[sociations]: tracked app associations");
12645                pw.println("    service [COMP_SPEC]: service client-side state");
12646                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12647                pw.println("    all: dump all activities");
12648                pw.println("    top: dump the top activity");
12649                pw.println("    write: write all pending state to storage");
12650                pw.println("    track-associations: enable association tracking");
12651                pw.println("    untrack-associations: disable and clear association tracking");
12652                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12653                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12654                pw.println("    a partial substring in a component name, a");
12655                pw.println("    hex object identifier.");
12656                pw.println("  -a: include all available server state.");
12657                pw.println("  -c: include client state.");
12658                pw.println("  -p: limit output to given package.");
12659                return;
12660            } else {
12661                pw.println("Unknown argument: " + opt + "; use -h for help");
12662            }
12663        }
12664
12665        long origId = Binder.clearCallingIdentity();
12666        boolean more = false;
12667        // Is the caller requesting to dump a particular piece of data?
12668        if (opti < args.length) {
12669            String cmd = args[opti];
12670            opti++;
12671            if ("activities".equals(cmd) || "a".equals(cmd)) {
12672                synchronized (this) {
12673                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12674                }
12675            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12676                synchronized (this) {
12677                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12678                }
12679            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12680                String[] newArgs;
12681                String name;
12682                if (opti >= args.length) {
12683                    name = null;
12684                    newArgs = EMPTY_STRING_ARRAY;
12685                } else {
12686                    dumpPackage = args[opti];
12687                    opti++;
12688                    newArgs = new String[args.length - opti];
12689                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12690                            args.length - opti);
12691                }
12692                synchronized (this) {
12693                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12694                }
12695            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12696                String[] newArgs;
12697                String name;
12698                if (opti >= args.length) {
12699                    name = null;
12700                    newArgs = EMPTY_STRING_ARRAY;
12701                } else {
12702                    dumpPackage = args[opti];
12703                    opti++;
12704                    newArgs = new String[args.length - opti];
12705                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12706                            args.length - opti);
12707                }
12708                synchronized (this) {
12709                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12710                }
12711            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12712                String[] newArgs;
12713                String name;
12714                if (opti >= args.length) {
12715                    name = null;
12716                    newArgs = EMPTY_STRING_ARRAY;
12717                } else {
12718                    dumpPackage = args[opti];
12719                    opti++;
12720                    newArgs = new String[args.length - opti];
12721                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12722                            args.length - opti);
12723                }
12724                synchronized (this) {
12725                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12726                }
12727            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12728                synchronized (this) {
12729                    dumpOomLocked(fd, pw, args, opti, true);
12730                }
12731            } else if ("provider".equals(cmd)) {
12732                String[] newArgs;
12733                String name;
12734                if (opti >= args.length) {
12735                    name = null;
12736                    newArgs = EMPTY_STRING_ARRAY;
12737                } else {
12738                    name = args[opti];
12739                    opti++;
12740                    newArgs = new String[args.length - opti];
12741                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12742                }
12743                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12744                    pw.println("No providers match: " + name);
12745                    pw.println("Use -h for help.");
12746                }
12747            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12748                synchronized (this) {
12749                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12750                }
12751            } else if ("service".equals(cmd)) {
12752                String[] newArgs;
12753                String name;
12754                if (opti >= args.length) {
12755                    name = null;
12756                    newArgs = EMPTY_STRING_ARRAY;
12757                } else {
12758                    name = args[opti];
12759                    opti++;
12760                    newArgs = new String[args.length - opti];
12761                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12762                            args.length - opti);
12763                }
12764                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12765                    pw.println("No services match: " + name);
12766                    pw.println("Use -h for help.");
12767                }
12768            } else if ("package".equals(cmd)) {
12769                String[] newArgs;
12770                if (opti >= args.length) {
12771                    pw.println("package: no package name specified");
12772                    pw.println("Use -h for help.");
12773                } else {
12774                    dumpPackage = args[opti];
12775                    opti++;
12776                    newArgs = new String[args.length - opti];
12777                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12778                            args.length - opti);
12779                    args = newArgs;
12780                    opti = 0;
12781                    more = true;
12782                }
12783            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12784                synchronized (this) {
12785                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12786                }
12787            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12788                synchronized (this) {
12789                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12790                }
12791            } else if ("write".equals(cmd)) {
12792                mTaskPersister.flush();
12793                pw.println("All tasks persisted.");
12794                return;
12795            } else if ("track-associations".equals(cmd)) {
12796                synchronized (this) {
12797                    if (!mTrackingAssociations) {
12798                        mTrackingAssociations = true;
12799                        pw.println("Association tracking started.");
12800                    } else {
12801                        pw.println("Association tracking already enabled.");
12802                    }
12803                }
12804                return;
12805            } else if ("untrack-associations".equals(cmd)) {
12806                synchronized (this) {
12807                    if (mTrackingAssociations) {
12808                        mTrackingAssociations = false;
12809                        mAssociations.clear();
12810                        pw.println("Association tracking stopped.");
12811                    } else {
12812                        pw.println("Association tracking not running.");
12813                    }
12814                }
12815                return;
12816            } else {
12817                // Dumping a single activity?
12818                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12819                    pw.println("Bad activity command, or no activities match: " + cmd);
12820                    pw.println("Use -h for help.");
12821                }
12822            }
12823            if (!more) {
12824                Binder.restoreCallingIdentity(origId);
12825                return;
12826            }
12827        }
12828
12829        // No piece of data specified, dump everything.
12830        synchronized (this) {
12831            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12832            pw.println();
12833            if (dumpAll) {
12834                pw.println("-------------------------------------------------------------------------------");
12835            }
12836            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12837            pw.println();
12838            if (dumpAll) {
12839                pw.println("-------------------------------------------------------------------------------");
12840            }
12841            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12842            pw.println();
12843            if (dumpAll) {
12844                pw.println("-------------------------------------------------------------------------------");
12845            }
12846            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12847            pw.println();
12848            if (dumpAll) {
12849                pw.println("-------------------------------------------------------------------------------");
12850            }
12851            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12852            pw.println();
12853            if (dumpAll) {
12854                pw.println("-------------------------------------------------------------------------------");
12855            }
12856            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12857            if (mAssociations.size() > 0) {
12858                pw.println();
12859                if (dumpAll) {
12860                    pw.println("-------------------------------------------------------------------------------");
12861                }
12862                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12863            }
12864            pw.println();
12865            if (dumpAll) {
12866                pw.println("-------------------------------------------------------------------------------");
12867            }
12868            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12869        }
12870        Binder.restoreCallingIdentity(origId);
12871    }
12872
12873    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12874            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12875        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12876
12877        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12878                dumpPackage);
12879        boolean needSep = printedAnything;
12880
12881        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12882                dumpPackage, needSep, "  mFocusedActivity: ");
12883        if (printed) {
12884            printedAnything = true;
12885            needSep = false;
12886        }
12887
12888        if (dumpPackage == null) {
12889            if (needSep) {
12890                pw.println();
12891            }
12892            needSep = true;
12893            printedAnything = true;
12894            mStackSupervisor.dump(pw, "  ");
12895        }
12896
12897        if (!printedAnything) {
12898            pw.println("  (nothing)");
12899        }
12900    }
12901
12902    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12903            int opti, boolean dumpAll, String dumpPackage) {
12904        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12905
12906        boolean printedAnything = false;
12907
12908        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12909            boolean printedHeader = false;
12910
12911            final int N = mRecentTasks.size();
12912            for (int i=0; i<N; i++) {
12913                TaskRecord tr = mRecentTasks.get(i);
12914                if (dumpPackage != null) {
12915                    if (tr.realActivity == null ||
12916                            !dumpPackage.equals(tr.realActivity)) {
12917                        continue;
12918                    }
12919                }
12920                if (!printedHeader) {
12921                    pw.println("  Recent tasks:");
12922                    printedHeader = true;
12923                    printedAnything = true;
12924                }
12925                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12926                        pw.println(tr);
12927                if (dumpAll) {
12928                    mRecentTasks.get(i).dump(pw, "    ");
12929                }
12930            }
12931        }
12932
12933        if (!printedAnything) {
12934            pw.println("  (nothing)");
12935        }
12936    }
12937
12938    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12939            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12940        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12941
12942        int dumpUid = 0;
12943        if (dumpPackage != null) {
12944            IPackageManager pm = AppGlobals.getPackageManager();
12945            try {
12946                dumpUid = pm.getPackageUid(dumpPackage, 0);
12947            } catch (RemoteException e) {
12948            }
12949        }
12950
12951        boolean printedAnything = false;
12952
12953        final long now = SystemClock.uptimeMillis();
12954
12955        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12956            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12957                    = mAssociations.valueAt(i1);
12958            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12959                SparseArray<ArrayMap<String, Association>> sourceUids
12960                        = targetComponents.valueAt(i2);
12961                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12962                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12963                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12964                        Association ass = sourceProcesses.valueAt(i4);
12965                        if (dumpPackage != null) {
12966                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12967                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12968                                continue;
12969                            }
12970                        }
12971                        printedAnything = true;
12972                        pw.print("  ");
12973                        pw.print(ass.mTargetProcess);
12974                        pw.print("/");
12975                        UserHandle.formatUid(pw, ass.mTargetUid);
12976                        pw.print(" <- ");
12977                        pw.print(ass.mSourceProcess);
12978                        pw.print("/");
12979                        UserHandle.formatUid(pw, ass.mSourceUid);
12980                        pw.println();
12981                        pw.print("    via ");
12982                        pw.print(ass.mTargetComponent.flattenToShortString());
12983                        pw.println();
12984                        pw.print("    ");
12985                        long dur = ass.mTime;
12986                        if (ass.mNesting > 0) {
12987                            dur += now - ass.mStartTime;
12988                        }
12989                        TimeUtils.formatDuration(dur, pw);
12990                        pw.print(" (");
12991                        pw.print(ass.mCount);
12992                        pw.println(" times)");
12993                        if (ass.mNesting > 0) {
12994                            pw.print("    ");
12995                            pw.print(" Currently active: ");
12996                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
12997                            pw.println();
12998                        }
12999                    }
13000                }
13001            }
13002
13003        }
13004
13005        if (!printedAnything) {
13006            pw.println("  (nothing)");
13007        }
13008    }
13009
13010    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13011            int opti, boolean dumpAll, String dumpPackage) {
13012        boolean needSep = false;
13013        boolean printedAnything = false;
13014        int numPers = 0;
13015
13016        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13017
13018        if (dumpAll) {
13019            final int NP = mProcessNames.getMap().size();
13020            for (int ip=0; ip<NP; ip++) {
13021                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13022                final int NA = procs.size();
13023                for (int ia=0; ia<NA; ia++) {
13024                    ProcessRecord r = procs.valueAt(ia);
13025                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13026                        continue;
13027                    }
13028                    if (!needSep) {
13029                        pw.println("  All known processes:");
13030                        needSep = true;
13031                        printedAnything = true;
13032                    }
13033                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13034                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13035                        pw.print(" "); pw.println(r);
13036                    r.dump(pw, "    ");
13037                    if (r.persistent) {
13038                        numPers++;
13039                    }
13040                }
13041            }
13042        }
13043
13044        if (mIsolatedProcesses.size() > 0) {
13045            boolean printed = false;
13046            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13047                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13048                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13049                    continue;
13050                }
13051                if (!printed) {
13052                    if (needSep) {
13053                        pw.println();
13054                    }
13055                    pw.println("  Isolated process list (sorted by uid):");
13056                    printedAnything = true;
13057                    printed = true;
13058                    needSep = true;
13059                }
13060                pw.println(String.format("%sIsolated #%2d: %s",
13061                        "    ", i, r.toString()));
13062            }
13063        }
13064
13065        if (mActiveUids.size() > 0) {
13066            if (needSep) {
13067                pw.println();
13068            }
13069            pw.println("  UID states:");
13070            for (int i=0; i<mActiveUids.size(); i++) {
13071                UidRecord uidRec = mActiveUids.valueAt(i);
13072                pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13073                pw.print(": "); pw.println(uidRec);
13074            }
13075            needSep = true;
13076            printedAnything = true;
13077        }
13078
13079        if (mLruProcesses.size() > 0) {
13080            if (needSep) {
13081                pw.println();
13082            }
13083            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13084                    pw.print(" total, non-act at ");
13085                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13086                    pw.print(", non-svc at ");
13087                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13088                    pw.println("):");
13089            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13090            needSep = true;
13091            printedAnything = true;
13092        }
13093
13094        if (dumpAll || dumpPackage != null) {
13095            synchronized (mPidsSelfLocked) {
13096                boolean printed = false;
13097                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13098                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13099                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13100                        continue;
13101                    }
13102                    if (!printed) {
13103                        if (needSep) pw.println();
13104                        needSep = true;
13105                        pw.println("  PID mappings:");
13106                        printed = true;
13107                        printedAnything = true;
13108                    }
13109                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13110                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13111                }
13112            }
13113        }
13114
13115        if (mForegroundProcesses.size() > 0) {
13116            synchronized (mPidsSelfLocked) {
13117                boolean printed = false;
13118                for (int i=0; i<mForegroundProcesses.size(); i++) {
13119                    ProcessRecord r = mPidsSelfLocked.get(
13120                            mForegroundProcesses.valueAt(i).pid);
13121                    if (dumpPackage != null && (r == null
13122                            || !r.pkgList.containsKey(dumpPackage))) {
13123                        continue;
13124                    }
13125                    if (!printed) {
13126                        if (needSep) pw.println();
13127                        needSep = true;
13128                        pw.println("  Foreground Processes:");
13129                        printed = true;
13130                        printedAnything = true;
13131                    }
13132                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13133                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13134                }
13135            }
13136        }
13137
13138        if (mPersistentStartingProcesses.size() > 0) {
13139            if (needSep) pw.println();
13140            needSep = true;
13141            printedAnything = true;
13142            pw.println("  Persisent processes that are starting:");
13143            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13144                    "Starting Norm", "Restarting PERS", dumpPackage);
13145        }
13146
13147        if (mRemovedProcesses.size() > 0) {
13148            if (needSep) pw.println();
13149            needSep = true;
13150            printedAnything = true;
13151            pw.println("  Processes that are being removed:");
13152            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13153                    "Removed Norm", "Removed PERS", dumpPackage);
13154        }
13155
13156        if (mProcessesOnHold.size() > 0) {
13157            if (needSep) pw.println();
13158            needSep = true;
13159            printedAnything = true;
13160            pw.println("  Processes that are on old until the system is ready:");
13161            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13162                    "OnHold Norm", "OnHold PERS", dumpPackage);
13163        }
13164
13165        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13166
13167        if (mProcessCrashTimes.getMap().size() > 0) {
13168            boolean printed = false;
13169            long now = SystemClock.uptimeMillis();
13170            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13171            final int NP = pmap.size();
13172            for (int ip=0; ip<NP; ip++) {
13173                String pname = pmap.keyAt(ip);
13174                SparseArray<Long> uids = pmap.valueAt(ip);
13175                final int N = uids.size();
13176                for (int i=0; i<N; i++) {
13177                    int puid = uids.keyAt(i);
13178                    ProcessRecord r = mProcessNames.get(pname, puid);
13179                    if (dumpPackage != null && (r == null
13180                            || !r.pkgList.containsKey(dumpPackage))) {
13181                        continue;
13182                    }
13183                    if (!printed) {
13184                        if (needSep) pw.println();
13185                        needSep = true;
13186                        pw.println("  Time since processes crashed:");
13187                        printed = true;
13188                        printedAnything = true;
13189                    }
13190                    pw.print("    Process "); pw.print(pname);
13191                            pw.print(" uid "); pw.print(puid);
13192                            pw.print(": last crashed ");
13193                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13194                            pw.println(" ago");
13195                }
13196            }
13197        }
13198
13199        if (mBadProcesses.getMap().size() > 0) {
13200            boolean printed = false;
13201            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13202            final int NP = pmap.size();
13203            for (int ip=0; ip<NP; ip++) {
13204                String pname = pmap.keyAt(ip);
13205                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13206                final int N = uids.size();
13207                for (int i=0; i<N; i++) {
13208                    int puid = uids.keyAt(i);
13209                    ProcessRecord r = mProcessNames.get(pname, puid);
13210                    if (dumpPackage != null && (r == null
13211                            || !r.pkgList.containsKey(dumpPackage))) {
13212                        continue;
13213                    }
13214                    if (!printed) {
13215                        if (needSep) pw.println();
13216                        needSep = true;
13217                        pw.println("  Bad processes:");
13218                        printedAnything = true;
13219                    }
13220                    BadProcessInfo info = uids.valueAt(i);
13221                    pw.print("    Bad process "); pw.print(pname);
13222                            pw.print(" uid "); pw.print(puid);
13223                            pw.print(": crashed at time "); pw.println(info.time);
13224                    if (info.shortMsg != null) {
13225                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13226                    }
13227                    if (info.longMsg != null) {
13228                        pw.print("      Long msg: "); pw.println(info.longMsg);
13229                    }
13230                    if (info.stack != null) {
13231                        pw.println("      Stack:");
13232                        int lastPos = 0;
13233                        for (int pos=0; pos<info.stack.length(); pos++) {
13234                            if (info.stack.charAt(pos) == '\n') {
13235                                pw.print("        ");
13236                                pw.write(info.stack, lastPos, pos-lastPos);
13237                                pw.println();
13238                                lastPos = pos+1;
13239                            }
13240                        }
13241                        if (lastPos < info.stack.length()) {
13242                            pw.print("        ");
13243                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13244                            pw.println();
13245                        }
13246                    }
13247                }
13248            }
13249        }
13250
13251        if (dumpPackage == null) {
13252            pw.println();
13253            needSep = false;
13254            pw.println("  mStartedUsers:");
13255            for (int i=0; i<mStartedUsers.size(); i++) {
13256                UserStartedState uss = mStartedUsers.valueAt(i);
13257                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13258                        pw.print(": "); uss.dump("", pw);
13259            }
13260            pw.print("  mStartedUserArray: [");
13261            for (int i=0; i<mStartedUserArray.length; i++) {
13262                if (i > 0) pw.print(", ");
13263                pw.print(mStartedUserArray[i]);
13264            }
13265            pw.println("]");
13266            pw.print("  mUserLru: [");
13267            for (int i=0; i<mUserLru.size(); i++) {
13268                if (i > 0) pw.print(", ");
13269                pw.print(mUserLru.get(i));
13270            }
13271            pw.println("]");
13272            if (dumpAll) {
13273                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13274            }
13275            synchronized (mUserProfileGroupIdsSelfLocked) {
13276                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13277                    pw.println("  mUserProfileGroupIds:");
13278                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13279                        pw.print("    User #");
13280                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13281                        pw.print(" -> profile #");
13282                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13283                    }
13284                }
13285            }
13286        }
13287        if (mHomeProcess != null && (dumpPackage == null
13288                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13289            if (needSep) {
13290                pw.println();
13291                needSep = false;
13292            }
13293            pw.println("  mHomeProcess: " + mHomeProcess);
13294        }
13295        if (mPreviousProcess != null && (dumpPackage == null
13296                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13297            if (needSep) {
13298                pw.println();
13299                needSep = false;
13300            }
13301            pw.println("  mPreviousProcess: " + mPreviousProcess);
13302        }
13303        if (dumpAll) {
13304            StringBuilder sb = new StringBuilder(128);
13305            sb.append("  mPreviousProcessVisibleTime: ");
13306            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13307            pw.println(sb);
13308        }
13309        if (mHeavyWeightProcess != null && (dumpPackage == null
13310                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13311            if (needSep) {
13312                pw.println();
13313                needSep = false;
13314            }
13315            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13316        }
13317        if (dumpPackage == null) {
13318            pw.println("  mConfiguration: " + mConfiguration);
13319        }
13320        if (dumpAll) {
13321            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13322            if (mCompatModePackages.getPackages().size() > 0) {
13323                boolean printed = false;
13324                for (Map.Entry<String, Integer> entry
13325                        : mCompatModePackages.getPackages().entrySet()) {
13326                    String pkg = entry.getKey();
13327                    int mode = entry.getValue();
13328                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13329                        continue;
13330                    }
13331                    if (!printed) {
13332                        pw.println("  mScreenCompatPackages:");
13333                        printed = true;
13334                    }
13335                    pw.print("    "); pw.print(pkg); pw.print(": ");
13336                            pw.print(mode); pw.println();
13337                }
13338            }
13339        }
13340        if (dumpPackage == null) {
13341            pw.println("  mWakefulness="
13342                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13343            pw.println("  mSleepTokens=" + mSleepTokens);
13344            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13345                    + lockScreenShownToString());
13346            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13347            if (mRunningVoice != null) {
13348                pw.println("  mRunningVoice=" + mRunningVoice);
13349                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13350            }
13351        }
13352        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13353                || mOrigWaitForDebugger) {
13354            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13355                    || dumpPackage.equals(mOrigDebugApp)) {
13356                if (needSep) {
13357                    pw.println();
13358                    needSep = false;
13359                }
13360                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13361                        + " mDebugTransient=" + mDebugTransient
13362                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13363            }
13364        }
13365        if (mMemWatchProcesses.getMap().size() > 0) {
13366            pw.println("  Mem watch processes:");
13367            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13368                    = mMemWatchProcesses.getMap();
13369            for (int i=0; i<procs.size(); i++) {
13370                final String proc = procs.keyAt(i);
13371                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13372                for (int j=0; j<uids.size(); j++) {
13373                    if (needSep) {
13374                        pw.println();
13375                        needSep = false;
13376                    }
13377                    StringBuilder sb = new StringBuilder();
13378                    sb.append("    ").append(proc).append('/');
13379                    UserHandle.formatUid(sb, uids.keyAt(j));
13380                    Pair<Long, String> val = uids.valueAt(j);
13381                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13382                    if (val.second != null) {
13383                        sb.append(", report to ").append(val.second);
13384                    }
13385                    pw.println(sb.toString());
13386                }
13387            }
13388            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13389            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13390            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13391                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13392        }
13393        if (mOpenGlTraceApp != null) {
13394            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13395                if (needSep) {
13396                    pw.println();
13397                    needSep = false;
13398                }
13399                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13400            }
13401        }
13402        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13403                || mProfileFd != null) {
13404            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13405                if (needSep) {
13406                    pw.println();
13407                    needSep = false;
13408                }
13409                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13410                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13411                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13412                        + mAutoStopProfiler);
13413                pw.println("  mProfileType=" + mProfileType);
13414            }
13415        }
13416        if (dumpPackage == null) {
13417            if (mAlwaysFinishActivities || mController != null) {
13418                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13419                        + " mController=" + mController);
13420            }
13421            if (dumpAll) {
13422                pw.println("  Total persistent processes: " + numPers);
13423                pw.println("  mProcessesReady=" + mProcessesReady
13424                        + " mSystemReady=" + mSystemReady
13425                        + " mBooted=" + mBooted
13426                        + " mFactoryTest=" + mFactoryTest);
13427                pw.println("  mBooting=" + mBooting
13428                        + " mCallFinishBooting=" + mCallFinishBooting
13429                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13430                pw.print("  mLastPowerCheckRealtime=");
13431                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13432                        pw.println("");
13433                pw.print("  mLastPowerCheckUptime=");
13434                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13435                        pw.println("");
13436                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13437                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13438                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13439                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13440                        + " (" + mLruProcesses.size() + " total)"
13441                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13442                        + " mNumServiceProcs=" + mNumServiceProcs
13443                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13444                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13445                        + " mLastMemoryLevel" + mLastMemoryLevel
13446                        + " mLastNumProcesses" + mLastNumProcesses);
13447                long now = SystemClock.uptimeMillis();
13448                pw.print("  mLastIdleTime=");
13449                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13450                        pw.print(" mLowRamSinceLastIdle=");
13451                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13452                        pw.println();
13453            }
13454        }
13455
13456        if (!printedAnything) {
13457            pw.println("  (nothing)");
13458        }
13459    }
13460
13461    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13462            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13463        if (mProcessesToGc.size() > 0) {
13464            boolean printed = false;
13465            long now = SystemClock.uptimeMillis();
13466            for (int i=0; i<mProcessesToGc.size(); i++) {
13467                ProcessRecord proc = mProcessesToGc.get(i);
13468                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13469                    continue;
13470                }
13471                if (!printed) {
13472                    if (needSep) pw.println();
13473                    needSep = true;
13474                    pw.println("  Processes that are waiting to GC:");
13475                    printed = true;
13476                }
13477                pw.print("    Process "); pw.println(proc);
13478                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13479                        pw.print(", last gced=");
13480                        pw.print(now-proc.lastRequestedGc);
13481                        pw.print(" ms ago, last lowMem=");
13482                        pw.print(now-proc.lastLowMemory);
13483                        pw.println(" ms ago");
13484
13485            }
13486        }
13487        return needSep;
13488    }
13489
13490    void printOomLevel(PrintWriter pw, String name, int adj) {
13491        pw.print("    ");
13492        if (adj >= 0) {
13493            pw.print(' ');
13494            if (adj < 10) pw.print(' ');
13495        } else {
13496            if (adj > -10) pw.print(' ');
13497        }
13498        pw.print(adj);
13499        pw.print(": ");
13500        pw.print(name);
13501        pw.print(" (");
13502        pw.print(mProcessList.getMemLevel(adj)/1024);
13503        pw.println(" kB)");
13504    }
13505
13506    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13507            int opti, boolean dumpAll) {
13508        boolean needSep = false;
13509
13510        if (mLruProcesses.size() > 0) {
13511            if (needSep) pw.println();
13512            needSep = true;
13513            pw.println("  OOM levels:");
13514            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13515            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13516            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13517            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13518            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13519            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13520            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13521            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13522            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13523            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13524            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13525            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13526            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13527            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13528
13529            if (needSep) pw.println();
13530            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13531                    pw.print(" total, non-act at ");
13532                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13533                    pw.print(", non-svc at ");
13534                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13535                    pw.println("):");
13536            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13537            needSep = true;
13538        }
13539
13540        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13541
13542        pw.println();
13543        pw.println("  mHomeProcess: " + mHomeProcess);
13544        pw.println("  mPreviousProcess: " + mPreviousProcess);
13545        if (mHeavyWeightProcess != null) {
13546            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13547        }
13548
13549        return true;
13550    }
13551
13552    /**
13553     * There are three ways to call this:
13554     *  - no provider specified: dump all the providers
13555     *  - a flattened component name that matched an existing provider was specified as the
13556     *    first arg: dump that one provider
13557     *  - the first arg isn't the flattened component name of an existing provider:
13558     *    dump all providers whose component contains the first arg as a substring
13559     */
13560    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13561            int opti, boolean dumpAll) {
13562        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13563    }
13564
13565    static class ItemMatcher {
13566        ArrayList<ComponentName> components;
13567        ArrayList<String> strings;
13568        ArrayList<Integer> objects;
13569        boolean all;
13570
13571        ItemMatcher() {
13572            all = true;
13573        }
13574
13575        void build(String name) {
13576            ComponentName componentName = ComponentName.unflattenFromString(name);
13577            if (componentName != null) {
13578                if (components == null) {
13579                    components = new ArrayList<ComponentName>();
13580                }
13581                components.add(componentName);
13582                all = false;
13583            } else {
13584                int objectId = 0;
13585                // Not a '/' separated full component name; maybe an object ID?
13586                try {
13587                    objectId = Integer.parseInt(name, 16);
13588                    if (objects == null) {
13589                        objects = new ArrayList<Integer>();
13590                    }
13591                    objects.add(objectId);
13592                    all = false;
13593                } catch (RuntimeException e) {
13594                    // Not an integer; just do string match.
13595                    if (strings == null) {
13596                        strings = new ArrayList<String>();
13597                    }
13598                    strings.add(name);
13599                    all = false;
13600                }
13601            }
13602        }
13603
13604        int build(String[] args, int opti) {
13605            for (; opti<args.length; opti++) {
13606                String name = args[opti];
13607                if ("--".equals(name)) {
13608                    return opti+1;
13609                }
13610                build(name);
13611            }
13612            return opti;
13613        }
13614
13615        boolean match(Object object, ComponentName comp) {
13616            if (all) {
13617                return true;
13618            }
13619            if (components != null) {
13620                for (int i=0; i<components.size(); i++) {
13621                    if (components.get(i).equals(comp)) {
13622                        return true;
13623                    }
13624                }
13625            }
13626            if (objects != null) {
13627                for (int i=0; i<objects.size(); i++) {
13628                    if (System.identityHashCode(object) == objects.get(i)) {
13629                        return true;
13630                    }
13631                }
13632            }
13633            if (strings != null) {
13634                String flat = comp.flattenToString();
13635                for (int i=0; i<strings.size(); i++) {
13636                    if (flat.contains(strings.get(i))) {
13637                        return true;
13638                    }
13639                }
13640            }
13641            return false;
13642        }
13643    }
13644
13645    /**
13646     * There are three things that cmd can be:
13647     *  - a flattened component name that matches an existing activity
13648     *  - the cmd arg isn't the flattened component name of an existing activity:
13649     *    dump all activity whose component contains the cmd as a substring
13650     *  - A hex number of the ActivityRecord object instance.
13651     */
13652    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13653            int opti, boolean dumpAll) {
13654        ArrayList<ActivityRecord> activities;
13655
13656        synchronized (this) {
13657            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13658        }
13659
13660        if (activities.size() <= 0) {
13661            return false;
13662        }
13663
13664        String[] newArgs = new String[args.length - opti];
13665        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13666
13667        TaskRecord lastTask = null;
13668        boolean needSep = false;
13669        for (int i=activities.size()-1; i>=0; i--) {
13670            ActivityRecord r = activities.get(i);
13671            if (needSep) {
13672                pw.println();
13673            }
13674            needSep = true;
13675            synchronized (this) {
13676                if (lastTask != r.task) {
13677                    lastTask = r.task;
13678                    pw.print("TASK "); pw.print(lastTask.affinity);
13679                            pw.print(" id="); pw.println(lastTask.taskId);
13680                    if (dumpAll) {
13681                        lastTask.dump(pw, "  ");
13682                    }
13683                }
13684            }
13685            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13686        }
13687        return true;
13688    }
13689
13690    /**
13691     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13692     * there is a thread associated with the activity.
13693     */
13694    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13695            final ActivityRecord r, String[] args, boolean dumpAll) {
13696        String innerPrefix = prefix + "  ";
13697        synchronized (this) {
13698            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13699                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13700                    pw.print(" pid=");
13701                    if (r.app != null) pw.println(r.app.pid);
13702                    else pw.println("(not running)");
13703            if (dumpAll) {
13704                r.dump(pw, innerPrefix);
13705            }
13706        }
13707        if (r.app != null && r.app.thread != null) {
13708            // flush anything that is already in the PrintWriter since the thread is going
13709            // to write to the file descriptor directly
13710            pw.flush();
13711            try {
13712                TransferPipe tp = new TransferPipe();
13713                try {
13714                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13715                            r.appToken, innerPrefix, args);
13716                    tp.go(fd);
13717                } finally {
13718                    tp.kill();
13719                }
13720            } catch (IOException e) {
13721                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13722            } catch (RemoteException e) {
13723                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13724            }
13725        }
13726    }
13727
13728    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13729            int opti, boolean dumpAll, String dumpPackage) {
13730        boolean needSep = false;
13731        boolean onlyHistory = false;
13732        boolean printedAnything = false;
13733
13734        if ("history".equals(dumpPackage)) {
13735            if (opti < args.length && "-s".equals(args[opti])) {
13736                dumpAll = false;
13737            }
13738            onlyHistory = true;
13739            dumpPackage = null;
13740        }
13741
13742        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13743        if (!onlyHistory && dumpAll) {
13744            if (mRegisteredReceivers.size() > 0) {
13745                boolean printed = false;
13746                Iterator it = mRegisteredReceivers.values().iterator();
13747                while (it.hasNext()) {
13748                    ReceiverList r = (ReceiverList)it.next();
13749                    if (dumpPackage != null && (r.app == null ||
13750                            !dumpPackage.equals(r.app.info.packageName))) {
13751                        continue;
13752                    }
13753                    if (!printed) {
13754                        pw.println("  Registered Receivers:");
13755                        needSep = true;
13756                        printed = true;
13757                        printedAnything = true;
13758                    }
13759                    pw.print("  * "); pw.println(r);
13760                    r.dump(pw, "    ");
13761                }
13762            }
13763
13764            if (mReceiverResolver.dump(pw, needSep ?
13765                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13766                    "    ", dumpPackage, false, false)) {
13767                needSep = true;
13768                printedAnything = true;
13769            }
13770        }
13771
13772        for (BroadcastQueue q : mBroadcastQueues) {
13773            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13774            printedAnything |= needSep;
13775        }
13776
13777        needSep = true;
13778
13779        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13780            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13781                if (needSep) {
13782                    pw.println();
13783                }
13784                needSep = true;
13785                printedAnything = true;
13786                pw.print("  Sticky broadcasts for user ");
13787                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13788                StringBuilder sb = new StringBuilder(128);
13789                for (Map.Entry<String, ArrayList<Intent>> ent
13790                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13791                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13792                    if (dumpAll) {
13793                        pw.println(":");
13794                        ArrayList<Intent> intents = ent.getValue();
13795                        final int N = intents.size();
13796                        for (int i=0; i<N; i++) {
13797                            sb.setLength(0);
13798                            sb.append("    Intent: ");
13799                            intents.get(i).toShortString(sb, false, true, false, false);
13800                            pw.println(sb.toString());
13801                            Bundle bundle = intents.get(i).getExtras();
13802                            if (bundle != null) {
13803                                pw.print("      ");
13804                                pw.println(bundle.toString());
13805                            }
13806                        }
13807                    } else {
13808                        pw.println("");
13809                    }
13810                }
13811            }
13812        }
13813
13814        if (!onlyHistory && dumpAll) {
13815            pw.println();
13816            for (BroadcastQueue queue : mBroadcastQueues) {
13817                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13818                        + queue.mBroadcastsScheduled);
13819            }
13820            pw.println("  mHandler:");
13821            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13822            needSep = true;
13823            printedAnything = true;
13824        }
13825
13826        if (!printedAnything) {
13827            pw.println("  (nothing)");
13828        }
13829    }
13830
13831    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13832            int opti, boolean dumpAll, String dumpPackage) {
13833        boolean needSep;
13834        boolean printedAnything = false;
13835
13836        ItemMatcher matcher = new ItemMatcher();
13837        matcher.build(args, opti);
13838
13839        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13840
13841        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13842        printedAnything |= needSep;
13843
13844        if (mLaunchingProviders.size() > 0) {
13845            boolean printed = false;
13846            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13847                ContentProviderRecord r = mLaunchingProviders.get(i);
13848                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13849                    continue;
13850                }
13851                if (!printed) {
13852                    if (needSep) pw.println();
13853                    needSep = true;
13854                    pw.println("  Launching content providers:");
13855                    printed = true;
13856                    printedAnything = true;
13857                }
13858                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13859                        pw.println(r);
13860            }
13861        }
13862
13863        if (mGrantedUriPermissions.size() > 0) {
13864            boolean printed = false;
13865            int dumpUid = -2;
13866            if (dumpPackage != null) {
13867                try {
13868                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13869                } catch (NameNotFoundException e) {
13870                    dumpUid = -1;
13871                }
13872            }
13873            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13874                int uid = mGrantedUriPermissions.keyAt(i);
13875                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13876                    continue;
13877                }
13878                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13879                if (!printed) {
13880                    if (needSep) pw.println();
13881                    needSep = true;
13882                    pw.println("  Granted Uri Permissions:");
13883                    printed = true;
13884                    printedAnything = true;
13885                }
13886                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13887                for (UriPermission perm : perms.values()) {
13888                    pw.print("    "); pw.println(perm);
13889                    if (dumpAll) {
13890                        perm.dump(pw, "      ");
13891                    }
13892                }
13893            }
13894        }
13895
13896        if (!printedAnything) {
13897            pw.println("  (nothing)");
13898        }
13899    }
13900
13901    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13902            int opti, boolean dumpAll, String dumpPackage) {
13903        boolean printed = false;
13904
13905        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13906
13907        if (mIntentSenderRecords.size() > 0) {
13908            Iterator<WeakReference<PendingIntentRecord>> it
13909                    = mIntentSenderRecords.values().iterator();
13910            while (it.hasNext()) {
13911                WeakReference<PendingIntentRecord> ref = it.next();
13912                PendingIntentRecord rec = ref != null ? ref.get(): null;
13913                if (dumpPackage != null && (rec == null
13914                        || !dumpPackage.equals(rec.key.packageName))) {
13915                    continue;
13916                }
13917                printed = true;
13918                if (rec != null) {
13919                    pw.print("  * "); pw.println(rec);
13920                    if (dumpAll) {
13921                        rec.dump(pw, "    ");
13922                    }
13923                } else {
13924                    pw.print("  * "); pw.println(ref);
13925                }
13926            }
13927        }
13928
13929        if (!printed) {
13930            pw.println("  (nothing)");
13931        }
13932    }
13933
13934    private static final int dumpProcessList(PrintWriter pw,
13935            ActivityManagerService service, List list,
13936            String prefix, String normalLabel, String persistentLabel,
13937            String dumpPackage) {
13938        int numPers = 0;
13939        final int N = list.size()-1;
13940        for (int i=N; i>=0; i--) {
13941            ProcessRecord r = (ProcessRecord)list.get(i);
13942            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13943                continue;
13944            }
13945            pw.println(String.format("%s%s #%2d: %s",
13946                    prefix, (r.persistent ? persistentLabel : normalLabel),
13947                    i, r.toString()));
13948            if (r.persistent) {
13949                numPers++;
13950            }
13951        }
13952        return numPers;
13953    }
13954
13955    private static final boolean dumpProcessOomList(PrintWriter pw,
13956            ActivityManagerService service, List<ProcessRecord> origList,
13957            String prefix, String normalLabel, String persistentLabel,
13958            boolean inclDetails, String dumpPackage) {
13959
13960        ArrayList<Pair<ProcessRecord, Integer>> list
13961                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13962        for (int i=0; i<origList.size(); i++) {
13963            ProcessRecord r = origList.get(i);
13964            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13965                continue;
13966            }
13967            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13968        }
13969
13970        if (list.size() <= 0) {
13971            return false;
13972        }
13973
13974        Comparator<Pair<ProcessRecord, Integer>> comparator
13975                = new Comparator<Pair<ProcessRecord, Integer>>() {
13976            @Override
13977            public int compare(Pair<ProcessRecord, Integer> object1,
13978                    Pair<ProcessRecord, Integer> object2) {
13979                if (object1.first.setAdj != object2.first.setAdj) {
13980                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13981                }
13982                if (object1.second.intValue() != object2.second.intValue()) {
13983                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13984                }
13985                return 0;
13986            }
13987        };
13988
13989        Collections.sort(list, comparator);
13990
13991        final long curRealtime = SystemClock.elapsedRealtime();
13992        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13993        final long curUptime = SystemClock.uptimeMillis();
13994        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13995
13996        for (int i=list.size()-1; i>=0; i--) {
13997            ProcessRecord r = list.get(i).first;
13998            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13999            char schedGroup;
14000            switch (r.setSchedGroup) {
14001                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14002                    schedGroup = 'B';
14003                    break;
14004                case Process.THREAD_GROUP_DEFAULT:
14005                    schedGroup = 'F';
14006                    break;
14007                default:
14008                    schedGroup = '?';
14009                    break;
14010            }
14011            char foreground;
14012            if (r.foregroundActivities) {
14013                foreground = 'A';
14014            } else if (r.foregroundServices) {
14015                foreground = 'S';
14016            } else {
14017                foreground = ' ';
14018            }
14019            String procState = ProcessList.makeProcStateString(r.curProcState);
14020            pw.print(prefix);
14021            pw.print(r.persistent ? persistentLabel : normalLabel);
14022            pw.print(" #");
14023            int num = (origList.size()-1)-list.get(i).second;
14024            if (num < 10) pw.print(' ');
14025            pw.print(num);
14026            pw.print(": ");
14027            pw.print(oomAdj);
14028            pw.print(' ');
14029            pw.print(schedGroup);
14030            pw.print('/');
14031            pw.print(foreground);
14032            pw.print('/');
14033            pw.print(procState);
14034            pw.print(" trm:");
14035            if (r.trimMemoryLevel < 10) pw.print(' ');
14036            pw.print(r.trimMemoryLevel);
14037            pw.print(' ');
14038            pw.print(r.toShortString());
14039            pw.print(" (");
14040            pw.print(r.adjType);
14041            pw.println(')');
14042            if (r.adjSource != null || r.adjTarget != null) {
14043                pw.print(prefix);
14044                pw.print("    ");
14045                if (r.adjTarget instanceof ComponentName) {
14046                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14047                } else if (r.adjTarget != null) {
14048                    pw.print(r.adjTarget.toString());
14049                } else {
14050                    pw.print("{null}");
14051                }
14052                pw.print("<=");
14053                if (r.adjSource instanceof ProcessRecord) {
14054                    pw.print("Proc{");
14055                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14056                    pw.println("}");
14057                } else if (r.adjSource != null) {
14058                    pw.println(r.adjSource.toString());
14059                } else {
14060                    pw.println("{null}");
14061                }
14062            }
14063            if (inclDetails) {
14064                pw.print(prefix);
14065                pw.print("    ");
14066                pw.print("oom: max="); pw.print(r.maxAdj);
14067                pw.print(" curRaw="); pw.print(r.curRawAdj);
14068                pw.print(" setRaw="); pw.print(r.setRawAdj);
14069                pw.print(" cur="); pw.print(r.curAdj);
14070                pw.print(" set="); pw.println(r.setAdj);
14071                pw.print(prefix);
14072                pw.print("    ");
14073                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14074                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14075                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14076                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14077                pw.println();
14078                pw.print(prefix);
14079                pw.print("    ");
14080                pw.print("cached="); pw.print(r.cached);
14081                pw.print(" empty="); pw.print(r.empty);
14082                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14083
14084                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14085                    if (r.lastWakeTime != 0) {
14086                        long wtime;
14087                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14088                        synchronized (stats) {
14089                            wtime = stats.getProcessWakeTime(r.info.uid,
14090                                    r.pid, curRealtime);
14091                        }
14092                        long timeUsed = wtime - r.lastWakeTime;
14093                        pw.print(prefix);
14094                        pw.print("    ");
14095                        pw.print("keep awake over ");
14096                        TimeUtils.formatDuration(realtimeSince, pw);
14097                        pw.print(" used ");
14098                        TimeUtils.formatDuration(timeUsed, pw);
14099                        pw.print(" (");
14100                        pw.print((timeUsed*100)/realtimeSince);
14101                        pw.println("%)");
14102                    }
14103                    if (r.lastCpuTime != 0) {
14104                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14105                        pw.print(prefix);
14106                        pw.print("    ");
14107                        pw.print("run cpu over ");
14108                        TimeUtils.formatDuration(uptimeSince, pw);
14109                        pw.print(" used ");
14110                        TimeUtils.formatDuration(timeUsed, pw);
14111                        pw.print(" (");
14112                        pw.print((timeUsed*100)/uptimeSince);
14113                        pw.println("%)");
14114                    }
14115                }
14116            }
14117        }
14118        return true;
14119    }
14120
14121    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14122            String[] args) {
14123        ArrayList<ProcessRecord> procs;
14124        synchronized (this) {
14125            if (args != null && args.length > start
14126                    && args[start].charAt(0) != '-') {
14127                procs = new ArrayList<ProcessRecord>();
14128                int pid = -1;
14129                try {
14130                    pid = Integer.parseInt(args[start]);
14131                } catch (NumberFormatException e) {
14132                }
14133                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14134                    ProcessRecord proc = mLruProcesses.get(i);
14135                    if (proc.pid == pid) {
14136                        procs.add(proc);
14137                    } else if (allPkgs && proc.pkgList != null
14138                            && proc.pkgList.containsKey(args[start])) {
14139                        procs.add(proc);
14140                    } else if (proc.processName.equals(args[start])) {
14141                        procs.add(proc);
14142                    }
14143                }
14144                if (procs.size() <= 0) {
14145                    return null;
14146                }
14147            } else {
14148                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14149            }
14150        }
14151        return procs;
14152    }
14153
14154    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14155            PrintWriter pw, String[] args) {
14156        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14157        if (procs == null) {
14158            pw.println("No process found for: " + args[0]);
14159            return;
14160        }
14161
14162        long uptime = SystemClock.uptimeMillis();
14163        long realtime = SystemClock.elapsedRealtime();
14164        pw.println("Applications Graphics Acceleration Info:");
14165        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14166
14167        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14168            ProcessRecord r = procs.get(i);
14169            if (r.thread != null) {
14170                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14171                pw.flush();
14172                try {
14173                    TransferPipe tp = new TransferPipe();
14174                    try {
14175                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14176                        tp.go(fd);
14177                    } finally {
14178                        tp.kill();
14179                    }
14180                } catch (IOException e) {
14181                    pw.println("Failure while dumping the app: " + r);
14182                    pw.flush();
14183                } catch (RemoteException e) {
14184                    pw.println("Got a RemoteException while dumping the app " + r);
14185                    pw.flush();
14186                }
14187            }
14188        }
14189    }
14190
14191    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14192        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14193        if (procs == null) {
14194            pw.println("No process found for: " + args[0]);
14195            return;
14196        }
14197
14198        pw.println("Applications Database Info:");
14199
14200        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14201            ProcessRecord r = procs.get(i);
14202            if (r.thread != null) {
14203                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14204                pw.flush();
14205                try {
14206                    TransferPipe tp = new TransferPipe();
14207                    try {
14208                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14209                        tp.go(fd);
14210                    } finally {
14211                        tp.kill();
14212                    }
14213                } catch (IOException e) {
14214                    pw.println("Failure while dumping the app: " + r);
14215                    pw.flush();
14216                } catch (RemoteException e) {
14217                    pw.println("Got a RemoteException while dumping the app " + r);
14218                    pw.flush();
14219                }
14220            }
14221        }
14222    }
14223
14224    final static class MemItem {
14225        final boolean isProc;
14226        final String label;
14227        final String shortLabel;
14228        final long pss;
14229        final int id;
14230        final boolean hasActivities;
14231        ArrayList<MemItem> subitems;
14232
14233        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14234                boolean _hasActivities) {
14235            isProc = true;
14236            label = _label;
14237            shortLabel = _shortLabel;
14238            pss = _pss;
14239            id = _id;
14240            hasActivities = _hasActivities;
14241        }
14242
14243        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14244            isProc = false;
14245            label = _label;
14246            shortLabel = _shortLabel;
14247            pss = _pss;
14248            id = _id;
14249            hasActivities = false;
14250        }
14251    }
14252
14253    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14254            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14255        if (sort && !isCompact) {
14256            Collections.sort(items, new Comparator<MemItem>() {
14257                @Override
14258                public int compare(MemItem lhs, MemItem rhs) {
14259                    if (lhs.pss < rhs.pss) {
14260                        return 1;
14261                    } else if (lhs.pss > rhs.pss) {
14262                        return -1;
14263                    }
14264                    return 0;
14265                }
14266            });
14267        }
14268
14269        for (int i=0; i<items.size(); i++) {
14270            MemItem mi = items.get(i);
14271            if (!isCompact) {
14272                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14273            } else if (mi.isProc) {
14274                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14275                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14276                pw.println(mi.hasActivities ? ",a" : ",e");
14277            } else {
14278                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14279                pw.println(mi.pss);
14280            }
14281            if (mi.subitems != null) {
14282                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14283                        true, isCompact);
14284            }
14285        }
14286    }
14287
14288    // These are in KB.
14289    static final long[] DUMP_MEM_BUCKETS = new long[] {
14290        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14291        120*1024, 160*1024, 200*1024,
14292        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14293        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14294    };
14295
14296    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14297            boolean stackLike) {
14298        int start = label.lastIndexOf('.');
14299        if (start >= 0) start++;
14300        else start = 0;
14301        int end = label.length();
14302        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14303            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14304                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14305                out.append(bucket);
14306                out.append(stackLike ? "MB." : "MB ");
14307                out.append(label, start, end);
14308                return;
14309            }
14310        }
14311        out.append(memKB/1024);
14312        out.append(stackLike ? "MB." : "MB ");
14313        out.append(label, start, end);
14314    }
14315
14316    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14317            ProcessList.NATIVE_ADJ,
14318            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14319            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14320            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14321            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14322            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14323            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14324    };
14325    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14326            "Native",
14327            "System", "Persistent", "Persistent Service", "Foreground",
14328            "Visible", "Perceptible",
14329            "Heavy Weight", "Backup",
14330            "A Services", "Home",
14331            "Previous", "B Services", "Cached"
14332    };
14333    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14334            "native",
14335            "sys", "pers", "persvc", "fore",
14336            "vis", "percept",
14337            "heavy", "backup",
14338            "servicea", "home",
14339            "prev", "serviceb", "cached"
14340    };
14341
14342    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14343            long realtime, boolean isCheckinRequest, boolean isCompact) {
14344        if (isCheckinRequest || isCompact) {
14345            // short checkin version
14346            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14347        } else {
14348            pw.println("Applications Memory Usage (kB):");
14349            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14350        }
14351    }
14352
14353    private static final int KSM_SHARED = 0;
14354    private static final int KSM_SHARING = 1;
14355    private static final int KSM_UNSHARED = 2;
14356    private static final int KSM_VOLATILE = 3;
14357
14358    private final long[] getKsmInfo() {
14359        long[] longOut = new long[4];
14360        final int[] SINGLE_LONG_FORMAT = new int[] {
14361            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14362        };
14363        long[] longTmp = new long[1];
14364        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14365                SINGLE_LONG_FORMAT, null, longTmp, null);
14366        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14367        longTmp[0] = 0;
14368        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14369                SINGLE_LONG_FORMAT, null, longTmp, null);
14370        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14371        longTmp[0] = 0;
14372        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14373                SINGLE_LONG_FORMAT, null, longTmp, null);
14374        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14375        longTmp[0] = 0;
14376        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14377                SINGLE_LONG_FORMAT, null, longTmp, null);
14378        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14379        return longOut;
14380    }
14381
14382    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14383            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14384        boolean dumpDetails = false;
14385        boolean dumpFullDetails = false;
14386        boolean dumpDalvik = false;
14387        boolean dumpSummaryOnly = false;
14388        boolean oomOnly = false;
14389        boolean isCompact = false;
14390        boolean localOnly = false;
14391        boolean packages = false;
14392
14393        int opti = 0;
14394        while (opti < args.length) {
14395            String opt = args[opti];
14396            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14397                break;
14398            }
14399            opti++;
14400            if ("-a".equals(opt)) {
14401                dumpDetails = true;
14402                dumpFullDetails = true;
14403                dumpDalvik = true;
14404            } else if ("-d".equals(opt)) {
14405                dumpDalvik = true;
14406            } else if ("-c".equals(opt)) {
14407                isCompact = true;
14408            } else if ("-s".equals(opt)) {
14409                dumpDetails = true;
14410                dumpSummaryOnly = true;
14411            } else if ("--oom".equals(opt)) {
14412                oomOnly = true;
14413            } else if ("--local".equals(opt)) {
14414                localOnly = true;
14415            } else if ("--package".equals(opt)) {
14416                packages = true;
14417            } else if ("-h".equals(opt)) {
14418                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14419                pw.println("  -a: include all available information for each process.");
14420                pw.println("  -d: include dalvik details.");
14421                pw.println("  -c: dump in a compact machine-parseable representation.");
14422                pw.println("  -s: dump only summary of application memory usage.");
14423                pw.println("  --oom: only show processes organized by oom adj.");
14424                pw.println("  --local: only collect details locally, don't call process.");
14425                pw.println("  --package: interpret process arg as package, dumping all");
14426                pw.println("             processes that have loaded that package.");
14427                pw.println("If [process] is specified it can be the name or ");
14428                pw.println("pid of a specific process to dump.");
14429                return;
14430            } else {
14431                pw.println("Unknown argument: " + opt + "; use -h for help");
14432            }
14433        }
14434
14435        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14436        long uptime = SystemClock.uptimeMillis();
14437        long realtime = SystemClock.elapsedRealtime();
14438        final long[] tmpLong = new long[1];
14439
14440        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14441        if (procs == null) {
14442            // No Java processes.  Maybe they want to print a native process.
14443            if (args != null && args.length > opti
14444                    && args[opti].charAt(0) != '-') {
14445                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14446                        = new ArrayList<ProcessCpuTracker.Stats>();
14447                updateCpuStatsNow();
14448                int findPid = -1;
14449                try {
14450                    findPid = Integer.parseInt(args[opti]);
14451                } catch (NumberFormatException e) {
14452                }
14453                synchronized (mProcessCpuTracker) {
14454                    final int N = mProcessCpuTracker.countStats();
14455                    for (int i=0; i<N; i++) {
14456                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14457                        if (st.pid == findPid || (st.baseName != null
14458                                && st.baseName.equals(args[opti]))) {
14459                            nativeProcs.add(st);
14460                        }
14461                    }
14462                }
14463                if (nativeProcs.size() > 0) {
14464                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14465                            isCompact);
14466                    Debug.MemoryInfo mi = null;
14467                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14468                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14469                        final int pid = r.pid;
14470                        if (!isCheckinRequest && dumpDetails) {
14471                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14472                        }
14473                        if (mi == null) {
14474                            mi = new Debug.MemoryInfo();
14475                        }
14476                        if (dumpDetails || (!brief && !oomOnly)) {
14477                            Debug.getMemoryInfo(pid, mi);
14478                        } else {
14479                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14480                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14481                        }
14482                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14483                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14484                        if (isCheckinRequest) {
14485                            pw.println();
14486                        }
14487                    }
14488                    return;
14489                }
14490            }
14491            pw.println("No process found for: " + args[opti]);
14492            return;
14493        }
14494
14495        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14496            dumpDetails = true;
14497        }
14498
14499        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14500
14501        String[] innerArgs = new String[args.length-opti];
14502        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14503
14504        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14505        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14506        long nativePss = 0;
14507        long dalvikPss = 0;
14508        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14509                EmptyArray.LONG;
14510        long otherPss = 0;
14511        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14512
14513        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14514        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14515                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14516
14517        long totalPss = 0;
14518        long cachedPss = 0;
14519
14520        Debug.MemoryInfo mi = null;
14521        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14522            final ProcessRecord r = procs.get(i);
14523            final IApplicationThread thread;
14524            final int pid;
14525            final int oomAdj;
14526            final boolean hasActivities;
14527            synchronized (this) {
14528                thread = r.thread;
14529                pid = r.pid;
14530                oomAdj = r.getSetAdjWithServices();
14531                hasActivities = r.activities.size() > 0;
14532            }
14533            if (thread != null) {
14534                if (!isCheckinRequest && dumpDetails) {
14535                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14536                }
14537                if (mi == null) {
14538                    mi = new Debug.MemoryInfo();
14539                }
14540                if (dumpDetails || (!brief && !oomOnly)) {
14541                    Debug.getMemoryInfo(pid, mi);
14542                } else {
14543                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14544                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14545                }
14546                if (dumpDetails) {
14547                    if (localOnly) {
14548                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14549                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14550                        if (isCheckinRequest) {
14551                            pw.println();
14552                        }
14553                    } else {
14554                        try {
14555                            pw.flush();
14556                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14557                                    dumpDalvik, dumpSummaryOnly, innerArgs);
14558                        } catch (RemoteException e) {
14559                            if (!isCheckinRequest) {
14560                                pw.println("Got RemoteException!");
14561                                pw.flush();
14562                            }
14563                        }
14564                    }
14565                }
14566
14567                final long myTotalPss = mi.getTotalPss();
14568                final long myTotalUss = mi.getTotalUss();
14569
14570                synchronized (this) {
14571                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14572                        // Record this for posterity if the process has been stable.
14573                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14574                    }
14575                }
14576
14577                if (!isCheckinRequest && mi != null) {
14578                    totalPss += myTotalPss;
14579                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14580                            (hasActivities ? " / activities)" : ")"),
14581                            r.processName, myTotalPss, pid, hasActivities);
14582                    procMems.add(pssItem);
14583                    procMemsMap.put(pid, pssItem);
14584
14585                    nativePss += mi.nativePss;
14586                    dalvikPss += mi.dalvikPss;
14587                    for (int j=0; j<dalvikSubitemPss.length; j++) {
14588                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14589                    }
14590                    otherPss += mi.otherPss;
14591                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14592                        long mem = mi.getOtherPss(j);
14593                        miscPss[j] += mem;
14594                        otherPss -= mem;
14595                    }
14596
14597                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14598                        cachedPss += myTotalPss;
14599                    }
14600
14601                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14602                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14603                                || oomIndex == (oomPss.length-1)) {
14604                            oomPss[oomIndex] += myTotalPss;
14605                            if (oomProcs[oomIndex] == null) {
14606                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14607                            }
14608                            oomProcs[oomIndex].add(pssItem);
14609                            break;
14610                        }
14611                    }
14612                }
14613            }
14614        }
14615
14616        long nativeProcTotalPss = 0;
14617
14618        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14619            // If we are showing aggregations, also look for native processes to
14620            // include so that our aggregations are more accurate.
14621            updateCpuStatsNow();
14622            mi = null;
14623            synchronized (mProcessCpuTracker) {
14624                final int N = mProcessCpuTracker.countStats();
14625                for (int i=0; i<N; i++) {
14626                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14627                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14628                        if (mi == null) {
14629                            mi = new Debug.MemoryInfo();
14630                        }
14631                        if (!brief && !oomOnly) {
14632                            Debug.getMemoryInfo(st.pid, mi);
14633                        } else {
14634                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14635                            mi.nativePrivateDirty = (int)tmpLong[0];
14636                        }
14637
14638                        final long myTotalPss = mi.getTotalPss();
14639                        totalPss += myTotalPss;
14640                        nativeProcTotalPss += myTotalPss;
14641
14642                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14643                                st.name, myTotalPss, st.pid, false);
14644                        procMems.add(pssItem);
14645
14646                        nativePss += mi.nativePss;
14647                        dalvikPss += mi.dalvikPss;
14648                        for (int j=0; j<dalvikSubitemPss.length; j++) {
14649                            dalvikSubitemPss[j] += mi.getOtherPss(
14650                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
14651                        }
14652                        otherPss += mi.otherPss;
14653                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14654                            long mem = mi.getOtherPss(j);
14655                            miscPss[j] += mem;
14656                            otherPss -= mem;
14657                        }
14658                        oomPss[0] += myTotalPss;
14659                        if (oomProcs[0] == null) {
14660                            oomProcs[0] = new ArrayList<MemItem>();
14661                        }
14662                        oomProcs[0].add(pssItem);
14663                    }
14664                }
14665            }
14666
14667            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14668
14669            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14670            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14671            if (dalvikSubitemPss.length > 0) {
14672                dalvikItem.subitems = new ArrayList<MemItem>();
14673                for (int j=0; j<dalvikSubitemPss.length; j++) {
14674                    final String name = Debug.MemoryInfo.getOtherLabel(
14675                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
14676                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14677                }
14678            }
14679            catMems.add(dalvikItem);
14680            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14681            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14682                String label = Debug.MemoryInfo.getOtherLabel(j);
14683                catMems.add(new MemItem(label, label, miscPss[j], j));
14684            }
14685
14686            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14687            for (int j=0; j<oomPss.length; j++) {
14688                if (oomPss[j] != 0) {
14689                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14690                            : DUMP_MEM_OOM_LABEL[j];
14691                    MemItem item = new MemItem(label, label, oomPss[j],
14692                            DUMP_MEM_OOM_ADJ[j]);
14693                    item.subitems = oomProcs[j];
14694                    oomMems.add(item);
14695                }
14696            }
14697
14698            if (!brief && !oomOnly && !isCompact) {
14699                pw.println();
14700                pw.println("Total PSS by process:");
14701                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14702                pw.println();
14703            }
14704            if (!isCompact) {
14705                pw.println("Total PSS by OOM adjustment:");
14706            }
14707            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14708            if (!brief && !oomOnly) {
14709                PrintWriter out = categoryPw != null ? categoryPw : pw;
14710                if (!isCompact) {
14711                    out.println();
14712                    out.println("Total PSS by category:");
14713                }
14714                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14715            }
14716            if (!isCompact) {
14717                pw.println();
14718            }
14719            MemInfoReader memInfo = new MemInfoReader();
14720            memInfo.readMemInfo();
14721            if (nativeProcTotalPss > 0) {
14722                synchronized (this) {
14723                    final long cachedKb = memInfo.getCachedSizeKb();
14724                    final long freeKb = memInfo.getFreeSizeKb();
14725                    final long zramKb = memInfo.getZramTotalSizeKb();
14726                    final long kernelKb = memInfo.getKernelUsedSizeKb();
14727                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14728                            kernelKb*1024, nativeProcTotalPss*1024);
14729                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14730                            nativeProcTotalPss);
14731                }
14732            }
14733            if (!brief) {
14734                if (!isCompact) {
14735                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14736                    pw.print(" kB (status ");
14737                    switch (mLastMemoryLevel) {
14738                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14739                            pw.println("normal)");
14740                            break;
14741                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14742                            pw.println("moderate)");
14743                            break;
14744                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14745                            pw.println("low)");
14746                            break;
14747                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14748                            pw.println("critical)");
14749                            break;
14750                        default:
14751                            pw.print(mLastMemoryLevel);
14752                            pw.println(")");
14753                            break;
14754                    }
14755                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14756                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14757                            pw.print(cachedPss); pw.print(" cached pss + ");
14758                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14759                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14760                } else {
14761                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14762                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14763                            + memInfo.getFreeSizeKb()); pw.print(",");
14764                    pw.println(totalPss - cachedPss);
14765                }
14766            }
14767            if (!isCompact) {
14768                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14769                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14770                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14771                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14772                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14773                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14774                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14775            }
14776            if (!brief) {
14777                if (memInfo.getZramTotalSizeKb() != 0) {
14778                    if (!isCompact) {
14779                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14780                                pw.print(" kB physical used for ");
14781                                pw.print(memInfo.getSwapTotalSizeKb()
14782                                        - memInfo.getSwapFreeSizeKb());
14783                                pw.print(" kB in swap (");
14784                                pw.print(memInfo.getSwapTotalSizeKb());
14785                                pw.println(" kB total swap)");
14786                    } else {
14787                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14788                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14789                                pw.println(memInfo.getSwapFreeSizeKb());
14790                    }
14791                }
14792                final long[] ksm = getKsmInfo();
14793                if (!isCompact) {
14794                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14795                            || ksm[KSM_VOLATILE] != 0) {
14796                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14797                                pw.print(" kB saved from shared ");
14798                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14799                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14800                                pw.print(" kB unshared; ");
14801                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14802                    }
14803                    pw.print("   Tuning: ");
14804                    pw.print(ActivityManager.staticGetMemoryClass());
14805                    pw.print(" (large ");
14806                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14807                    pw.print("), oom ");
14808                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14809                    pw.print(" kB");
14810                    pw.print(", restore limit ");
14811                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14812                    pw.print(" kB");
14813                    if (ActivityManager.isLowRamDeviceStatic()) {
14814                        pw.print(" (low-ram)");
14815                    }
14816                    if (ActivityManager.isHighEndGfx()) {
14817                        pw.print(" (high-end-gfx)");
14818                    }
14819                    pw.println();
14820                } else {
14821                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14822                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14823                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14824                    pw.print("tuning,");
14825                    pw.print(ActivityManager.staticGetMemoryClass());
14826                    pw.print(',');
14827                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14828                    pw.print(',');
14829                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14830                    if (ActivityManager.isLowRamDeviceStatic()) {
14831                        pw.print(",low-ram");
14832                    }
14833                    if (ActivityManager.isHighEndGfx()) {
14834                        pw.print(",high-end-gfx");
14835                    }
14836                    pw.println();
14837                }
14838            }
14839        }
14840    }
14841
14842    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14843            long memtrack, String name) {
14844        sb.append("  ");
14845        sb.append(ProcessList.makeOomAdjString(oomAdj));
14846        sb.append(' ');
14847        sb.append(ProcessList.makeProcStateString(procState));
14848        sb.append(' ');
14849        ProcessList.appendRamKb(sb, pss);
14850        sb.append(" kB: ");
14851        sb.append(name);
14852        if (memtrack > 0) {
14853            sb.append(" (");
14854            sb.append(memtrack);
14855            sb.append(" kB memtrack)");
14856        }
14857    }
14858
14859    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14860        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14861        sb.append(" (pid ");
14862        sb.append(mi.pid);
14863        sb.append(") ");
14864        sb.append(mi.adjType);
14865        sb.append('\n');
14866        if (mi.adjReason != null) {
14867            sb.append("                      ");
14868            sb.append(mi.adjReason);
14869            sb.append('\n');
14870        }
14871    }
14872
14873    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14874        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14875        for (int i=0, N=memInfos.size(); i<N; i++) {
14876            ProcessMemInfo mi = memInfos.get(i);
14877            infoMap.put(mi.pid, mi);
14878        }
14879        updateCpuStatsNow();
14880        long[] memtrackTmp = new long[1];
14881        synchronized (mProcessCpuTracker) {
14882            final int N = mProcessCpuTracker.countStats();
14883            for (int i=0; i<N; i++) {
14884                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14885                if (st.vsize > 0) {
14886                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14887                    if (pss > 0) {
14888                        if (infoMap.indexOfKey(st.pid) < 0) {
14889                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14890                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14891                            mi.pss = pss;
14892                            mi.memtrack = memtrackTmp[0];
14893                            memInfos.add(mi);
14894                        }
14895                    }
14896                }
14897            }
14898        }
14899
14900        long totalPss = 0;
14901        long totalMemtrack = 0;
14902        for (int i=0, N=memInfos.size(); i<N; i++) {
14903            ProcessMemInfo mi = memInfos.get(i);
14904            if (mi.pss == 0) {
14905                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14906                mi.memtrack = memtrackTmp[0];
14907            }
14908            totalPss += mi.pss;
14909            totalMemtrack += mi.memtrack;
14910        }
14911        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14912            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14913                if (lhs.oomAdj != rhs.oomAdj) {
14914                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14915                }
14916                if (lhs.pss != rhs.pss) {
14917                    return lhs.pss < rhs.pss ? 1 : -1;
14918                }
14919                return 0;
14920            }
14921        });
14922
14923        StringBuilder tag = new StringBuilder(128);
14924        StringBuilder stack = new StringBuilder(128);
14925        tag.append("Low on memory -- ");
14926        appendMemBucket(tag, totalPss, "total", false);
14927        appendMemBucket(stack, totalPss, "total", true);
14928
14929        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14930        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14931        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14932
14933        boolean firstLine = true;
14934        int lastOomAdj = Integer.MIN_VALUE;
14935        long extraNativeRam = 0;
14936        long extraNativeMemtrack = 0;
14937        long cachedPss = 0;
14938        for (int i=0, N=memInfos.size(); i<N; i++) {
14939            ProcessMemInfo mi = memInfos.get(i);
14940
14941            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14942                cachedPss += mi.pss;
14943            }
14944
14945            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14946                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14947                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14948                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14949                if (lastOomAdj != mi.oomAdj) {
14950                    lastOomAdj = mi.oomAdj;
14951                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14952                        tag.append(" / ");
14953                    }
14954                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14955                        if (firstLine) {
14956                            stack.append(":");
14957                            firstLine = false;
14958                        }
14959                        stack.append("\n\t at ");
14960                    } else {
14961                        stack.append("$");
14962                    }
14963                } else {
14964                    tag.append(" ");
14965                    stack.append("$");
14966                }
14967                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14968                    appendMemBucket(tag, mi.pss, mi.name, false);
14969                }
14970                appendMemBucket(stack, mi.pss, mi.name, true);
14971                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14972                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14973                    stack.append("(");
14974                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14975                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14976                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14977                            stack.append(":");
14978                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14979                        }
14980                    }
14981                    stack.append(")");
14982                }
14983            }
14984
14985            appendMemInfo(fullNativeBuilder, mi);
14986            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14987                // The short form only has native processes that are >= 512K.
14988                if (mi.pss >= 512) {
14989                    appendMemInfo(shortNativeBuilder, mi);
14990                } else {
14991                    extraNativeRam += mi.pss;
14992                    extraNativeMemtrack += mi.memtrack;
14993                }
14994            } else {
14995                // Short form has all other details, but if we have collected RAM
14996                // from smaller native processes let's dump a summary of that.
14997                if (extraNativeRam > 0) {
14998                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14999                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15000                    shortNativeBuilder.append('\n');
15001                    extraNativeRam = 0;
15002                }
15003                appendMemInfo(fullJavaBuilder, mi);
15004            }
15005        }
15006
15007        fullJavaBuilder.append("           ");
15008        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15009        fullJavaBuilder.append(" kB: TOTAL");
15010        if (totalMemtrack > 0) {
15011            fullJavaBuilder.append(" (");
15012            fullJavaBuilder.append(totalMemtrack);
15013            fullJavaBuilder.append(" kB memtrack)");
15014        } else {
15015        }
15016        fullJavaBuilder.append("\n");
15017
15018        MemInfoReader memInfo = new MemInfoReader();
15019        memInfo.readMemInfo();
15020        final long[] infos = memInfo.getRawInfo();
15021
15022        StringBuilder memInfoBuilder = new StringBuilder(1024);
15023        Debug.getMemInfo(infos);
15024        memInfoBuilder.append("  MemInfo: ");
15025        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15026        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15027        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15028        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15029        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15030        memInfoBuilder.append("           ");
15031        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15032        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15033        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15034        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15035        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15036            memInfoBuilder.append("  ZRAM: ");
15037            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15038            memInfoBuilder.append(" kB RAM, ");
15039            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15040            memInfoBuilder.append(" kB swap total, ");
15041            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15042            memInfoBuilder.append(" kB swap free\n");
15043        }
15044        final long[] ksm = getKsmInfo();
15045        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15046                || ksm[KSM_VOLATILE] != 0) {
15047            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15048            memInfoBuilder.append(" kB saved from shared ");
15049            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15050            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15051            memInfoBuilder.append(" kB unshared; ");
15052            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15053        }
15054        memInfoBuilder.append("  Free RAM: ");
15055        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15056                + memInfo.getFreeSizeKb());
15057        memInfoBuilder.append(" kB\n");
15058        memInfoBuilder.append("  Used RAM: ");
15059        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15060        memInfoBuilder.append(" kB\n");
15061        memInfoBuilder.append("  Lost RAM: ");
15062        memInfoBuilder.append(memInfo.getTotalSizeKb()
15063                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15064                - memInfo.getKernelUsedSizeKb());
15065        memInfoBuilder.append(" kB\n");
15066        Slog.i(TAG, "Low on memory:");
15067        Slog.i(TAG, shortNativeBuilder.toString());
15068        Slog.i(TAG, fullJavaBuilder.toString());
15069        Slog.i(TAG, memInfoBuilder.toString());
15070
15071        StringBuilder dropBuilder = new StringBuilder(1024);
15072        /*
15073        StringWriter oomSw = new StringWriter();
15074        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15075        StringWriter catSw = new StringWriter();
15076        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15077        String[] emptyArgs = new String[] { };
15078        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15079        oomPw.flush();
15080        String oomString = oomSw.toString();
15081        */
15082        dropBuilder.append("Low on memory:");
15083        dropBuilder.append(stack);
15084        dropBuilder.append('\n');
15085        dropBuilder.append(fullNativeBuilder);
15086        dropBuilder.append(fullJavaBuilder);
15087        dropBuilder.append('\n');
15088        dropBuilder.append(memInfoBuilder);
15089        dropBuilder.append('\n');
15090        /*
15091        dropBuilder.append(oomString);
15092        dropBuilder.append('\n');
15093        */
15094        StringWriter catSw = new StringWriter();
15095        synchronized (ActivityManagerService.this) {
15096            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15097            String[] emptyArgs = new String[] { };
15098            catPw.println();
15099            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15100            catPw.println();
15101            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15102                    false, false, null);
15103            catPw.println();
15104            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15105            catPw.flush();
15106        }
15107        dropBuilder.append(catSw.toString());
15108        addErrorToDropBox("lowmem", null, "system_server", null,
15109                null, tag.toString(), dropBuilder.toString(), null, null);
15110        //Slog.i(TAG, "Sent to dropbox:");
15111        //Slog.i(TAG, dropBuilder.toString());
15112        synchronized (ActivityManagerService.this) {
15113            long now = SystemClock.uptimeMillis();
15114            if (mLastMemUsageReportTime < now) {
15115                mLastMemUsageReportTime = now;
15116            }
15117        }
15118    }
15119
15120    /**
15121     * Searches array of arguments for the specified string
15122     * @param args array of argument strings
15123     * @param value value to search for
15124     * @return true if the value is contained in the array
15125     */
15126    private static boolean scanArgs(String[] args, String value) {
15127        if (args != null) {
15128            for (String arg : args) {
15129                if (value.equals(arg)) {
15130                    return true;
15131                }
15132            }
15133        }
15134        return false;
15135    }
15136
15137    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15138            ContentProviderRecord cpr, boolean always) {
15139        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15140
15141        if (!inLaunching || always) {
15142            synchronized (cpr) {
15143                cpr.launchingApp = null;
15144                cpr.notifyAll();
15145            }
15146            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15147            String names[] = cpr.info.authority.split(";");
15148            for (int j = 0; j < names.length; j++) {
15149                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15150            }
15151        }
15152
15153        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15154            ContentProviderConnection conn = cpr.connections.get(i);
15155            if (conn.waiting) {
15156                // If this connection is waiting for the provider, then we don't
15157                // need to mess with its process unless we are always removing
15158                // or for some reason the provider is not currently launching.
15159                if (inLaunching && !always) {
15160                    continue;
15161                }
15162            }
15163            ProcessRecord capp = conn.client;
15164            conn.dead = true;
15165            if (conn.stableCount > 0) {
15166                if (!capp.persistent && capp.thread != null
15167                        && capp.pid != 0
15168                        && capp.pid != MY_PID) {
15169                    capp.kill("depends on provider "
15170                            + cpr.name.flattenToShortString()
15171                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15172                }
15173            } else if (capp.thread != null && conn.provider.provider != null) {
15174                try {
15175                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15176                } catch (RemoteException e) {
15177                }
15178                // In the protocol here, we don't expect the client to correctly
15179                // clean up this connection, we'll just remove it.
15180                cpr.connections.remove(i);
15181                if (conn.client.conProviders.remove(conn)) {
15182                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15183                }
15184            }
15185        }
15186
15187        if (inLaunching && always) {
15188            mLaunchingProviders.remove(cpr);
15189        }
15190        return inLaunching;
15191    }
15192
15193    /**
15194     * Main code for cleaning up a process when it has gone away.  This is
15195     * called both as a result of the process dying, or directly when stopping
15196     * a process when running in single process mode.
15197     *
15198     * @return Returns true if the given process has been restarted, so the
15199     * app that was passed in must remain on the process lists.
15200     */
15201    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15202            boolean restarting, boolean allowRestart, int index) {
15203        if (index >= 0) {
15204            removeLruProcessLocked(app);
15205            ProcessList.remove(app.pid);
15206        }
15207
15208        mProcessesToGc.remove(app);
15209        mPendingPssProcesses.remove(app);
15210
15211        // Dismiss any open dialogs.
15212        if (app.crashDialog != null && !app.forceCrashReport) {
15213            app.crashDialog.dismiss();
15214            app.crashDialog = null;
15215        }
15216        if (app.anrDialog != null) {
15217            app.anrDialog.dismiss();
15218            app.anrDialog = null;
15219        }
15220        if (app.waitDialog != null) {
15221            app.waitDialog.dismiss();
15222            app.waitDialog = null;
15223        }
15224
15225        app.crashing = false;
15226        app.notResponding = false;
15227
15228        app.resetPackageList(mProcessStats);
15229        app.unlinkDeathRecipient();
15230        app.makeInactive(mProcessStats);
15231        app.waitingToKill = null;
15232        app.forcingToForeground = null;
15233        updateProcessForegroundLocked(app, false, false);
15234        app.foregroundActivities = false;
15235        app.hasShownUi = false;
15236        app.treatLikeActivity = false;
15237        app.hasAboveClient = false;
15238        app.hasClientActivities = false;
15239
15240        mServices.killServicesLocked(app, allowRestart);
15241
15242        boolean restart = false;
15243
15244        // Remove published content providers.
15245        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15246            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15247            final boolean always = app.bad || !allowRestart;
15248            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15249            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15250                // We left the provider in the launching list, need to
15251                // restart it.
15252                restart = true;
15253            }
15254
15255            cpr.provider = null;
15256            cpr.proc = null;
15257        }
15258        app.pubProviders.clear();
15259
15260        // Take care of any launching providers waiting for this process.
15261        if (checkAppInLaunchingProvidersLocked(app, false)) {
15262            restart = true;
15263        }
15264
15265        // Unregister from connected content providers.
15266        if (!app.conProviders.isEmpty()) {
15267            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15268                ContentProviderConnection conn = app.conProviders.get(i);
15269                conn.provider.connections.remove(conn);
15270                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15271                        conn.provider.name);
15272            }
15273            app.conProviders.clear();
15274        }
15275
15276        // At this point there may be remaining entries in mLaunchingProviders
15277        // where we were the only one waiting, so they are no longer of use.
15278        // Look for these and clean up if found.
15279        // XXX Commented out for now.  Trying to figure out a way to reproduce
15280        // the actual situation to identify what is actually going on.
15281        if (false) {
15282            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15283                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15284                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15285                    synchronized (cpr) {
15286                        cpr.launchingApp = null;
15287                        cpr.notifyAll();
15288                    }
15289                }
15290            }
15291        }
15292
15293        skipCurrentReceiverLocked(app);
15294
15295        // Unregister any receivers.
15296        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15297            removeReceiverLocked(app.receivers.valueAt(i));
15298        }
15299        app.receivers.clear();
15300
15301        // If the app is undergoing backup, tell the backup manager about it
15302        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15303            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15304                    + mBackupTarget.appInfo + " died during backup");
15305            try {
15306                IBackupManager bm = IBackupManager.Stub.asInterface(
15307                        ServiceManager.getService(Context.BACKUP_SERVICE));
15308                bm.agentDisconnected(app.info.packageName);
15309            } catch (RemoteException e) {
15310                // can't happen; backup manager is local
15311            }
15312        }
15313
15314        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15315            ProcessChangeItem item = mPendingProcessChanges.get(i);
15316            if (item.pid == app.pid) {
15317                mPendingProcessChanges.remove(i);
15318                mAvailProcessChanges.add(item);
15319            }
15320        }
15321        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15322
15323        // If the caller is restarting this app, then leave it in its
15324        // current lists and let the caller take care of it.
15325        if (restarting) {
15326            return false;
15327        }
15328
15329        if (!app.persistent || app.isolated) {
15330            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15331                    "Removing non-persistent process during cleanup: " + app);
15332            removeProcessNameLocked(app.processName, app.uid);
15333            if (mHeavyWeightProcess == app) {
15334                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15335                        mHeavyWeightProcess.userId, 0));
15336                mHeavyWeightProcess = null;
15337            }
15338        } else if (!app.removed) {
15339            // This app is persistent, so we need to keep its record around.
15340            // If it is not already on the pending app list, add it there
15341            // and start a new process for it.
15342            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15343                mPersistentStartingProcesses.add(app);
15344                restart = true;
15345            }
15346        }
15347        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15348                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15349        mProcessesOnHold.remove(app);
15350
15351        if (app == mHomeProcess) {
15352            mHomeProcess = null;
15353        }
15354        if (app == mPreviousProcess) {
15355            mPreviousProcess = null;
15356        }
15357
15358        if (restart && !app.isolated) {
15359            // We have components that still need to be running in the
15360            // process, so re-launch it.
15361            if (index < 0) {
15362                ProcessList.remove(app.pid);
15363            }
15364            addProcessNameLocked(app);
15365            startProcessLocked(app, "restart", app.processName);
15366            return true;
15367        } else if (app.pid > 0 && app.pid != MY_PID) {
15368            // Goodbye!
15369            boolean removed;
15370            synchronized (mPidsSelfLocked) {
15371                mPidsSelfLocked.remove(app.pid);
15372                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15373            }
15374            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15375            if (app.isolated) {
15376                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15377            }
15378            app.setPid(0);
15379        }
15380        return false;
15381    }
15382
15383    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15384        // Look through the content providers we are waiting to have launched,
15385        // and if any run in this process then either schedule a restart of
15386        // the process or kill the client waiting for it if this process has
15387        // gone bad.
15388        boolean restart = false;
15389        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15390            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15391            if (cpr.launchingApp == app) {
15392                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15393                    restart = true;
15394                } else {
15395                    removeDyingProviderLocked(app, cpr, true);
15396                }
15397            }
15398        }
15399        return restart;
15400    }
15401
15402    // =========================================================
15403    // SERVICES
15404    // =========================================================
15405
15406    @Override
15407    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15408            int flags) {
15409        enforceNotIsolatedCaller("getServices");
15410        synchronized (this) {
15411            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15412        }
15413    }
15414
15415    @Override
15416    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15417        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15418        synchronized (this) {
15419            return mServices.getRunningServiceControlPanelLocked(name);
15420        }
15421    }
15422
15423    @Override
15424    public ComponentName startService(IApplicationThread caller, Intent service,
15425            String resolvedType, int userId) throws TransactionTooLargeException {
15426        enforceNotIsolatedCaller("startService");
15427        // Refuse possible leaked file descriptors
15428        if (service != null && service.hasFileDescriptors() == true) {
15429            throw new IllegalArgumentException("File descriptors passed in Intent");
15430        }
15431
15432        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15433                "startService: " + service + " type=" + resolvedType);
15434        synchronized(this) {
15435            final int callingPid = Binder.getCallingPid();
15436            final int callingUid = Binder.getCallingUid();
15437            final long origId = Binder.clearCallingIdentity();
15438            ComponentName res = mServices.startServiceLocked(caller, service,
15439                    resolvedType, callingPid, callingUid, userId);
15440            Binder.restoreCallingIdentity(origId);
15441            return res;
15442        }
15443    }
15444
15445    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, int userId)
15446            throws TransactionTooLargeException {
15447        synchronized(this) {
15448            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15449                    "startServiceInPackage: " + service + " type=" + resolvedType);
15450            final long origId = Binder.clearCallingIdentity();
15451            ComponentName res = mServices.startServiceLocked(null, service,
15452                    resolvedType, -1, uid, userId);
15453            Binder.restoreCallingIdentity(origId);
15454            return res;
15455        }
15456    }
15457
15458    @Override
15459    public int stopService(IApplicationThread caller, Intent service,
15460            String resolvedType, int userId) {
15461        enforceNotIsolatedCaller("stopService");
15462        // Refuse possible leaked file descriptors
15463        if (service != null && service.hasFileDescriptors() == true) {
15464            throw new IllegalArgumentException("File descriptors passed in Intent");
15465        }
15466
15467        synchronized(this) {
15468            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15469        }
15470    }
15471
15472    @Override
15473    public IBinder peekService(Intent service, String resolvedType) {
15474        enforceNotIsolatedCaller("peekService");
15475        // Refuse possible leaked file descriptors
15476        if (service != null && service.hasFileDescriptors() == true) {
15477            throw new IllegalArgumentException("File descriptors passed in Intent");
15478        }
15479        synchronized(this) {
15480            return mServices.peekServiceLocked(service, resolvedType);
15481        }
15482    }
15483
15484    @Override
15485    public boolean stopServiceToken(ComponentName className, IBinder token,
15486            int startId) {
15487        synchronized(this) {
15488            return mServices.stopServiceTokenLocked(className, token, startId);
15489        }
15490    }
15491
15492    @Override
15493    public void setServiceForeground(ComponentName className, IBinder token,
15494            int id, Notification notification, boolean removeNotification) {
15495        synchronized(this) {
15496            mServices.setServiceForegroundLocked(className, token, id, notification,
15497                    removeNotification);
15498        }
15499    }
15500
15501    @Override
15502    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15503            boolean requireFull, String name, String callerPackage) {
15504        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15505                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15506    }
15507
15508    int unsafeConvertIncomingUser(int userId) {
15509        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15510                ? mCurrentUserId : userId;
15511    }
15512
15513    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15514            int allowMode, String name, String callerPackage) {
15515        final int callingUserId = UserHandle.getUserId(callingUid);
15516        if (callingUserId == userId) {
15517            return userId;
15518        }
15519
15520        // Note that we may be accessing mCurrentUserId outside of a lock...
15521        // shouldn't be a big deal, if this is being called outside
15522        // of a locked context there is intrinsically a race with
15523        // the value the caller will receive and someone else changing it.
15524        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15525        // we will switch to the calling user if access to the current user fails.
15526        int targetUserId = unsafeConvertIncomingUser(userId);
15527
15528        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15529            final boolean allow;
15530            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15531                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15532                // If the caller has this permission, they always pass go.  And collect $200.
15533                allow = true;
15534            } else if (allowMode == ALLOW_FULL_ONLY) {
15535                // We require full access, sucks to be you.
15536                allow = false;
15537            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15538                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15539                // If the caller does not have either permission, they are always doomed.
15540                allow = false;
15541            } else if (allowMode == ALLOW_NON_FULL) {
15542                // We are blanket allowing non-full access, you lucky caller!
15543                allow = true;
15544            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15545                // We may or may not allow this depending on whether the two users are
15546                // in the same profile.
15547                synchronized (mUserProfileGroupIdsSelfLocked) {
15548                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15549                            UserInfo.NO_PROFILE_GROUP_ID);
15550                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15551                            UserInfo.NO_PROFILE_GROUP_ID);
15552                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15553                            && callingProfile == targetProfile;
15554                }
15555            } else {
15556                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15557            }
15558            if (!allow) {
15559                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15560                    // In this case, they would like to just execute as their
15561                    // owner user instead of failing.
15562                    targetUserId = callingUserId;
15563                } else {
15564                    StringBuilder builder = new StringBuilder(128);
15565                    builder.append("Permission Denial: ");
15566                    builder.append(name);
15567                    if (callerPackage != null) {
15568                        builder.append(" from ");
15569                        builder.append(callerPackage);
15570                    }
15571                    builder.append(" asks to run as user ");
15572                    builder.append(userId);
15573                    builder.append(" but is calling from user ");
15574                    builder.append(UserHandle.getUserId(callingUid));
15575                    builder.append("; this requires ");
15576                    builder.append(INTERACT_ACROSS_USERS_FULL);
15577                    if (allowMode != ALLOW_FULL_ONLY) {
15578                        builder.append(" or ");
15579                        builder.append(INTERACT_ACROSS_USERS);
15580                    }
15581                    String msg = builder.toString();
15582                    Slog.w(TAG, msg);
15583                    throw new SecurityException(msg);
15584                }
15585            }
15586        }
15587        if (!allowAll && targetUserId < 0) {
15588            throw new IllegalArgumentException(
15589                    "Call does not support special user #" + targetUserId);
15590        }
15591        // Check shell permission
15592        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15593            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15594                    targetUserId)) {
15595                throw new SecurityException("Shell does not have permission to access user "
15596                        + targetUserId + "\n " + Debug.getCallers(3));
15597            }
15598        }
15599        return targetUserId;
15600    }
15601
15602    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15603            String className, int flags) {
15604        boolean result = false;
15605        // For apps that don't have pre-defined UIDs, check for permission
15606        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15607            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15608                if (ActivityManager.checkUidPermission(
15609                        INTERACT_ACROSS_USERS,
15610                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15611                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15612                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15613                            + " requests FLAG_SINGLE_USER, but app does not hold "
15614                            + INTERACT_ACROSS_USERS;
15615                    Slog.w(TAG, msg);
15616                    throw new SecurityException(msg);
15617                }
15618                // Permission passed
15619                result = true;
15620            }
15621        } else if ("system".equals(componentProcessName)) {
15622            result = true;
15623        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15624            // Phone app and persistent apps are allowed to export singleuser providers.
15625            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15626                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15627        }
15628        if (DEBUG_MU) Slog.v(TAG_MU,
15629                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15630                + Integer.toHexString(flags) + ") = " + result);
15631        return result;
15632    }
15633
15634    /**
15635     * Checks to see if the caller is in the same app as the singleton
15636     * component, or the component is in a special app. It allows special apps
15637     * to export singleton components but prevents exporting singleton
15638     * components for regular apps.
15639     */
15640    boolean isValidSingletonCall(int callingUid, int componentUid) {
15641        int componentAppId = UserHandle.getAppId(componentUid);
15642        return UserHandle.isSameApp(callingUid, componentUid)
15643                || componentAppId == Process.SYSTEM_UID
15644                || componentAppId == Process.PHONE_UID
15645                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15646                        == PackageManager.PERMISSION_GRANTED;
15647    }
15648
15649    public int bindService(IApplicationThread caller, IBinder token, Intent service,
15650            String resolvedType, IServiceConnection connection, int flags, int userId)
15651            throws TransactionTooLargeException {
15652        enforceNotIsolatedCaller("bindService");
15653
15654        // Refuse possible leaked file descriptors
15655        if (service != null && service.hasFileDescriptors() == true) {
15656            throw new IllegalArgumentException("File descriptors passed in Intent");
15657        }
15658
15659        synchronized(this) {
15660            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15661                    connection, flags, userId);
15662        }
15663    }
15664
15665    public boolean unbindService(IServiceConnection connection) {
15666        synchronized (this) {
15667            return mServices.unbindServiceLocked(connection);
15668        }
15669    }
15670
15671    public void publishService(IBinder token, Intent intent, IBinder service) {
15672        // Refuse possible leaked file descriptors
15673        if (intent != null && intent.hasFileDescriptors() == true) {
15674            throw new IllegalArgumentException("File descriptors passed in Intent");
15675        }
15676
15677        synchronized(this) {
15678            if (!(token instanceof ServiceRecord)) {
15679                throw new IllegalArgumentException("Invalid service token");
15680            }
15681            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15682        }
15683    }
15684
15685    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15686        // Refuse possible leaked file descriptors
15687        if (intent != null && intent.hasFileDescriptors() == true) {
15688            throw new IllegalArgumentException("File descriptors passed in Intent");
15689        }
15690
15691        synchronized(this) {
15692            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15693        }
15694    }
15695
15696    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15697        synchronized(this) {
15698            if (!(token instanceof ServiceRecord)) {
15699                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15700                throw new IllegalArgumentException("Invalid service token");
15701            }
15702            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15703        }
15704    }
15705
15706    // =========================================================
15707    // BACKUP AND RESTORE
15708    // =========================================================
15709
15710    // Cause the target app to be launched if necessary and its backup agent
15711    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15712    // activity manager to announce its creation.
15713    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15714        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15715                "bindBackupAgent: app=" + app + " mode=" + backupMode);
15716        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15717
15718        synchronized(this) {
15719            // !!! TODO: currently no check here that we're already bound
15720            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15721            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15722            synchronized (stats) {
15723                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15724            }
15725
15726            // Backup agent is now in use, its package can't be stopped.
15727            try {
15728                AppGlobals.getPackageManager().setPackageStoppedState(
15729                        app.packageName, false, UserHandle.getUserId(app.uid));
15730            } catch (RemoteException e) {
15731            } catch (IllegalArgumentException e) {
15732                Slog.w(TAG, "Failed trying to unstop package "
15733                        + app.packageName + ": " + e);
15734            }
15735
15736            BackupRecord r = new BackupRecord(ss, app, backupMode);
15737            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15738                    ? new ComponentName(app.packageName, app.backupAgentName)
15739                    : new ComponentName("android", "FullBackupAgent");
15740            // startProcessLocked() returns existing proc's record if it's already running
15741            ProcessRecord proc = startProcessLocked(app.processName, app,
15742                    false, 0, "backup", hostingName, false, false, false);
15743            if (proc == null) {
15744                Slog.e(TAG, "Unable to start backup agent process " + r);
15745                return false;
15746            }
15747
15748            r.app = proc;
15749            mBackupTarget = r;
15750            mBackupAppName = app.packageName;
15751
15752            // Try not to kill the process during backup
15753            updateOomAdjLocked(proc);
15754
15755            // If the process is already attached, schedule the creation of the backup agent now.
15756            // If it is not yet live, this will be done when it attaches to the framework.
15757            if (proc.thread != null) {
15758                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
15759                try {
15760                    proc.thread.scheduleCreateBackupAgent(app,
15761                            compatibilityInfoForPackageLocked(app), backupMode);
15762                } catch (RemoteException e) {
15763                    // Will time out on the backup manager side
15764                }
15765            } else {
15766                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
15767            }
15768            // Invariants: at this point, the target app process exists and the application
15769            // is either already running or in the process of coming up.  mBackupTarget and
15770            // mBackupAppName describe the app, so that when it binds back to the AM we
15771            // know that it's scheduled for a backup-agent operation.
15772        }
15773
15774        return true;
15775    }
15776
15777    @Override
15778    public void clearPendingBackup() {
15779        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
15780        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15781
15782        synchronized (this) {
15783            mBackupTarget = null;
15784            mBackupAppName = null;
15785        }
15786    }
15787
15788    // A backup agent has just come up
15789    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15790        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
15791                + " = " + agent);
15792
15793        synchronized(this) {
15794            if (!agentPackageName.equals(mBackupAppName)) {
15795                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15796                return;
15797            }
15798        }
15799
15800        long oldIdent = Binder.clearCallingIdentity();
15801        try {
15802            IBackupManager bm = IBackupManager.Stub.asInterface(
15803                    ServiceManager.getService(Context.BACKUP_SERVICE));
15804            bm.agentConnected(agentPackageName, agent);
15805        } catch (RemoteException e) {
15806            // can't happen; the backup manager service is local
15807        } catch (Exception e) {
15808            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15809            e.printStackTrace();
15810        } finally {
15811            Binder.restoreCallingIdentity(oldIdent);
15812        }
15813    }
15814
15815    // done with this agent
15816    public void unbindBackupAgent(ApplicationInfo appInfo) {
15817        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
15818        if (appInfo == null) {
15819            Slog.w(TAG, "unbind backup agent for null app");
15820            return;
15821        }
15822
15823        synchronized(this) {
15824            try {
15825                if (mBackupAppName == null) {
15826                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15827                    return;
15828                }
15829
15830                if (!mBackupAppName.equals(appInfo.packageName)) {
15831                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15832                    return;
15833                }
15834
15835                // Not backing this app up any more; reset its OOM adjustment
15836                final ProcessRecord proc = mBackupTarget.app;
15837                updateOomAdjLocked(proc);
15838
15839                // If the app crashed during backup, 'thread' will be null here
15840                if (proc.thread != null) {
15841                    try {
15842                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15843                                compatibilityInfoForPackageLocked(appInfo));
15844                    } catch (Exception e) {
15845                        Slog.e(TAG, "Exception when unbinding backup agent:");
15846                        e.printStackTrace();
15847                    }
15848                }
15849            } finally {
15850                mBackupTarget = null;
15851                mBackupAppName = null;
15852            }
15853        }
15854    }
15855    // =========================================================
15856    // BROADCASTS
15857    // =========================================================
15858
15859    boolean isPendingBroadcastProcessLocked(int pid) {
15860        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15861                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15862    }
15863
15864    void skipPendingBroadcastLocked(int pid) {
15865            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15866            for (BroadcastQueue queue : mBroadcastQueues) {
15867                queue.skipPendingBroadcastLocked(pid);
15868            }
15869    }
15870
15871    // The app just attached; send any pending broadcasts that it should receive
15872    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15873        boolean didSomething = false;
15874        for (BroadcastQueue queue : mBroadcastQueues) {
15875            didSomething |= queue.sendPendingBroadcastsLocked(app);
15876        }
15877        return didSomething;
15878    }
15879
15880    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15881            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15882        enforceNotIsolatedCaller("registerReceiver");
15883        ArrayList<Intent> stickyIntents = null;
15884        ProcessRecord callerApp = null;
15885        int callingUid;
15886        int callingPid;
15887        synchronized(this) {
15888            if (caller != null) {
15889                callerApp = getRecordForAppLocked(caller);
15890                if (callerApp == null) {
15891                    throw new SecurityException(
15892                            "Unable to find app for caller " + caller
15893                            + " (pid=" + Binder.getCallingPid()
15894                            + ") when registering receiver " + receiver);
15895                }
15896                if (callerApp.info.uid != Process.SYSTEM_UID &&
15897                        !callerApp.pkgList.containsKey(callerPackage) &&
15898                        !"android".equals(callerPackage)) {
15899                    throw new SecurityException("Given caller package " + callerPackage
15900                            + " is not running in process " + callerApp);
15901                }
15902                callingUid = callerApp.info.uid;
15903                callingPid = callerApp.pid;
15904            } else {
15905                callerPackage = null;
15906                callingUid = Binder.getCallingUid();
15907                callingPid = Binder.getCallingPid();
15908            }
15909
15910            userId = handleIncomingUser(callingPid, callingUid, userId,
15911                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15912
15913            Iterator<String> actions = filter.actionsIterator();
15914            if (actions == null) {
15915                ArrayList<String> noAction = new ArrayList<String>(1);
15916                noAction.add(null);
15917                actions = noAction.iterator();
15918            }
15919
15920            // Collect stickies of users
15921            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
15922            while (actions.hasNext()) {
15923                String action = actions.next();
15924                for (int id : userIds) {
15925                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
15926                    if (stickies != null) {
15927                        ArrayList<Intent> intents = stickies.get(action);
15928                        if (intents != null) {
15929                            if (stickyIntents == null) {
15930                                stickyIntents = new ArrayList<Intent>();
15931                            }
15932                            stickyIntents.addAll(intents);
15933                        }
15934                    }
15935                }
15936            }
15937        }
15938
15939        ArrayList<Intent> allSticky = null;
15940        if (stickyIntents != null) {
15941            final ContentResolver resolver = mContext.getContentResolver();
15942            // Look for any matching sticky broadcasts...
15943            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
15944                Intent intent = stickyIntents.get(i);
15945                // If intent has scheme "content", it will need to acccess
15946                // provider that needs to lock mProviderMap in ActivityThread
15947                // and also it may need to wait application response, so we
15948                // cannot lock ActivityManagerService here.
15949                if (filter.match(resolver, intent, true, TAG) >= 0) {
15950                    if (allSticky == null) {
15951                        allSticky = new ArrayList<Intent>();
15952                    }
15953                    allSticky.add(intent);
15954                }
15955            }
15956        }
15957
15958        // The first sticky in the list is returned directly back to the client.
15959        Intent sticky = allSticky != null ? allSticky.get(0) : null;
15960        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
15961        if (receiver == null) {
15962            return sticky;
15963        }
15964
15965        synchronized (this) {
15966            if (callerApp != null && (callerApp.thread == null
15967                    || callerApp.thread.asBinder() != caller.asBinder())) {
15968                // Original caller already died
15969                return null;
15970            }
15971            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15972            if (rl == null) {
15973                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15974                        userId, receiver);
15975                if (rl.app != null) {
15976                    rl.app.receivers.add(rl);
15977                } else {
15978                    try {
15979                        receiver.asBinder().linkToDeath(rl, 0);
15980                    } catch (RemoteException e) {
15981                        return sticky;
15982                    }
15983                    rl.linkedToDeath = true;
15984                }
15985                mRegisteredReceivers.put(receiver.asBinder(), rl);
15986            } else if (rl.uid != callingUid) {
15987                throw new IllegalArgumentException(
15988                        "Receiver requested to register for uid " + callingUid
15989                        + " was previously registered for uid " + rl.uid);
15990            } else if (rl.pid != callingPid) {
15991                throw new IllegalArgumentException(
15992                        "Receiver requested to register for pid " + callingPid
15993                        + " was previously registered for pid " + rl.pid);
15994            } else if (rl.userId != userId) {
15995                throw new IllegalArgumentException(
15996                        "Receiver requested to register for user " + userId
15997                        + " was previously registered for user " + rl.userId);
15998            }
15999            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16000                    permission, callingUid, userId);
16001            rl.add(bf);
16002            if (!bf.debugCheck()) {
16003                Slog.w(TAG, "==> For Dynamic broadcast");
16004            }
16005            mReceiverResolver.addFilter(bf);
16006
16007            // Enqueue broadcasts for all existing stickies that match
16008            // this filter.
16009            if (allSticky != null) {
16010                ArrayList receivers = new ArrayList();
16011                receivers.add(bf);
16012
16013                final int stickyCount = allSticky.size();
16014                for (int i = 0; i < stickyCount; i++) {
16015                    Intent intent = allSticky.get(i);
16016                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16017                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16018                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
16019                            null, null, false, true, true, -1);
16020                    queue.enqueueParallelBroadcastLocked(r);
16021                    queue.scheduleBroadcastsLocked();
16022                }
16023            }
16024
16025            return sticky;
16026        }
16027    }
16028
16029    public void unregisterReceiver(IIntentReceiver receiver) {
16030        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16031
16032        final long origId = Binder.clearCallingIdentity();
16033        try {
16034            boolean doTrim = false;
16035
16036            synchronized(this) {
16037                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16038                if (rl != null) {
16039                    final BroadcastRecord r = rl.curBroadcast;
16040                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16041                        final boolean doNext = r.queue.finishReceiverLocked(
16042                                r, r.resultCode, r.resultData, r.resultExtras,
16043                                r.resultAbort, false);
16044                        if (doNext) {
16045                            doTrim = true;
16046                            r.queue.processNextBroadcast(false);
16047                        }
16048                    }
16049
16050                    if (rl.app != null) {
16051                        rl.app.receivers.remove(rl);
16052                    }
16053                    removeReceiverLocked(rl);
16054                    if (rl.linkedToDeath) {
16055                        rl.linkedToDeath = false;
16056                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16057                    }
16058                }
16059            }
16060
16061            // If we actually concluded any broadcasts, we might now be able
16062            // to trim the recipients' apps from our working set
16063            if (doTrim) {
16064                trimApplications();
16065                return;
16066            }
16067
16068        } finally {
16069            Binder.restoreCallingIdentity(origId);
16070        }
16071    }
16072
16073    void removeReceiverLocked(ReceiverList rl) {
16074        mRegisteredReceivers.remove(rl.receiver.asBinder());
16075        for (int i = rl.size() - 1; i >= 0; i--) {
16076            mReceiverResolver.removeFilter(rl.get(i));
16077        }
16078    }
16079
16080    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16081        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16082            ProcessRecord r = mLruProcesses.get(i);
16083            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16084                try {
16085                    r.thread.dispatchPackageBroadcast(cmd, packages);
16086                } catch (RemoteException ex) {
16087                }
16088            }
16089        }
16090    }
16091
16092    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16093            int callingUid, int[] users) {
16094        List<ResolveInfo> receivers = null;
16095        try {
16096            HashSet<ComponentName> singleUserReceivers = null;
16097            boolean scannedFirstReceivers = false;
16098            for (int user : users) {
16099                // Skip users that have Shell restrictions
16100                if (callingUid == Process.SHELL_UID
16101                        && getUserManagerLocked().hasUserRestriction(
16102                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16103                    continue;
16104                }
16105                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16106                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16107                if (user != UserHandle.USER_OWNER && newReceivers != null) {
16108                    // If this is not the primary user, we need to check for
16109                    // any receivers that should be filtered out.
16110                    for (int i=0; i<newReceivers.size(); i++) {
16111                        ResolveInfo ri = newReceivers.get(i);
16112                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16113                            newReceivers.remove(i);
16114                            i--;
16115                        }
16116                    }
16117                }
16118                if (newReceivers != null && newReceivers.size() == 0) {
16119                    newReceivers = null;
16120                }
16121                if (receivers == null) {
16122                    receivers = newReceivers;
16123                } else if (newReceivers != null) {
16124                    // We need to concatenate the additional receivers
16125                    // found with what we have do far.  This would be easy,
16126                    // but we also need to de-dup any receivers that are
16127                    // singleUser.
16128                    if (!scannedFirstReceivers) {
16129                        // Collect any single user receivers we had already retrieved.
16130                        scannedFirstReceivers = true;
16131                        for (int i=0; i<receivers.size(); i++) {
16132                            ResolveInfo ri = receivers.get(i);
16133                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16134                                ComponentName cn = new ComponentName(
16135                                        ri.activityInfo.packageName, ri.activityInfo.name);
16136                                if (singleUserReceivers == null) {
16137                                    singleUserReceivers = new HashSet<ComponentName>();
16138                                }
16139                                singleUserReceivers.add(cn);
16140                            }
16141                        }
16142                    }
16143                    // Add the new results to the existing results, tracking
16144                    // and de-dupping single user receivers.
16145                    for (int i=0; i<newReceivers.size(); i++) {
16146                        ResolveInfo ri = newReceivers.get(i);
16147                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16148                            ComponentName cn = new ComponentName(
16149                                    ri.activityInfo.packageName, ri.activityInfo.name);
16150                            if (singleUserReceivers == null) {
16151                                singleUserReceivers = new HashSet<ComponentName>();
16152                            }
16153                            if (!singleUserReceivers.contains(cn)) {
16154                                singleUserReceivers.add(cn);
16155                                receivers.add(ri);
16156                            }
16157                        } else {
16158                            receivers.add(ri);
16159                        }
16160                    }
16161                }
16162            }
16163        } catch (RemoteException ex) {
16164            // pm is in same process, this will never happen.
16165        }
16166        return receivers;
16167    }
16168
16169    private final int broadcastIntentLocked(ProcessRecord callerApp,
16170            String callerPackage, Intent intent, String resolvedType,
16171            IIntentReceiver resultTo, int resultCode, String resultData,
16172            Bundle map, String requiredPermission, int appOp,
16173            boolean ordered, boolean sticky, int callingPid, int callingUid,
16174            int userId) {
16175        intent = new Intent(intent);
16176
16177        // By default broadcasts do not go to stopped apps.
16178        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16179
16180        // If we have not finished booting, don't allow this to launch new processes.
16181        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16182            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16183        }
16184
16185        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16186                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16187                + " ordered=" + ordered + " userid=" + userId);
16188        if ((resultTo != null) && !ordered) {
16189            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16190        }
16191
16192        userId = handleIncomingUser(callingPid, callingUid, userId,
16193                true, ALLOW_NON_FULL, "broadcast", callerPackage);
16194
16195        // Make sure that the user who is receiving this broadcast is running.
16196        // If not, we will just skip it. Make an exception for shutdown broadcasts
16197        // and upgrade steps.
16198
16199        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16200            if ((callingUid != Process.SYSTEM_UID
16201                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16202                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16203                Slog.w(TAG, "Skipping broadcast of " + intent
16204                        + ": user " + userId + " is stopped");
16205                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16206            }
16207        }
16208
16209        /*
16210         * Prevent non-system code (defined here to be non-persistent
16211         * processes) from sending protected broadcasts.
16212         */
16213        int callingAppId = UserHandle.getAppId(callingUid);
16214        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16215            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16216            || callingAppId == Process.NFC_UID || callingUid == 0) {
16217            // Always okay.
16218        } else if (callerApp == null || !callerApp.persistent) {
16219            try {
16220                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16221                        intent.getAction())) {
16222                    String msg = "Permission Denial: not allowed to send broadcast "
16223                            + intent.getAction() + " from pid="
16224                            + callingPid + ", uid=" + callingUid;
16225                    Slog.w(TAG, msg);
16226                    throw new SecurityException(msg);
16227                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16228                    // Special case for compatibility: we don't want apps to send this,
16229                    // but historically it has not been protected and apps may be using it
16230                    // to poke their own app widget.  So, instead of making it protected,
16231                    // just limit it to the caller.
16232                    if (callerApp == null) {
16233                        String msg = "Permission Denial: not allowed to send broadcast "
16234                                + intent.getAction() + " from unknown caller.";
16235                        Slog.w(TAG, msg);
16236                        throw new SecurityException(msg);
16237                    } else if (intent.getComponent() != null) {
16238                        // They are good enough to send to an explicit component...  verify
16239                        // it is being sent to the calling app.
16240                        if (!intent.getComponent().getPackageName().equals(
16241                                callerApp.info.packageName)) {
16242                            String msg = "Permission Denial: not allowed to send broadcast "
16243                                    + intent.getAction() + " to "
16244                                    + intent.getComponent().getPackageName() + " from "
16245                                    + callerApp.info.packageName;
16246                            Slog.w(TAG, msg);
16247                            throw new SecurityException(msg);
16248                        }
16249                    } else {
16250                        // Limit broadcast to their own package.
16251                        intent.setPackage(callerApp.info.packageName);
16252                    }
16253                }
16254            } catch (RemoteException e) {
16255                Slog.w(TAG, "Remote exception", e);
16256                return ActivityManager.BROADCAST_SUCCESS;
16257            }
16258        }
16259
16260        final String action = intent.getAction();
16261        if (action != null) {
16262            switch (action) {
16263                case Intent.ACTION_UID_REMOVED:
16264                case Intent.ACTION_PACKAGE_REMOVED:
16265                case Intent.ACTION_PACKAGE_CHANGED:
16266                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16267                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16268                    // Handle special intents: if this broadcast is from the package
16269                    // manager about a package being removed, we need to remove all of
16270                    // its activities from the history stack.
16271                    if (checkComponentPermission(
16272                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16273                            callingPid, callingUid, -1, true)
16274                            != PackageManager.PERMISSION_GRANTED) {
16275                        String msg = "Permission Denial: " + intent.getAction()
16276                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16277                                + ", uid=" + callingUid + ")"
16278                                + " requires "
16279                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16280                        Slog.w(TAG, msg);
16281                        throw new SecurityException(msg);
16282                    }
16283                    switch (action) {
16284                        case Intent.ACTION_UID_REMOVED:
16285                            final Bundle intentExtras = intent.getExtras();
16286                            final int uid = intentExtras != null
16287                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16288                            if (uid >= 0) {
16289                                mBatteryStatsService.removeUid(uid);
16290                                mAppOpsService.uidRemoved(uid);
16291                            }
16292                            break;
16293                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16294                            // If resources are unavailable just force stop all those packages
16295                            // and flush the attribute cache as well.
16296                            String list[] =
16297                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16298                            if (list != null && list.length > 0) {
16299                                for (int i = 0; i < list.length; i++) {
16300                                    forceStopPackageLocked(list[i], -1, false, true, true,
16301                                            false, false, userId, "storage unmount");
16302                                }
16303                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16304                                sendPackageBroadcastLocked(
16305                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16306                                        userId);
16307                            }
16308                            break;
16309                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16310                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16311                            break;
16312                        case Intent.ACTION_PACKAGE_REMOVED:
16313                        case Intent.ACTION_PACKAGE_CHANGED:
16314                            Uri data = intent.getData();
16315                            String ssp;
16316                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16317                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16318                                boolean fullUninstall = removed &&
16319                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16320                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16321                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16322                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16323                                            false, true, true, false, fullUninstall, userId,
16324                                            removed ? "pkg removed" : "pkg changed");
16325                                }
16326                                if (removed) {
16327                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16328                                            new String[] {ssp}, userId);
16329                                    if (fullUninstall) {
16330                                        mAppOpsService.packageRemoved(
16331                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16332
16333                                        // Remove all permissions granted from/to this package
16334                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16335
16336                                        removeTasksByPackageNameLocked(ssp, userId);
16337                                        if (userId == UserHandle.USER_OWNER) {
16338                                            mTaskPersister.removeFromPackageCache(ssp);
16339                                        }
16340                                        mBatteryStatsService.notePackageUninstalled(ssp);
16341                                    }
16342                                } else {
16343                                    cleanupDisabledPackageComponentsLocked(ssp, userId,
16344                                            intent.getStringArrayExtra(
16345                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16346                                    if (userId == UserHandle.USER_OWNER) {
16347                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16348                                    }
16349                                }
16350                            }
16351                            break;
16352                    }
16353                    break;
16354                case Intent.ACTION_PACKAGE_ADDED:
16355                    // Special case for adding a package: by default turn on compatibility mode.
16356                    Uri data = intent.getData();
16357                    String ssp;
16358                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16359                        final boolean replacing =
16360                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16361                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16362
16363                        if (userId == UserHandle.USER_OWNER) {
16364                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16365                        }
16366                        try {
16367                            ApplicationInfo ai = AppGlobals.getPackageManager().
16368                                    getApplicationInfo(ssp, 0, 0);
16369                            mBatteryStatsService.notePackageInstalled(ssp,
16370                                    ai != null ? ai.versionCode : 0);
16371                        } catch (RemoteException e) {
16372                        }
16373                    }
16374                    break;
16375                case Intent.ACTION_TIMEZONE_CHANGED:
16376                    // If this is the time zone changed action, queue up a message that will reset
16377                    // the timezone of all currently running processes. This message will get
16378                    // queued up before the broadcast happens.
16379                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16380                    break;
16381                case Intent.ACTION_TIME_CHANGED:
16382                    // If the user set the time, let all running processes know.
16383                    final int is24Hour =
16384                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16385                                    : 0;
16386                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16387                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16388                    synchronized (stats) {
16389                        stats.noteCurrentTimeChangedLocked();
16390                    }
16391                    break;
16392                case Intent.ACTION_CLEAR_DNS_CACHE:
16393                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16394                    break;
16395                case Proxy.PROXY_CHANGE_ACTION:
16396                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16397                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16398                    break;
16399            }
16400        }
16401
16402        // Add to the sticky list if requested.
16403        if (sticky) {
16404            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16405                    callingPid, callingUid)
16406                    != PackageManager.PERMISSION_GRANTED) {
16407                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16408                        + callingPid + ", uid=" + callingUid
16409                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16410                Slog.w(TAG, msg);
16411                throw new SecurityException(msg);
16412            }
16413            if (requiredPermission != null) {
16414                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16415                        + " and enforce permission " + requiredPermission);
16416                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16417            }
16418            if (intent.getComponent() != null) {
16419                throw new SecurityException(
16420                        "Sticky broadcasts can't target a specific component");
16421            }
16422            // We use userId directly here, since the "all" target is maintained
16423            // as a separate set of sticky broadcasts.
16424            if (userId != UserHandle.USER_ALL) {
16425                // But first, if this is not a broadcast to all users, then
16426                // make sure it doesn't conflict with an existing broadcast to
16427                // all users.
16428                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16429                        UserHandle.USER_ALL);
16430                if (stickies != null) {
16431                    ArrayList<Intent> list = stickies.get(intent.getAction());
16432                    if (list != null) {
16433                        int N = list.size();
16434                        int i;
16435                        for (i=0; i<N; i++) {
16436                            if (intent.filterEquals(list.get(i))) {
16437                                throw new IllegalArgumentException(
16438                                        "Sticky broadcast " + intent + " for user "
16439                                        + userId + " conflicts with existing global broadcast");
16440                            }
16441                        }
16442                    }
16443                }
16444            }
16445            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16446            if (stickies == null) {
16447                stickies = new ArrayMap<>();
16448                mStickyBroadcasts.put(userId, stickies);
16449            }
16450            ArrayList<Intent> list = stickies.get(intent.getAction());
16451            if (list == null) {
16452                list = new ArrayList<>();
16453                stickies.put(intent.getAction(), list);
16454            }
16455            final int stickiesCount = list.size();
16456            int i;
16457            for (i = 0; i < stickiesCount; i++) {
16458                if (intent.filterEquals(list.get(i))) {
16459                    // This sticky already exists, replace it.
16460                    list.set(i, new Intent(intent));
16461                    break;
16462                }
16463            }
16464            if (i >= stickiesCount) {
16465                list.add(new Intent(intent));
16466            }
16467        }
16468
16469        int[] users;
16470        if (userId == UserHandle.USER_ALL) {
16471            // Caller wants broadcast to go to all started users.
16472            users = mStartedUserArray;
16473        } else {
16474            // Caller wants broadcast to go to one specific user.
16475            users = new int[] {userId};
16476        }
16477
16478        // Figure out who all will receive this broadcast.
16479        List receivers = null;
16480        List<BroadcastFilter> registeredReceivers = null;
16481        // Need to resolve the intent to interested receivers...
16482        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16483                 == 0) {
16484            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16485        }
16486        if (intent.getComponent() == null) {
16487            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16488                // Query one target user at a time, excluding shell-restricted users
16489                UserManagerService ums = getUserManagerLocked();
16490                for (int i = 0; i < users.length; i++) {
16491                    if (ums.hasUserRestriction(
16492                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16493                        continue;
16494                    }
16495                    List<BroadcastFilter> registeredReceiversForUser =
16496                            mReceiverResolver.queryIntent(intent,
16497                                    resolvedType, false, users[i]);
16498                    if (registeredReceivers == null) {
16499                        registeredReceivers = registeredReceiversForUser;
16500                    } else if (registeredReceiversForUser != null) {
16501                        registeredReceivers.addAll(registeredReceiversForUser);
16502                    }
16503                }
16504            } else {
16505                registeredReceivers = mReceiverResolver.queryIntent(intent,
16506                        resolvedType, false, userId);
16507            }
16508        }
16509
16510        final boolean replacePending =
16511                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16512
16513        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16514                + " replacePending=" + replacePending);
16515
16516        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16517        if (!ordered && NR > 0) {
16518            // If we are not serializing this broadcast, then send the
16519            // registered receivers separately so they don't wait for the
16520            // components to be launched.
16521            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16522            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16523                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16524                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16525                    ordered, sticky, false, userId);
16526            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16527            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16528            if (!replaced) {
16529                queue.enqueueParallelBroadcastLocked(r);
16530                queue.scheduleBroadcastsLocked();
16531            }
16532            registeredReceivers = null;
16533            NR = 0;
16534        }
16535
16536        // Merge into one list.
16537        int ir = 0;
16538        if (receivers != null) {
16539            // A special case for PACKAGE_ADDED: do not allow the package
16540            // being added to see this broadcast.  This prevents them from
16541            // using this as a back door to get run as soon as they are
16542            // installed.  Maybe in the future we want to have a special install
16543            // broadcast or such for apps, but we'd like to deliberately make
16544            // this decision.
16545            String skipPackages[] = null;
16546            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16547                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16548                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16549                Uri data = intent.getData();
16550                if (data != null) {
16551                    String pkgName = data.getSchemeSpecificPart();
16552                    if (pkgName != null) {
16553                        skipPackages = new String[] { pkgName };
16554                    }
16555                }
16556            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16557                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16558            }
16559            if (skipPackages != null && (skipPackages.length > 0)) {
16560                for (String skipPackage : skipPackages) {
16561                    if (skipPackage != null) {
16562                        int NT = receivers.size();
16563                        for (int it=0; it<NT; it++) {
16564                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16565                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16566                                receivers.remove(it);
16567                                it--;
16568                                NT--;
16569                            }
16570                        }
16571                    }
16572                }
16573            }
16574
16575            int NT = receivers != null ? receivers.size() : 0;
16576            int it = 0;
16577            ResolveInfo curt = null;
16578            BroadcastFilter curr = null;
16579            while (it < NT && ir < NR) {
16580                if (curt == null) {
16581                    curt = (ResolveInfo)receivers.get(it);
16582                }
16583                if (curr == null) {
16584                    curr = registeredReceivers.get(ir);
16585                }
16586                if (curr.getPriority() >= curt.priority) {
16587                    // Insert this broadcast record into the final list.
16588                    receivers.add(it, curr);
16589                    ir++;
16590                    curr = null;
16591                    it++;
16592                    NT++;
16593                } else {
16594                    // Skip to the next ResolveInfo in the final list.
16595                    it++;
16596                    curt = null;
16597                }
16598            }
16599        }
16600        while (ir < NR) {
16601            if (receivers == null) {
16602                receivers = new ArrayList();
16603            }
16604            receivers.add(registeredReceivers.get(ir));
16605            ir++;
16606        }
16607
16608        if ((receivers != null && receivers.size() > 0)
16609                || resultTo != null) {
16610            BroadcastQueue queue = broadcastQueueForIntent(intent);
16611            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16612                    callerPackage, callingPid, callingUid, resolvedType,
16613                    requiredPermission, appOp, receivers, resultTo, resultCode,
16614                    resultData, map, ordered, sticky, false, userId);
16615
16616            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16617                    + ": prev had " + queue.mOrderedBroadcasts.size());
16618            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16619                    "Enqueueing broadcast " + r.intent.getAction());
16620
16621            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16622            if (!replaced) {
16623                queue.enqueueOrderedBroadcastLocked(r);
16624                queue.scheduleBroadcastsLocked();
16625            }
16626        }
16627
16628        return ActivityManager.BROADCAST_SUCCESS;
16629    }
16630
16631    final Intent verifyBroadcastLocked(Intent intent) {
16632        // Refuse possible leaked file descriptors
16633        if (intent != null && intent.hasFileDescriptors() == true) {
16634            throw new IllegalArgumentException("File descriptors passed in Intent");
16635        }
16636
16637        int flags = intent.getFlags();
16638
16639        if (!mProcessesReady) {
16640            // if the caller really truly claims to know what they're doing, go
16641            // ahead and allow the broadcast without launching any receivers
16642            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16643                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16644            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16645                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16646                        + " before boot completion");
16647                throw new IllegalStateException("Cannot broadcast before boot completed");
16648            }
16649        }
16650
16651        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16652            throw new IllegalArgumentException(
16653                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16654        }
16655
16656        return intent;
16657    }
16658
16659    public final int broadcastIntent(IApplicationThread caller,
16660            Intent intent, String resolvedType, IIntentReceiver resultTo,
16661            int resultCode, String resultData, Bundle map,
16662            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16663        enforceNotIsolatedCaller("broadcastIntent");
16664        synchronized(this) {
16665            intent = verifyBroadcastLocked(intent);
16666
16667            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16668            final int callingPid = Binder.getCallingPid();
16669            final int callingUid = Binder.getCallingUid();
16670            final long origId = Binder.clearCallingIdentity();
16671            int res = broadcastIntentLocked(callerApp,
16672                    callerApp != null ? callerApp.info.packageName : null,
16673                    intent, resolvedType, resultTo,
16674                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16675                    callingPid, callingUid, userId);
16676            Binder.restoreCallingIdentity(origId);
16677            return res;
16678        }
16679    }
16680
16681    int broadcastIntentInPackage(String packageName, int uid,
16682            Intent intent, String resolvedType, IIntentReceiver resultTo,
16683            int resultCode, String resultData, Bundle map,
16684            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16685        synchronized(this) {
16686            intent = verifyBroadcastLocked(intent);
16687
16688            final long origId = Binder.clearCallingIdentity();
16689            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16690                    resultTo, resultCode, resultData, map, requiredPermission,
16691                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16692            Binder.restoreCallingIdentity(origId);
16693            return res;
16694        }
16695    }
16696
16697    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16698        // Refuse possible leaked file descriptors
16699        if (intent != null && intent.hasFileDescriptors() == true) {
16700            throw new IllegalArgumentException("File descriptors passed in Intent");
16701        }
16702
16703        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16704                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16705
16706        synchronized(this) {
16707            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16708                    != PackageManager.PERMISSION_GRANTED) {
16709                String msg = "Permission Denial: unbroadcastIntent() from pid="
16710                        + Binder.getCallingPid()
16711                        + ", uid=" + Binder.getCallingUid()
16712                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16713                Slog.w(TAG, msg);
16714                throw new SecurityException(msg);
16715            }
16716            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16717            if (stickies != null) {
16718                ArrayList<Intent> list = stickies.get(intent.getAction());
16719                if (list != null) {
16720                    int N = list.size();
16721                    int i;
16722                    for (i=0; i<N; i++) {
16723                        if (intent.filterEquals(list.get(i))) {
16724                            list.remove(i);
16725                            break;
16726                        }
16727                    }
16728                    if (list.size() <= 0) {
16729                        stickies.remove(intent.getAction());
16730                    }
16731                }
16732                if (stickies.size() <= 0) {
16733                    mStickyBroadcasts.remove(userId);
16734                }
16735            }
16736        }
16737    }
16738
16739    void backgroundServicesFinishedLocked(int userId) {
16740        for (BroadcastQueue queue : mBroadcastQueues) {
16741            queue.backgroundServicesFinishedLocked(userId);
16742        }
16743    }
16744
16745    public void finishReceiver(IBinder who, int resultCode, String resultData,
16746            Bundle resultExtras, boolean resultAbort, int flags) {
16747        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
16748
16749        // Refuse possible leaked file descriptors
16750        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16751            throw new IllegalArgumentException("File descriptors passed in Bundle");
16752        }
16753
16754        final long origId = Binder.clearCallingIdentity();
16755        try {
16756            boolean doNext = false;
16757            BroadcastRecord r;
16758
16759            synchronized(this) {
16760                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16761                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16762                r = queue.getMatchingOrderedReceiver(who);
16763                if (r != null) {
16764                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16765                        resultData, resultExtras, resultAbort, true);
16766                }
16767            }
16768
16769            if (doNext) {
16770                r.queue.processNextBroadcast(false);
16771            }
16772            trimApplications();
16773        } finally {
16774            Binder.restoreCallingIdentity(origId);
16775        }
16776    }
16777
16778    // =========================================================
16779    // INSTRUMENTATION
16780    // =========================================================
16781
16782    public boolean startInstrumentation(ComponentName className,
16783            String profileFile, int flags, Bundle arguments,
16784            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16785            int userId, String abiOverride) {
16786        enforceNotIsolatedCaller("startInstrumentation");
16787        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16788                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16789        // Refuse possible leaked file descriptors
16790        if (arguments != null && arguments.hasFileDescriptors()) {
16791            throw new IllegalArgumentException("File descriptors passed in Bundle");
16792        }
16793
16794        synchronized(this) {
16795            InstrumentationInfo ii = null;
16796            ApplicationInfo ai = null;
16797            try {
16798                ii = mContext.getPackageManager().getInstrumentationInfo(
16799                    className, STOCK_PM_FLAGS);
16800                ai = AppGlobals.getPackageManager().getApplicationInfo(
16801                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16802            } catch (PackageManager.NameNotFoundException e) {
16803            } catch (RemoteException e) {
16804            }
16805            if (ii == null) {
16806                reportStartInstrumentationFailure(watcher, className,
16807                        "Unable to find instrumentation info for: " + className);
16808                return false;
16809            }
16810            if (ai == null) {
16811                reportStartInstrumentationFailure(watcher, className,
16812                        "Unable to find instrumentation target package: " + ii.targetPackage);
16813                return false;
16814            }
16815
16816            int match = mContext.getPackageManager().checkSignatures(
16817                    ii.targetPackage, ii.packageName);
16818            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16819                String msg = "Permission Denial: starting instrumentation "
16820                        + className + " from pid="
16821                        + Binder.getCallingPid()
16822                        + ", uid=" + Binder.getCallingPid()
16823                        + " not allowed because package " + ii.packageName
16824                        + " does not have a signature matching the target "
16825                        + ii.targetPackage;
16826                reportStartInstrumentationFailure(watcher, className, msg);
16827                throw new SecurityException(msg);
16828            }
16829
16830            final long origId = Binder.clearCallingIdentity();
16831            // Instrumentation can kill and relaunch even persistent processes
16832            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16833                    "start instr");
16834            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16835            app.instrumentationClass = className;
16836            app.instrumentationInfo = ai;
16837            app.instrumentationProfileFile = profileFile;
16838            app.instrumentationArguments = arguments;
16839            app.instrumentationWatcher = watcher;
16840            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16841            app.instrumentationResultClass = className;
16842            Binder.restoreCallingIdentity(origId);
16843        }
16844
16845        return true;
16846    }
16847
16848    /**
16849     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16850     * error to the logs, but if somebody is watching, send the report there too.  This enables
16851     * the "am" command to report errors with more information.
16852     *
16853     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16854     * @param cn The component name of the instrumentation.
16855     * @param report The error report.
16856     */
16857    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16858            ComponentName cn, String report) {
16859        Slog.w(TAG, report);
16860        try {
16861            if (watcher != null) {
16862                Bundle results = new Bundle();
16863                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16864                results.putString("Error", report);
16865                watcher.instrumentationStatus(cn, -1, results);
16866            }
16867        } catch (RemoteException e) {
16868            Slog.w(TAG, e);
16869        }
16870    }
16871
16872    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16873        if (app.instrumentationWatcher != null) {
16874            try {
16875                // NOTE:  IInstrumentationWatcher *must* be oneway here
16876                app.instrumentationWatcher.instrumentationFinished(
16877                    app.instrumentationClass,
16878                    resultCode,
16879                    results);
16880            } catch (RemoteException e) {
16881            }
16882        }
16883        if (app.instrumentationUiAutomationConnection != null) {
16884            try {
16885                app.instrumentationUiAutomationConnection.shutdown();
16886            } catch (RemoteException re) {
16887                /* ignore */
16888            }
16889            // Only a UiAutomation can set this flag and now that
16890            // it is finished we make sure it is reset to its default.
16891            mUserIsMonkey = false;
16892        }
16893        app.instrumentationWatcher = null;
16894        app.instrumentationUiAutomationConnection = null;
16895        app.instrumentationClass = null;
16896        app.instrumentationInfo = null;
16897        app.instrumentationProfileFile = null;
16898        app.instrumentationArguments = null;
16899
16900        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16901                "finished inst");
16902    }
16903
16904    public void finishInstrumentation(IApplicationThread target,
16905            int resultCode, Bundle results) {
16906        int userId = UserHandle.getCallingUserId();
16907        // Refuse possible leaked file descriptors
16908        if (results != null && results.hasFileDescriptors()) {
16909            throw new IllegalArgumentException("File descriptors passed in Intent");
16910        }
16911
16912        synchronized(this) {
16913            ProcessRecord app = getRecordForAppLocked(target);
16914            if (app == null) {
16915                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16916                return;
16917            }
16918            final long origId = Binder.clearCallingIdentity();
16919            finishInstrumentationLocked(app, resultCode, results);
16920            Binder.restoreCallingIdentity(origId);
16921        }
16922    }
16923
16924    // =========================================================
16925    // CONFIGURATION
16926    // =========================================================
16927
16928    public ConfigurationInfo getDeviceConfigurationInfo() {
16929        ConfigurationInfo config = new ConfigurationInfo();
16930        synchronized (this) {
16931            config.reqTouchScreen = mConfiguration.touchscreen;
16932            config.reqKeyboardType = mConfiguration.keyboard;
16933            config.reqNavigation = mConfiguration.navigation;
16934            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16935                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16936                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16937            }
16938            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16939                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16940                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16941            }
16942            config.reqGlEsVersion = GL_ES_VERSION;
16943        }
16944        return config;
16945    }
16946
16947    ActivityStack getFocusedStack() {
16948        return mStackSupervisor.getFocusedStack();
16949    }
16950
16951    @Override
16952    public int getFocusedStackId() throws RemoteException {
16953        ActivityStack focusedStack = getFocusedStack();
16954        if (focusedStack != null) {
16955            return focusedStack.getStackId();
16956        }
16957        return -1;
16958    }
16959
16960    public Configuration getConfiguration() {
16961        Configuration ci;
16962        synchronized(this) {
16963            ci = new Configuration(mConfiguration);
16964            ci.userSetLocale = false;
16965        }
16966        return ci;
16967    }
16968
16969    public void updatePersistentConfiguration(Configuration values) {
16970        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16971                "updateConfiguration()");
16972        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16973                "updateConfiguration()");
16974        if (values == null) {
16975            throw new NullPointerException("Configuration must not be null");
16976        }
16977
16978        synchronized(this) {
16979            final long origId = Binder.clearCallingIdentity();
16980            updateConfigurationLocked(values, null, true, false);
16981            Binder.restoreCallingIdentity(origId);
16982        }
16983    }
16984
16985    public void updateConfiguration(Configuration values) {
16986        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16987                "updateConfiguration()");
16988
16989        synchronized(this) {
16990            if (values == null && mWindowManager != null) {
16991                // sentinel: fetch the current configuration from the window manager
16992                values = mWindowManager.computeNewConfiguration();
16993            }
16994
16995            if (mWindowManager != null) {
16996                mProcessList.applyDisplaySize(mWindowManager);
16997            }
16998
16999            final long origId = Binder.clearCallingIdentity();
17000            if (values != null) {
17001                Settings.System.clearConfiguration(values);
17002            }
17003            updateConfigurationLocked(values, null, false, false);
17004            Binder.restoreCallingIdentity(origId);
17005        }
17006    }
17007
17008    /**
17009     * Do either or both things: (1) change the current configuration, and (2)
17010     * make sure the given activity is running with the (now) current
17011     * configuration.  Returns true if the activity has been left running, or
17012     * false if <var>starting</var> is being destroyed to match the new
17013     * configuration.
17014     * @param persistent TODO
17015     */
17016    boolean updateConfigurationLocked(Configuration values,
17017            ActivityRecord starting, boolean persistent, boolean initLocale) {
17018        int changes = 0;
17019
17020        if (values != null) {
17021            Configuration newConfig = new Configuration(mConfiguration);
17022            changes = newConfig.updateFrom(values);
17023            if (changes != 0) {
17024                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17025                        "Updating configuration to: " + values);
17026
17027                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17028
17029                if (!initLocale && values.locale != null && values.userSetLocale) {
17030                    final String languageTag = values.locale.toLanguageTag();
17031                    SystemProperties.set("persist.sys.locale", languageTag);
17032                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17033                            values.locale));
17034                }
17035
17036                mConfigurationSeq++;
17037                if (mConfigurationSeq <= 0) {
17038                    mConfigurationSeq = 1;
17039                }
17040                newConfig.seq = mConfigurationSeq;
17041                mConfiguration = newConfig;
17042                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17043                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17044                //mUsageStatsService.noteStartConfig(newConfig);
17045
17046                final Configuration configCopy = new Configuration(mConfiguration);
17047
17048                // TODO: If our config changes, should we auto dismiss any currently
17049                // showing dialogs?
17050                mShowDialogs = shouldShowDialogs(newConfig);
17051
17052                AttributeCache ac = AttributeCache.instance();
17053                if (ac != null) {
17054                    ac.updateConfiguration(configCopy);
17055                }
17056
17057                // Make sure all resources in our process are updated
17058                // right now, so that anyone who is going to retrieve
17059                // resource values after we return will be sure to get
17060                // the new ones.  This is especially important during
17061                // boot, where the first config change needs to guarantee
17062                // all resources have that config before following boot
17063                // code is executed.
17064                mSystemThread.applyConfigurationToResources(configCopy);
17065
17066                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17067                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17068                    msg.obj = new Configuration(configCopy);
17069                    mHandler.sendMessage(msg);
17070                }
17071
17072                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17073                    ProcessRecord app = mLruProcesses.get(i);
17074                    try {
17075                        if (app.thread != null) {
17076                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17077                                    + app.processName + " new config " + mConfiguration);
17078                            app.thread.scheduleConfigurationChanged(configCopy);
17079                        }
17080                    } catch (Exception e) {
17081                    }
17082                }
17083                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17084                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17085                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17086                        | Intent.FLAG_RECEIVER_FOREGROUND);
17087                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17088                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
17089                        Process.SYSTEM_UID, UserHandle.USER_ALL);
17090                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17091                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17092                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17093                    if (!mProcessesReady) {
17094                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17095                    }
17096                    broadcastIntentLocked(null, null, intent,
17097                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17098                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17099                }
17100            }
17101        }
17102
17103        boolean kept = true;
17104        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17105        // mainStack is null during startup.
17106        if (mainStack != null) {
17107            if (changes != 0 && starting == null) {
17108                // If the configuration changed, and the caller is not already
17109                // in the process of starting an activity, then find the top
17110                // activity to check if its configuration needs to change.
17111                starting = mainStack.topRunningActivityLocked(null);
17112            }
17113
17114            if (starting != null) {
17115                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17116                // And we need to make sure at this point that all other activities
17117                // are made visible with the correct configuration.
17118                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17119            }
17120        }
17121
17122        if (values != null && mWindowManager != null) {
17123            mWindowManager.setNewConfiguration(mConfiguration);
17124        }
17125
17126        return kept;
17127    }
17128
17129    /**
17130     * Decide based on the configuration whether we should shouw the ANR,
17131     * crash, etc dialogs.  The idea is that if there is no affordnace to
17132     * press the on-screen buttons, we shouldn't show the dialog.
17133     *
17134     * A thought: SystemUI might also want to get told about this, the Power
17135     * dialog / global actions also might want different behaviors.
17136     */
17137    private static final boolean shouldShowDialogs(Configuration config) {
17138        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17139                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17140                && config.navigation == Configuration.NAVIGATION_NONAV);
17141    }
17142
17143    @Override
17144    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17145        synchronized (this) {
17146            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17147            if (srec != null) {
17148                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17149            }
17150        }
17151        return false;
17152    }
17153
17154    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17155            Intent resultData) {
17156
17157        synchronized (this) {
17158            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17159            if (r != null) {
17160                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17161            }
17162            return false;
17163        }
17164    }
17165
17166    public int getLaunchedFromUid(IBinder activityToken) {
17167        ActivityRecord srec;
17168        synchronized (this) {
17169            srec = ActivityRecord.forTokenLocked(activityToken);
17170        }
17171        if (srec == null) {
17172            return -1;
17173        }
17174        return srec.launchedFromUid;
17175    }
17176
17177    public String getLaunchedFromPackage(IBinder activityToken) {
17178        ActivityRecord srec;
17179        synchronized (this) {
17180            srec = ActivityRecord.forTokenLocked(activityToken);
17181        }
17182        if (srec == null) {
17183            return null;
17184        }
17185        return srec.launchedFromPackage;
17186    }
17187
17188    // =========================================================
17189    // LIFETIME MANAGEMENT
17190    // =========================================================
17191
17192    // Returns which broadcast queue the app is the current [or imminent] receiver
17193    // on, or 'null' if the app is not an active broadcast recipient.
17194    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17195        BroadcastRecord r = app.curReceiver;
17196        if (r != null) {
17197            return r.queue;
17198        }
17199
17200        // It's not the current receiver, but it might be starting up to become one
17201        synchronized (this) {
17202            for (BroadcastQueue queue : mBroadcastQueues) {
17203                r = queue.mPendingBroadcast;
17204                if (r != null && r.curApp == app) {
17205                    // found it; report which queue it's in
17206                    return queue;
17207                }
17208            }
17209        }
17210
17211        return null;
17212    }
17213
17214    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17215            ComponentName targetComponent, String targetProcess) {
17216        if (!mTrackingAssociations) {
17217            return null;
17218        }
17219        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17220                = mAssociations.get(targetUid);
17221        if (components == null) {
17222            components = new ArrayMap<>();
17223            mAssociations.put(targetUid, components);
17224        }
17225        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17226        if (sourceUids == null) {
17227            sourceUids = new SparseArray<>();
17228            components.put(targetComponent, sourceUids);
17229        }
17230        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17231        if (sourceProcesses == null) {
17232            sourceProcesses = new ArrayMap<>();
17233            sourceUids.put(sourceUid, sourceProcesses);
17234        }
17235        Association ass = sourceProcesses.get(sourceProcess);
17236        if (ass == null) {
17237            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17238                    targetProcess);
17239            sourceProcesses.put(sourceProcess, ass);
17240        }
17241        ass.mCount++;
17242        ass.mNesting++;
17243        if (ass.mNesting == 1) {
17244            ass.mStartTime = SystemClock.uptimeMillis();
17245        }
17246        return ass;
17247    }
17248
17249    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17250            ComponentName targetComponent) {
17251        if (!mTrackingAssociations) {
17252            return;
17253        }
17254        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17255                = mAssociations.get(targetUid);
17256        if (components == null) {
17257            return;
17258        }
17259        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17260        if (sourceUids == null) {
17261            return;
17262        }
17263        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17264        if (sourceProcesses == null) {
17265            return;
17266        }
17267        Association ass = sourceProcesses.get(sourceProcess);
17268        if (ass == null || ass.mNesting <= 0) {
17269            return;
17270        }
17271        ass.mNesting--;
17272        if (ass.mNesting == 0) {
17273            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17274        }
17275    }
17276
17277    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17278            boolean doingAll, long now) {
17279        if (mAdjSeq == app.adjSeq) {
17280            // This adjustment has already been computed.
17281            return app.curRawAdj;
17282        }
17283
17284        if (app.thread == null) {
17285            app.adjSeq = mAdjSeq;
17286            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17287            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17288            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17289        }
17290
17291        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17292        app.adjSource = null;
17293        app.adjTarget = null;
17294        app.empty = false;
17295        app.cached = false;
17296
17297        final int activitiesSize = app.activities.size();
17298
17299        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17300            // The max adjustment doesn't allow this app to be anything
17301            // below foreground, so it is not worth doing work for it.
17302            app.adjType = "fixed";
17303            app.adjSeq = mAdjSeq;
17304            app.curRawAdj = app.maxAdj;
17305            app.foregroundActivities = false;
17306            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17307            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17308            // System processes can do UI, and when they do we want to have
17309            // them trim their memory after the user leaves the UI.  To
17310            // facilitate this, here we need to determine whether or not it
17311            // is currently showing UI.
17312            app.systemNoUi = true;
17313            if (app == TOP_APP) {
17314                app.systemNoUi = false;
17315            } else if (activitiesSize > 0) {
17316                for (int j = 0; j < activitiesSize; j++) {
17317                    final ActivityRecord r = app.activities.get(j);
17318                    if (r.visible) {
17319                        app.systemNoUi = false;
17320                    }
17321                }
17322            }
17323            if (!app.systemNoUi) {
17324                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17325            }
17326            return (app.curAdj=app.maxAdj);
17327        }
17328
17329        app.systemNoUi = false;
17330
17331        final int PROCESS_STATE_TOP = mTopProcessState;
17332
17333        // Determine the importance of the process, starting with most
17334        // important to least, and assign an appropriate OOM adjustment.
17335        int adj;
17336        int schedGroup;
17337        int procState;
17338        boolean foregroundActivities = false;
17339        BroadcastQueue queue;
17340        if (app == TOP_APP) {
17341            // The last app on the list is the foreground app.
17342            adj = ProcessList.FOREGROUND_APP_ADJ;
17343            schedGroup = Process.THREAD_GROUP_DEFAULT;
17344            app.adjType = "top-activity";
17345            foregroundActivities = true;
17346            procState = PROCESS_STATE_TOP;
17347        } else if (app.instrumentationClass != null) {
17348            // Don't want to kill running instrumentation.
17349            adj = ProcessList.FOREGROUND_APP_ADJ;
17350            schedGroup = Process.THREAD_GROUP_DEFAULT;
17351            app.adjType = "instrumentation";
17352            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17353        } else if ((queue = isReceivingBroadcast(app)) != null) {
17354            // An app that is currently receiving a broadcast also
17355            // counts as being in the foreground for OOM killer purposes.
17356            // It's placed in a sched group based on the nature of the
17357            // broadcast as reflected by which queue it's active in.
17358            adj = ProcessList.FOREGROUND_APP_ADJ;
17359            schedGroup = (queue == mFgBroadcastQueue)
17360                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17361            app.adjType = "broadcast";
17362            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17363        } else if (app.executingServices.size() > 0) {
17364            // An app that is currently executing a service callback also
17365            // counts as being in the foreground.
17366            adj = ProcessList.FOREGROUND_APP_ADJ;
17367            schedGroup = app.execServicesFg ?
17368                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17369            app.adjType = "exec-service";
17370            procState = ActivityManager.PROCESS_STATE_SERVICE;
17371            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17372        } else {
17373            // As far as we know the process is empty.  We may change our mind later.
17374            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17375            // At this point we don't actually know the adjustment.  Use the cached adj
17376            // value that the caller wants us to.
17377            adj = cachedAdj;
17378            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17379            app.cached = true;
17380            app.empty = true;
17381            app.adjType = "cch-empty";
17382        }
17383
17384        // Examine all activities if not already foreground.
17385        if (!foregroundActivities && activitiesSize > 0) {
17386            for (int j = 0; j < activitiesSize; j++) {
17387                final ActivityRecord r = app.activities.get(j);
17388                if (r.app != app) {
17389                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17390                            + app + "?!?");
17391                    continue;
17392                }
17393                if (r.visible) {
17394                    // App has a visible activity; only upgrade adjustment.
17395                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17396                        adj = ProcessList.VISIBLE_APP_ADJ;
17397                        app.adjType = "visible";
17398                    }
17399                    if (procState > PROCESS_STATE_TOP) {
17400                        procState = PROCESS_STATE_TOP;
17401                    }
17402                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17403                    app.cached = false;
17404                    app.empty = false;
17405                    foregroundActivities = true;
17406                    break;
17407                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17408                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17409                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17410                        app.adjType = "pausing";
17411                    }
17412                    if (procState > PROCESS_STATE_TOP) {
17413                        procState = PROCESS_STATE_TOP;
17414                    }
17415                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17416                    app.cached = false;
17417                    app.empty = false;
17418                    foregroundActivities = true;
17419                } else if (r.state == ActivityState.STOPPING) {
17420                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17421                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17422                        app.adjType = "stopping";
17423                    }
17424                    // For the process state, we will at this point consider the
17425                    // process to be cached.  It will be cached either as an activity
17426                    // or empty depending on whether the activity is finishing.  We do
17427                    // this so that we can treat the process as cached for purposes of
17428                    // memory trimming (determing current memory level, trim command to
17429                    // send to process) since there can be an arbitrary number of stopping
17430                    // processes and they should soon all go into the cached state.
17431                    if (!r.finishing) {
17432                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17433                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17434                        }
17435                    }
17436                    app.cached = false;
17437                    app.empty = false;
17438                    foregroundActivities = true;
17439                } else {
17440                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17441                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17442                        app.adjType = "cch-act";
17443                    }
17444                }
17445            }
17446        }
17447
17448        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17449            if (app.foregroundServices) {
17450                // The user is aware of this app, so make it visible.
17451                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17452                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17453                app.cached = false;
17454                app.adjType = "fg-service";
17455                schedGroup = Process.THREAD_GROUP_DEFAULT;
17456            } else if (app.forcingToForeground != null) {
17457                // The user is aware of this app, so make it visible.
17458                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17459                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17460                app.cached = false;
17461                app.adjType = "force-fg";
17462                app.adjSource = app.forcingToForeground;
17463                schedGroup = Process.THREAD_GROUP_DEFAULT;
17464            }
17465        }
17466
17467        if (app == mHeavyWeightProcess) {
17468            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17469                // We don't want to kill the current heavy-weight process.
17470                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17471                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17472                app.cached = false;
17473                app.adjType = "heavy";
17474            }
17475            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17476                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17477            }
17478        }
17479
17480        if (app == mHomeProcess) {
17481            if (adj > ProcessList.HOME_APP_ADJ) {
17482                // This process is hosting what we currently consider to be the
17483                // home app, so we don't want to let it go into the background.
17484                adj = ProcessList.HOME_APP_ADJ;
17485                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17486                app.cached = false;
17487                app.adjType = "home";
17488            }
17489            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17490                procState = ActivityManager.PROCESS_STATE_HOME;
17491            }
17492        }
17493
17494        if (app == mPreviousProcess && app.activities.size() > 0) {
17495            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17496                // This was the previous process that showed UI to the user.
17497                // We want to try to keep it around more aggressively, to give
17498                // a good experience around switching between two apps.
17499                adj = ProcessList.PREVIOUS_APP_ADJ;
17500                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17501                app.cached = false;
17502                app.adjType = "previous";
17503            }
17504            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17505                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17506            }
17507        }
17508
17509        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17510                + " reason=" + app.adjType);
17511
17512        // By default, we use the computed adjustment.  It may be changed if
17513        // there are applications dependent on our services or providers, but
17514        // this gives us a baseline and makes sure we don't get into an
17515        // infinite recursion.
17516        app.adjSeq = mAdjSeq;
17517        app.curRawAdj = adj;
17518        app.hasStartedServices = false;
17519
17520        if (mBackupTarget != null && app == mBackupTarget.app) {
17521            // If possible we want to avoid killing apps while they're being backed up
17522            if (adj > ProcessList.BACKUP_APP_ADJ) {
17523                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17524                adj = ProcessList.BACKUP_APP_ADJ;
17525                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17526                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17527                }
17528                app.adjType = "backup";
17529                app.cached = false;
17530            }
17531            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17532                procState = ActivityManager.PROCESS_STATE_BACKUP;
17533            }
17534        }
17535
17536        boolean mayBeTop = false;
17537
17538        for (int is = app.services.size()-1;
17539                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17540                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17541                        || procState > ActivityManager.PROCESS_STATE_TOP);
17542                is--) {
17543            ServiceRecord s = app.services.valueAt(is);
17544            if (s.startRequested) {
17545                app.hasStartedServices = true;
17546                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17547                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17548                }
17549                if (app.hasShownUi && app != mHomeProcess) {
17550                    // If this process has shown some UI, let it immediately
17551                    // go to the LRU list because it may be pretty heavy with
17552                    // UI stuff.  We'll tag it with a label just to help
17553                    // debug and understand what is going on.
17554                    if (adj > ProcessList.SERVICE_ADJ) {
17555                        app.adjType = "cch-started-ui-services";
17556                    }
17557                } else {
17558                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17559                        // This service has seen some activity within
17560                        // recent memory, so we will keep its process ahead
17561                        // of the background processes.
17562                        if (adj > ProcessList.SERVICE_ADJ) {
17563                            adj = ProcessList.SERVICE_ADJ;
17564                            app.adjType = "started-services";
17565                            app.cached = false;
17566                        }
17567                    }
17568                    // If we have let the service slide into the background
17569                    // state, still have some text describing what it is doing
17570                    // even though the service no longer has an impact.
17571                    if (adj > ProcessList.SERVICE_ADJ) {
17572                        app.adjType = "cch-started-services";
17573                    }
17574                }
17575            }
17576            for (int conni = s.connections.size()-1;
17577                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17578                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17579                            || procState > ActivityManager.PROCESS_STATE_TOP);
17580                    conni--) {
17581                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17582                for (int i = 0;
17583                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17584                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17585                                || procState > ActivityManager.PROCESS_STATE_TOP);
17586                        i++) {
17587                    // XXX should compute this based on the max of
17588                    // all connected clients.
17589                    ConnectionRecord cr = clist.get(i);
17590                    if (cr.binding.client == app) {
17591                        // Binding to ourself is not interesting.
17592                        continue;
17593                    }
17594                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17595                        ProcessRecord client = cr.binding.client;
17596                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17597                                TOP_APP, doingAll, now);
17598                        int clientProcState = client.curProcState;
17599                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17600                            // If the other app is cached for any reason, for purposes here
17601                            // we are going to consider it empty.  The specific cached state
17602                            // doesn't propagate except under certain conditions.
17603                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17604                        }
17605                        String adjType = null;
17606                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17607                            // Not doing bind OOM management, so treat
17608                            // this guy more like a started service.
17609                            if (app.hasShownUi && app != mHomeProcess) {
17610                                // If this process has shown some UI, let it immediately
17611                                // go to the LRU list because it may be pretty heavy with
17612                                // UI stuff.  We'll tag it with a label just to help
17613                                // debug and understand what is going on.
17614                                if (adj > clientAdj) {
17615                                    adjType = "cch-bound-ui-services";
17616                                }
17617                                app.cached = false;
17618                                clientAdj = adj;
17619                                clientProcState = procState;
17620                            } else {
17621                                if (now >= (s.lastActivity
17622                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17623                                    // This service has not seen activity within
17624                                    // recent memory, so allow it to drop to the
17625                                    // LRU list if there is no other reason to keep
17626                                    // it around.  We'll also tag it with a label just
17627                                    // to help debug and undertand what is going on.
17628                                    if (adj > clientAdj) {
17629                                        adjType = "cch-bound-services";
17630                                    }
17631                                    clientAdj = adj;
17632                                }
17633                            }
17634                        }
17635                        if (adj > clientAdj) {
17636                            // If this process has recently shown UI, and
17637                            // the process that is binding to it is less
17638                            // important than being visible, then we don't
17639                            // care about the binding as much as we care
17640                            // about letting this process get into the LRU
17641                            // list to be killed and restarted if needed for
17642                            // memory.
17643                            if (app.hasShownUi && app != mHomeProcess
17644                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17645                                adjType = "cch-bound-ui-services";
17646                            } else {
17647                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17648                                        |Context.BIND_IMPORTANT)) != 0) {
17649                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17650                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17651                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17652                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17653                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17654                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17655                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17656                                    adj = clientAdj;
17657                                } else {
17658                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17659                                        adj = ProcessList.VISIBLE_APP_ADJ;
17660                                    }
17661                                }
17662                                if (!client.cached) {
17663                                    app.cached = false;
17664                                }
17665                                adjType = "service";
17666                            }
17667                        }
17668                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17669                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17670                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17671                            }
17672                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17673                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17674                                    // Special handling of clients who are in the top state.
17675                                    // We *may* want to consider this process to be in the
17676                                    // top state as well, but only if there is not another
17677                                    // reason for it to be running.  Being on the top is a
17678                                    // special state, meaning you are specifically running
17679                                    // for the current top app.  If the process is already
17680                                    // running in the background for some other reason, it
17681                                    // is more important to continue considering it to be
17682                                    // in the background state.
17683                                    mayBeTop = true;
17684                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17685                                } else {
17686                                    // Special handling for above-top states (persistent
17687                                    // processes).  These should not bring the current process
17688                                    // into the top state, since they are not on top.  Instead
17689                                    // give them the best state after that.
17690                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
17691                                        clientProcState =
17692                                                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17693                                    } else if (mWakefulness
17694                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
17695                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
17696                                                    != 0) {
17697                                        clientProcState =
17698                                                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17699                                    } else {
17700                                        clientProcState =
17701                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17702                                    }
17703                                }
17704                            }
17705                        } else {
17706                            if (clientProcState <
17707                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17708                                clientProcState =
17709                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17710                            }
17711                        }
17712                        if (procState > clientProcState) {
17713                            procState = clientProcState;
17714                        }
17715                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17716                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17717                            app.pendingUiClean = true;
17718                        }
17719                        if (adjType != null) {
17720                            app.adjType = adjType;
17721                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17722                                    .REASON_SERVICE_IN_USE;
17723                            app.adjSource = cr.binding.client;
17724                            app.adjSourceProcState = clientProcState;
17725                            app.adjTarget = s.name;
17726                        }
17727                    }
17728                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17729                        app.treatLikeActivity = true;
17730                    }
17731                    final ActivityRecord a = cr.activity;
17732                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17733                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17734                                (a.visible || a.state == ActivityState.RESUMED
17735                                 || a.state == ActivityState.PAUSING)) {
17736                            adj = ProcessList.FOREGROUND_APP_ADJ;
17737                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17738                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17739                            }
17740                            app.cached = false;
17741                            app.adjType = "service";
17742                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17743                                    .REASON_SERVICE_IN_USE;
17744                            app.adjSource = a;
17745                            app.adjSourceProcState = procState;
17746                            app.adjTarget = s.name;
17747                        }
17748                    }
17749                }
17750            }
17751        }
17752
17753        for (int provi = app.pubProviders.size()-1;
17754                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17755                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17756                        || procState > ActivityManager.PROCESS_STATE_TOP);
17757                provi--) {
17758            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17759            for (int i = cpr.connections.size()-1;
17760                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17761                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17762                            || procState > ActivityManager.PROCESS_STATE_TOP);
17763                    i--) {
17764                ContentProviderConnection conn = cpr.connections.get(i);
17765                ProcessRecord client = conn.client;
17766                if (client == app) {
17767                    // Being our own client is not interesting.
17768                    continue;
17769                }
17770                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17771                int clientProcState = client.curProcState;
17772                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17773                    // If the other app is cached for any reason, for purposes here
17774                    // we are going to consider it empty.
17775                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17776                }
17777                if (adj > clientAdj) {
17778                    if (app.hasShownUi && app != mHomeProcess
17779                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17780                        app.adjType = "cch-ui-provider";
17781                    } else {
17782                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17783                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17784                        app.adjType = "provider";
17785                    }
17786                    app.cached &= client.cached;
17787                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17788                            .REASON_PROVIDER_IN_USE;
17789                    app.adjSource = client;
17790                    app.adjSourceProcState = clientProcState;
17791                    app.adjTarget = cpr.name;
17792                }
17793                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17794                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17795                        // Special handling of clients who are in the top state.
17796                        // We *may* want to consider this process to be in the
17797                        // top state as well, but only if there is not another
17798                        // reason for it to be running.  Being on the top is a
17799                        // special state, meaning you are specifically running
17800                        // for the current top app.  If the process is already
17801                        // running in the background for some other reason, it
17802                        // is more important to continue considering it to be
17803                        // in the background state.
17804                        mayBeTop = true;
17805                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17806                    } else {
17807                        // Special handling for above-top states (persistent
17808                        // processes).  These should not bring the current process
17809                        // into the top state, since they are not on top.  Instead
17810                        // give them the best state after that.
17811                        clientProcState =
17812                                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17813                    }
17814                }
17815                if (procState > clientProcState) {
17816                    procState = clientProcState;
17817                }
17818                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17819                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17820                }
17821            }
17822            // If the provider has external (non-framework) process
17823            // dependencies, ensure that its adjustment is at least
17824            // FOREGROUND_APP_ADJ.
17825            if (cpr.hasExternalProcessHandles()) {
17826                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17827                    adj = ProcessList.FOREGROUND_APP_ADJ;
17828                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17829                    app.cached = false;
17830                    app.adjType = "provider";
17831                    app.adjTarget = cpr.name;
17832                }
17833                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17834                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17835                }
17836            }
17837        }
17838
17839        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17840            // A client of one of our services or providers is in the top state.  We
17841            // *may* want to be in the top state, but not if we are already running in
17842            // the background for some other reason.  For the decision here, we are going
17843            // to pick out a few specific states that we want to remain in when a client
17844            // is top (states that tend to be longer-term) and otherwise allow it to go
17845            // to the top state.
17846            switch (procState) {
17847                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17848                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17849                case ActivityManager.PROCESS_STATE_SERVICE:
17850                    // These all are longer-term states, so pull them up to the top
17851                    // of the background states, but not all the way to the top state.
17852                    procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17853                    break;
17854                default:
17855                    // Otherwise, top is a better choice, so take it.
17856                    procState = ActivityManager.PROCESS_STATE_TOP;
17857                    break;
17858            }
17859        }
17860
17861        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17862            if (app.hasClientActivities) {
17863                // This is a cached process, but with client activities.  Mark it so.
17864                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17865                app.adjType = "cch-client-act";
17866            } else if (app.treatLikeActivity) {
17867                // This is a cached process, but somebody wants us to treat it like it has
17868                // an activity, okay!
17869                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17870                app.adjType = "cch-as-act";
17871            }
17872        }
17873
17874        if (adj == ProcessList.SERVICE_ADJ) {
17875            if (doingAll) {
17876                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17877                mNewNumServiceProcs++;
17878                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17879                if (!app.serviceb) {
17880                    // This service isn't far enough down on the LRU list to
17881                    // normally be a B service, but if we are low on RAM and it
17882                    // is large we want to force it down since we would prefer to
17883                    // keep launcher over it.
17884                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17885                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17886                        app.serviceHighRam = true;
17887                        app.serviceb = true;
17888                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17889                    } else {
17890                        mNewNumAServiceProcs++;
17891                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17892                    }
17893                } else {
17894                    app.serviceHighRam = false;
17895                }
17896            }
17897            if (app.serviceb) {
17898                adj = ProcessList.SERVICE_B_ADJ;
17899            }
17900        }
17901
17902        app.curRawAdj = adj;
17903
17904        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17905        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17906        if (adj > app.maxAdj) {
17907            adj = app.maxAdj;
17908            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17909                schedGroup = Process.THREAD_GROUP_DEFAULT;
17910            }
17911        }
17912
17913        // Do final modification to adj.  Everything we do between here and applying
17914        // the final setAdj must be done in this function, because we will also use
17915        // it when computing the final cached adj later.  Note that we don't need to
17916        // worry about this for max adj above, since max adj will always be used to
17917        // keep it out of the cached vaues.
17918        app.curAdj = app.modifyRawOomAdj(adj);
17919        app.curSchedGroup = schedGroup;
17920        app.curProcState = procState;
17921        app.foregroundActivities = foregroundActivities;
17922
17923        return app.curRawAdj;
17924    }
17925
17926    /**
17927     * Record new PSS sample for a process.
17928     */
17929    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
17930        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
17931        proc.lastPssTime = now;
17932        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17933        if (DEBUG_PSS) Slog.d(TAG_PSS,
17934                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
17935                + " state=" + ProcessList.makeProcStateString(procState));
17936        if (proc.initialIdlePss == 0) {
17937            proc.initialIdlePss = pss;
17938        }
17939        proc.lastPss = pss;
17940        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17941            proc.lastCachedPss = pss;
17942        }
17943
17944        final SparseArray<Pair<Long, String>> watchUids
17945                = mMemWatchProcesses.getMap().get(proc.processName);
17946        Long check = null;
17947        if (watchUids != null) {
17948            Pair<Long, String> val = watchUids.get(proc.uid);
17949            if (val == null) {
17950                val = watchUids.get(0);
17951            }
17952            if (val != null) {
17953                check = val.first;
17954            }
17955        }
17956        if (check != null) {
17957            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
17958                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17959                if (!isDebuggable) {
17960                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
17961                        isDebuggable = true;
17962                    }
17963                }
17964                if (isDebuggable) {
17965                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
17966                    final ProcessRecord myProc = proc;
17967                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
17968                    mMemWatchDumpProcName = proc.processName;
17969                    mMemWatchDumpFile = heapdumpFile.toString();
17970                    mMemWatchDumpPid = proc.pid;
17971                    mMemWatchDumpUid = proc.uid;
17972                    BackgroundThread.getHandler().post(new Runnable() {
17973                        @Override
17974                        public void run() {
17975                            revokeUriPermission(ActivityThread.currentActivityThread()
17976                                            .getApplicationThread(),
17977                                    DumpHeapActivity.JAVA_URI,
17978                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
17979                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
17980                                    UserHandle.myUserId());
17981                            ParcelFileDescriptor fd = null;
17982                            try {
17983                                heapdumpFile.delete();
17984                                fd = ParcelFileDescriptor.open(heapdumpFile,
17985                                        ParcelFileDescriptor.MODE_CREATE |
17986                                                ParcelFileDescriptor.MODE_TRUNCATE |
17987                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
17988                                                ParcelFileDescriptor.MODE_APPEND);
17989                                IApplicationThread thread = myProc.thread;
17990                                if (thread != null) {
17991                                    try {
17992                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
17993                                                "Requesting dump heap from "
17994                                                + myProc + " to " + heapdumpFile);
17995                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
17996                                    } catch (RemoteException e) {
17997                                    }
17998                                }
17999                            } catch (FileNotFoundException e) {
18000                                e.printStackTrace();
18001                            } finally {
18002                                if (fd != null) {
18003                                    try {
18004                                        fd.close();
18005                                    } catch (IOException e) {
18006                                    }
18007                                }
18008                            }
18009                        }
18010                    });
18011                } else {
18012                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18013                            + ", but debugging not enabled");
18014                }
18015            }
18016        }
18017    }
18018
18019    /**
18020     * Schedule PSS collection of a process.
18021     */
18022    void requestPssLocked(ProcessRecord proc, int procState) {
18023        if (mPendingPssProcesses.contains(proc)) {
18024            return;
18025        }
18026        if (mPendingPssProcesses.size() == 0) {
18027            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18028        }
18029        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18030        proc.pssProcState = procState;
18031        mPendingPssProcesses.add(proc);
18032    }
18033
18034    /**
18035     * Schedule PSS collection of all processes.
18036     */
18037    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18038        if (!always) {
18039            if (now < (mLastFullPssTime +
18040                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18041                return;
18042            }
18043        }
18044        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18045        mLastFullPssTime = now;
18046        mFullPssPending = true;
18047        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18048        mPendingPssProcesses.clear();
18049        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18050            ProcessRecord app = mLruProcesses.get(i);
18051            if (app.thread == null
18052                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18053                continue;
18054            }
18055            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18056                app.pssProcState = app.setProcState;
18057                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18058                        mTestPssMode, isSleeping(), now);
18059                mPendingPssProcesses.add(app);
18060            }
18061        }
18062        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18063    }
18064
18065    public void setTestPssMode(boolean enabled) {
18066        synchronized (this) {
18067            mTestPssMode = enabled;
18068            if (enabled) {
18069                // Whenever we enable the mode, we want to take a snapshot all of current
18070                // process mem use.
18071                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18072            }
18073        }
18074    }
18075
18076    /**
18077     * Ask a given process to GC right now.
18078     */
18079    final void performAppGcLocked(ProcessRecord app) {
18080        try {
18081            app.lastRequestedGc = SystemClock.uptimeMillis();
18082            if (app.thread != null) {
18083                if (app.reportLowMemory) {
18084                    app.reportLowMemory = false;
18085                    app.thread.scheduleLowMemory();
18086                } else {
18087                    app.thread.processInBackground();
18088                }
18089            }
18090        } catch (Exception e) {
18091            // whatever.
18092        }
18093    }
18094
18095    /**
18096     * Returns true if things are idle enough to perform GCs.
18097     */
18098    private final boolean canGcNowLocked() {
18099        boolean processingBroadcasts = false;
18100        for (BroadcastQueue q : mBroadcastQueues) {
18101            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18102                processingBroadcasts = true;
18103            }
18104        }
18105        return !processingBroadcasts
18106                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18107    }
18108
18109    /**
18110     * Perform GCs on all processes that are waiting for it, but only
18111     * if things are idle.
18112     */
18113    final void performAppGcsLocked() {
18114        final int N = mProcessesToGc.size();
18115        if (N <= 0) {
18116            return;
18117        }
18118        if (canGcNowLocked()) {
18119            while (mProcessesToGc.size() > 0) {
18120                ProcessRecord proc = mProcessesToGc.remove(0);
18121                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18122                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18123                            <= SystemClock.uptimeMillis()) {
18124                        // To avoid spamming the system, we will GC processes one
18125                        // at a time, waiting a few seconds between each.
18126                        performAppGcLocked(proc);
18127                        scheduleAppGcsLocked();
18128                        return;
18129                    } else {
18130                        // It hasn't been long enough since we last GCed this
18131                        // process...  put it in the list to wait for its time.
18132                        addProcessToGcListLocked(proc);
18133                        break;
18134                    }
18135                }
18136            }
18137
18138            scheduleAppGcsLocked();
18139        }
18140    }
18141
18142    /**
18143     * If all looks good, perform GCs on all processes waiting for them.
18144     */
18145    final void performAppGcsIfAppropriateLocked() {
18146        if (canGcNowLocked()) {
18147            performAppGcsLocked();
18148            return;
18149        }
18150        // Still not idle, wait some more.
18151        scheduleAppGcsLocked();
18152    }
18153
18154    /**
18155     * Schedule the execution of all pending app GCs.
18156     */
18157    final void scheduleAppGcsLocked() {
18158        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18159
18160        if (mProcessesToGc.size() > 0) {
18161            // Schedule a GC for the time to the next process.
18162            ProcessRecord proc = mProcessesToGc.get(0);
18163            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18164
18165            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18166            long now = SystemClock.uptimeMillis();
18167            if (when < (now+GC_TIMEOUT)) {
18168                when = now + GC_TIMEOUT;
18169            }
18170            mHandler.sendMessageAtTime(msg, when);
18171        }
18172    }
18173
18174    /**
18175     * Add a process to the array of processes waiting to be GCed.  Keeps the
18176     * list in sorted order by the last GC time.  The process can't already be
18177     * on the list.
18178     */
18179    final void addProcessToGcListLocked(ProcessRecord proc) {
18180        boolean added = false;
18181        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18182            if (mProcessesToGc.get(i).lastRequestedGc <
18183                    proc.lastRequestedGc) {
18184                added = true;
18185                mProcessesToGc.add(i+1, proc);
18186                break;
18187            }
18188        }
18189        if (!added) {
18190            mProcessesToGc.add(0, proc);
18191        }
18192    }
18193
18194    /**
18195     * Set up to ask a process to GC itself.  This will either do it
18196     * immediately, or put it on the list of processes to gc the next
18197     * time things are idle.
18198     */
18199    final void scheduleAppGcLocked(ProcessRecord app) {
18200        long now = SystemClock.uptimeMillis();
18201        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18202            return;
18203        }
18204        if (!mProcessesToGc.contains(app)) {
18205            addProcessToGcListLocked(app);
18206            scheduleAppGcsLocked();
18207        }
18208    }
18209
18210    final void checkExcessivePowerUsageLocked(boolean doKills) {
18211        updateCpuStatsNow();
18212
18213        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18214        boolean doWakeKills = doKills;
18215        boolean doCpuKills = doKills;
18216        if (mLastPowerCheckRealtime == 0) {
18217            doWakeKills = false;
18218        }
18219        if (mLastPowerCheckUptime == 0) {
18220            doCpuKills = false;
18221        }
18222        if (stats.isScreenOn()) {
18223            doWakeKills = false;
18224        }
18225        final long curRealtime = SystemClock.elapsedRealtime();
18226        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18227        final long curUptime = SystemClock.uptimeMillis();
18228        final long uptimeSince = curUptime - mLastPowerCheckUptime;
18229        mLastPowerCheckRealtime = curRealtime;
18230        mLastPowerCheckUptime = curUptime;
18231        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18232            doWakeKills = false;
18233        }
18234        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18235            doCpuKills = false;
18236        }
18237        int i = mLruProcesses.size();
18238        while (i > 0) {
18239            i--;
18240            ProcessRecord app = mLruProcesses.get(i);
18241            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18242                long wtime;
18243                synchronized (stats) {
18244                    wtime = stats.getProcessWakeTime(app.info.uid,
18245                            app.pid, curRealtime);
18246                }
18247                long wtimeUsed = wtime - app.lastWakeTime;
18248                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18249                if (DEBUG_POWER) {
18250                    StringBuilder sb = new StringBuilder(128);
18251                    sb.append("Wake for ");
18252                    app.toShortString(sb);
18253                    sb.append(": over ");
18254                    TimeUtils.formatDuration(realtimeSince, sb);
18255                    sb.append(" used ");
18256                    TimeUtils.formatDuration(wtimeUsed, sb);
18257                    sb.append(" (");
18258                    sb.append((wtimeUsed*100)/realtimeSince);
18259                    sb.append("%)");
18260                    Slog.i(TAG_POWER, sb.toString());
18261                    sb.setLength(0);
18262                    sb.append("CPU for ");
18263                    app.toShortString(sb);
18264                    sb.append(": over ");
18265                    TimeUtils.formatDuration(uptimeSince, sb);
18266                    sb.append(" used ");
18267                    TimeUtils.formatDuration(cputimeUsed, sb);
18268                    sb.append(" (");
18269                    sb.append((cputimeUsed*100)/uptimeSince);
18270                    sb.append("%)");
18271                    Slog.i(TAG_POWER, sb.toString());
18272                }
18273                // If a process has held a wake lock for more
18274                // than 50% of the time during this period,
18275                // that sounds bad.  Kill!
18276                if (doWakeKills && realtimeSince > 0
18277                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
18278                    synchronized (stats) {
18279                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18280                                realtimeSince, wtimeUsed);
18281                    }
18282                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18283                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18284                } else if (doCpuKills && uptimeSince > 0
18285                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
18286                    synchronized (stats) {
18287                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18288                                uptimeSince, cputimeUsed);
18289                    }
18290                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18291                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18292                } else {
18293                    app.lastWakeTime = wtime;
18294                    app.lastCpuTime = app.curCpuTime;
18295                }
18296            }
18297        }
18298    }
18299
18300    private final boolean applyOomAdjLocked(ProcessRecord app,
18301            ProcessRecord TOP_APP, boolean doingAll, long now) {
18302        boolean success = true;
18303
18304        if (app.curRawAdj != app.setRawAdj) {
18305            app.setRawAdj = app.curRawAdj;
18306        }
18307
18308        int changes = 0;
18309
18310        if (app.curAdj != app.setAdj) {
18311            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18312            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18313                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18314                    + app.adjType);
18315            app.setAdj = app.curAdj;
18316        }
18317
18318        if (app.setSchedGroup != app.curSchedGroup) {
18319            app.setSchedGroup = app.curSchedGroup;
18320            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18321                    "Setting process group of " + app.processName
18322                    + " to " + app.curSchedGroup);
18323            if (app.waitingToKill != null &&
18324                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18325                app.kill(app.waitingToKill, true);
18326                success = false;
18327            } else {
18328                if (true) {
18329                    long oldId = Binder.clearCallingIdentity();
18330                    try {
18331                        Process.setProcessGroup(app.pid, app.curSchedGroup);
18332                    } catch (Exception e) {
18333                        Slog.w(TAG, "Failed setting process group of " + app.pid
18334                                + " to " + app.curSchedGroup);
18335                        e.printStackTrace();
18336                    } finally {
18337                        Binder.restoreCallingIdentity(oldId);
18338                    }
18339                } else {
18340                    if (app.thread != null) {
18341                        try {
18342                            app.thread.setSchedulingGroup(app.curSchedGroup);
18343                        } catch (RemoteException e) {
18344                        }
18345                    }
18346                }
18347                Process.setSwappiness(app.pid,
18348                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18349            }
18350        }
18351        if (app.repForegroundActivities != app.foregroundActivities) {
18352            app.repForegroundActivities = app.foregroundActivities;
18353            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18354        }
18355        if (app.repProcState != app.curProcState) {
18356            app.repProcState = app.curProcState;
18357            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18358            if (app.thread != null) {
18359                try {
18360                    if (false) {
18361                        //RuntimeException h = new RuntimeException("here");
18362                        Slog.i(TAG, "Sending new process state " + app.repProcState
18363                                + " to " + app /*, h*/);
18364                    }
18365                    app.thread.setProcessState(app.repProcState);
18366                } catch (RemoteException e) {
18367                }
18368            }
18369        }
18370        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18371                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18372            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18373                // Experimental code to more aggressively collect pss while
18374                // running test...  the problem is that this tends to collect
18375                // the data right when a process is transitioning between process
18376                // states, which well tend to give noisy data.
18377                long start = SystemClock.uptimeMillis();
18378                long pss = Debug.getPss(app.pid, mTmpLong, null);
18379                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18380                mPendingPssProcesses.remove(app);
18381                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18382                        + " to " + app.curProcState + ": "
18383                        + (SystemClock.uptimeMillis()-start) + "ms");
18384            }
18385            app.lastStateTime = now;
18386            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18387                    mTestPssMode, isSleeping(), now);
18388            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18389                    + ProcessList.makeProcStateString(app.setProcState) + " to "
18390                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18391                    + (app.nextPssTime-now) + ": " + app);
18392        } else {
18393            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18394                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18395                    mTestPssMode)))) {
18396                requestPssLocked(app, app.setProcState);
18397                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18398                        mTestPssMode, isSleeping(), now);
18399            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18400                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18401        }
18402        if (app.setProcState != app.curProcState) {
18403            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18404                    "Proc state change of " + app.processName
18405                    + " to " + app.curProcState);
18406            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18407            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18408            if (setImportant && !curImportant) {
18409                // This app is no longer something we consider important enough to allow to
18410                // use arbitrary amounts of battery power.  Note
18411                // its current wake lock time to later know to kill it if
18412                // it is not behaving well.
18413                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18414                synchronized (stats) {
18415                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18416                            app.pid, SystemClock.elapsedRealtime());
18417                }
18418                app.lastCpuTime = app.curCpuTime;
18419
18420            }
18421            // Inform UsageStats of important process state change
18422            // Must be called before updating setProcState
18423            maybeUpdateUsageStats(app);
18424
18425            app.setProcState = app.curProcState;
18426            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18427                app.notCachedSinceIdle = false;
18428            }
18429            if (!doingAll) {
18430                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18431            } else {
18432                app.procStateChanged = true;
18433            }
18434        }
18435
18436        if (changes != 0) {
18437            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18438                    "Changes in " + app + ": " + changes);
18439            int i = mPendingProcessChanges.size()-1;
18440            ProcessChangeItem item = null;
18441            while (i >= 0) {
18442                item = mPendingProcessChanges.get(i);
18443                if (item.pid == app.pid) {
18444                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18445                            "Re-using existing item: " + item);
18446                    break;
18447                }
18448                i--;
18449            }
18450            if (i < 0) {
18451                // No existing item in pending changes; need a new one.
18452                final int NA = mAvailProcessChanges.size();
18453                if (NA > 0) {
18454                    item = mAvailProcessChanges.remove(NA-1);
18455                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18456                            "Retrieving available item: " + item);
18457                } else {
18458                    item = new ProcessChangeItem();
18459                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18460                            "Allocating new item: " + item);
18461                }
18462                item.changes = 0;
18463                item.pid = app.pid;
18464                item.uid = app.info.uid;
18465                if (mPendingProcessChanges.size() == 0) {
18466                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18467                            "*** Enqueueing dispatch processes changed!");
18468                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18469                }
18470                mPendingProcessChanges.add(item);
18471            }
18472            item.changes |= changes;
18473            item.processState = app.repProcState;
18474            item.foregroundActivities = app.repForegroundActivities;
18475            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18476                    "Item " + Integer.toHexString(System.identityHashCode(item))
18477                    + " " + app.toShortString() + ": changes=" + item.changes
18478                    + " procState=" + item.processState
18479                    + " foreground=" + item.foregroundActivities
18480                    + " type=" + app.adjType + " source=" + app.adjSource
18481                    + " target=" + app.adjTarget);
18482        }
18483
18484        return success;
18485    }
18486
18487    private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18488        if (uidRec.pendingChange == null) {
18489            if (mPendingUidChanges.size() == 0) {
18490                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18491                        "*** Enqueueing dispatch uid changed!");
18492                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED).sendToTarget();
18493            }
18494            final int NA = mAvailUidChanges.size();
18495            if (NA > 0) {
18496                uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18497                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18498                        "Retrieving available item: " + uidRec.pendingChange);
18499            } else {
18500                uidRec.pendingChange = new UidRecord.ChangeItem();
18501                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18502                        "Allocating new item: " + uidRec.pendingChange);
18503            }
18504            uidRec.pendingChange.uidRecord = uidRec;
18505            uidRec.pendingChange.uid = uidRec.uid;
18506            mPendingUidChanges.add(uidRec.pendingChange);
18507        }
18508        uidRec.pendingChange.gone = gone;
18509        uidRec.pendingChange.processState = uidRec.setProcState;
18510    }
18511
18512    private void maybeUpdateUsageStats(ProcessRecord app) {
18513        if (DEBUG_USAGE_STATS) {
18514            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18515                    + "] state changes: old = " + app.setProcState + ", new = "
18516                    + app.curProcState);
18517        }
18518        if (mUsageStatsService == null) {
18519            return;
18520        }
18521        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
18522                && (app.setProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
18523                        || app.setProcState < 0)) {
18524            String[] packages = app.getPackageList();
18525            if (packages != null) {
18526                for (int i = 0; i < packages.length; i++) {
18527                    mUsageStatsService.reportEvent(packages[i], app.userId,
18528                            UsageEvents.Event.INTERACTION);
18529                }
18530            }
18531        }
18532    }
18533
18534    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18535        if (proc.thread != null) {
18536            if (proc.baseProcessTracker != null) {
18537                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18538            }
18539            if (proc.repProcState >= 0) {
18540                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18541                        proc.repProcState);
18542            }
18543        }
18544    }
18545
18546    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18547            ProcessRecord TOP_APP, boolean doingAll, long now) {
18548        if (app.thread == null) {
18549            return false;
18550        }
18551
18552        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18553
18554        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
18555    }
18556
18557    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18558            boolean oomAdj) {
18559        if (isForeground != proc.foregroundServices) {
18560            proc.foregroundServices = isForeground;
18561            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18562                    proc.info.uid);
18563            if (isForeground) {
18564                if (curProcs == null) {
18565                    curProcs = new ArrayList<ProcessRecord>();
18566                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18567                }
18568                if (!curProcs.contains(proc)) {
18569                    curProcs.add(proc);
18570                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18571                            proc.info.packageName, proc.info.uid);
18572                }
18573            } else {
18574                if (curProcs != null) {
18575                    if (curProcs.remove(proc)) {
18576                        mBatteryStatsService.noteEvent(
18577                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18578                                proc.info.packageName, proc.info.uid);
18579                        if (curProcs.size() <= 0) {
18580                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18581                        }
18582                    }
18583                }
18584            }
18585            if (oomAdj) {
18586                updateOomAdjLocked();
18587            }
18588        }
18589    }
18590
18591    private final ActivityRecord resumedAppLocked() {
18592        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18593        String pkg;
18594        int uid;
18595        if (act != null) {
18596            pkg = act.packageName;
18597            uid = act.info.applicationInfo.uid;
18598        } else {
18599            pkg = null;
18600            uid = -1;
18601        }
18602        // Has the UID or resumed package name changed?
18603        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18604                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18605            if (mCurResumedPackage != null) {
18606                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18607                        mCurResumedPackage, mCurResumedUid);
18608            }
18609            mCurResumedPackage = pkg;
18610            mCurResumedUid = uid;
18611            if (mCurResumedPackage != null) {
18612                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18613                        mCurResumedPackage, mCurResumedUid);
18614            }
18615        }
18616        return act;
18617    }
18618
18619    final boolean updateOomAdjLocked(ProcessRecord app) {
18620        final ActivityRecord TOP_ACT = resumedAppLocked();
18621        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18622        final boolean wasCached = app.cached;
18623
18624        mAdjSeq++;
18625
18626        // This is the desired cached adjusment we want to tell it to use.
18627        // If our app is currently cached, we know it, and that is it.  Otherwise,
18628        // we don't know it yet, and it needs to now be cached we will then
18629        // need to do a complete oom adj.
18630        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18631                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18632        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18633                SystemClock.uptimeMillis());
18634        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18635            // Changed to/from cached state, so apps after it in the LRU
18636            // list may also be changed.
18637            updateOomAdjLocked();
18638        }
18639        return success;
18640    }
18641
18642    final void updateOomAdjLocked() {
18643        final ActivityRecord TOP_ACT = resumedAppLocked();
18644        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18645        final long now = SystemClock.uptimeMillis();
18646        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18647        final int N = mLruProcesses.size();
18648
18649        if (false) {
18650            RuntimeException e = new RuntimeException();
18651            e.fillInStackTrace();
18652            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18653        }
18654
18655        // Reset state in all uid records.
18656        for (int i=mActiveUids.size()-1; i>=0; i--) {
18657            final UidRecord uidRec = mActiveUids.valueAt(i);
18658            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18659                    "Starting update of " + uidRec);
18660            uidRec.reset();
18661        }
18662
18663        mAdjSeq++;
18664        mNewNumServiceProcs = 0;
18665        mNewNumAServiceProcs = 0;
18666
18667        final int emptyProcessLimit;
18668        final int cachedProcessLimit;
18669        if (mProcessLimit <= 0) {
18670            emptyProcessLimit = cachedProcessLimit = 0;
18671        } else if (mProcessLimit == 1) {
18672            emptyProcessLimit = 1;
18673            cachedProcessLimit = 0;
18674        } else {
18675            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18676            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18677        }
18678
18679        // Let's determine how many processes we have running vs.
18680        // how many slots we have for background processes; we may want
18681        // to put multiple processes in a slot of there are enough of
18682        // them.
18683        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18684                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18685        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18686        if (numEmptyProcs > cachedProcessLimit) {
18687            // If there are more empty processes than our limit on cached
18688            // processes, then use the cached process limit for the factor.
18689            // This ensures that the really old empty processes get pushed
18690            // down to the bottom, so if we are running low on memory we will
18691            // have a better chance at keeping around more cached processes
18692            // instead of a gazillion empty processes.
18693            numEmptyProcs = cachedProcessLimit;
18694        }
18695        int emptyFactor = numEmptyProcs/numSlots;
18696        if (emptyFactor < 1) emptyFactor = 1;
18697        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18698        if (cachedFactor < 1) cachedFactor = 1;
18699        int stepCached = 0;
18700        int stepEmpty = 0;
18701        int numCached = 0;
18702        int numEmpty = 0;
18703        int numTrimming = 0;
18704
18705        mNumNonCachedProcs = 0;
18706        mNumCachedHiddenProcs = 0;
18707
18708        // First update the OOM adjustment for each of the
18709        // application processes based on their current state.
18710        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18711        int nextCachedAdj = curCachedAdj+1;
18712        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18713        int nextEmptyAdj = curEmptyAdj+2;
18714        for (int i=N-1; i>=0; i--) {
18715            ProcessRecord app = mLruProcesses.get(i);
18716            if (!app.killedByAm && app.thread != null) {
18717                app.procStateChanged = false;
18718                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18719
18720                // If we haven't yet assigned the final cached adj
18721                // to the process, do that now.
18722                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18723                    switch (app.curProcState) {
18724                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18725                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18726                            // This process is a cached process holding activities...
18727                            // assign it the next cached value for that type, and then
18728                            // step that cached level.
18729                            app.curRawAdj = curCachedAdj;
18730                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18731                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
18732                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18733                                    + ")");
18734                            if (curCachedAdj != nextCachedAdj) {
18735                                stepCached++;
18736                                if (stepCached >= cachedFactor) {
18737                                    stepCached = 0;
18738                                    curCachedAdj = nextCachedAdj;
18739                                    nextCachedAdj += 2;
18740                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18741                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18742                                    }
18743                                }
18744                            }
18745                            break;
18746                        default:
18747                            // For everything else, assign next empty cached process
18748                            // level and bump that up.  Note that this means that
18749                            // long-running services that have dropped down to the
18750                            // cached level will be treated as empty (since their process
18751                            // state is still as a service), which is what we want.
18752                            app.curRawAdj = curEmptyAdj;
18753                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18754                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
18755                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18756                                    + ")");
18757                            if (curEmptyAdj != nextEmptyAdj) {
18758                                stepEmpty++;
18759                                if (stepEmpty >= emptyFactor) {
18760                                    stepEmpty = 0;
18761                                    curEmptyAdj = nextEmptyAdj;
18762                                    nextEmptyAdj += 2;
18763                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18764                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18765                                    }
18766                                }
18767                            }
18768                            break;
18769                    }
18770                }
18771
18772                applyOomAdjLocked(app, TOP_APP, true, now);
18773
18774                // Count the number of process types.
18775                switch (app.curProcState) {
18776                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18777                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18778                        mNumCachedHiddenProcs++;
18779                        numCached++;
18780                        if (numCached > cachedProcessLimit) {
18781                            app.kill("cached #" + numCached, true);
18782                        }
18783                        break;
18784                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18785                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18786                                && app.lastActivityTime < oldTime) {
18787                            app.kill("empty for "
18788                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18789                                    / 1000) + "s", true);
18790                        } else {
18791                            numEmpty++;
18792                            if (numEmpty > emptyProcessLimit) {
18793                                app.kill("empty #" + numEmpty, true);
18794                            }
18795                        }
18796                        break;
18797                    default:
18798                        mNumNonCachedProcs++;
18799                        break;
18800                }
18801
18802                if (app.isolated && app.services.size() <= 0) {
18803                    // If this is an isolated process, and there are no
18804                    // services running in it, then the process is no longer
18805                    // needed.  We agressively kill these because we can by
18806                    // definition not re-use the same process again, and it is
18807                    // good to avoid having whatever code was running in them
18808                    // left sitting around after no longer needed.
18809                    app.kill("isolated not needed", true);
18810                } else {
18811                    // Keeping this process, update its uid.
18812                    final UidRecord uidRec = app.uidRecord;
18813                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
18814                        uidRec.curProcState = app.curProcState;
18815                    }
18816                }
18817
18818                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18819                        && !app.killedByAm) {
18820                    numTrimming++;
18821                }
18822            }
18823        }
18824
18825        mNumServiceProcs = mNewNumServiceProcs;
18826
18827        // Now determine the memory trimming level of background processes.
18828        // Unfortunately we need to start at the back of the list to do this
18829        // properly.  We only do this if the number of background apps we
18830        // are managing to keep around is less than half the maximum we desire;
18831        // if we are keeping a good number around, we'll let them use whatever
18832        // memory they want.
18833        final int numCachedAndEmpty = numCached + numEmpty;
18834        int memFactor;
18835        if (numCached <= ProcessList.TRIM_CACHED_APPS
18836                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18837            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18838                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18839            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18840                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18841            } else {
18842                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18843            }
18844        } else {
18845            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18846        }
18847        // We always allow the memory level to go up (better).  We only allow it to go
18848        // down if we are in a state where that is allowed, *and* the total number of processes
18849        // has gone down since last time.
18850        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
18851                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
18852                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
18853        if (memFactor > mLastMemoryLevel) {
18854            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18855                memFactor = mLastMemoryLevel;
18856                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
18857            }
18858        }
18859        mLastMemoryLevel = memFactor;
18860        mLastNumProcesses = mLruProcesses.size();
18861        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18862        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18863        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18864            if (mLowRamStartTime == 0) {
18865                mLowRamStartTime = now;
18866            }
18867            int step = 0;
18868            int fgTrimLevel;
18869            switch (memFactor) {
18870                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18871                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18872                    break;
18873                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18874                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18875                    break;
18876                default:
18877                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18878                    break;
18879            }
18880            int factor = numTrimming/3;
18881            int minFactor = 2;
18882            if (mHomeProcess != null) minFactor++;
18883            if (mPreviousProcess != null) minFactor++;
18884            if (factor < minFactor) factor = minFactor;
18885            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18886            for (int i=N-1; i>=0; i--) {
18887                ProcessRecord app = mLruProcesses.get(i);
18888                if (allChanged || app.procStateChanged) {
18889                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18890                    app.procStateChanged = false;
18891                }
18892                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18893                        && !app.killedByAm) {
18894                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18895                        try {
18896                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18897                                    "Trimming memory of " + app.processName + " to " + curLevel);
18898                            app.thread.scheduleTrimMemory(curLevel);
18899                        } catch (RemoteException e) {
18900                        }
18901                        if (false) {
18902                            // For now we won't do this; our memory trimming seems
18903                            // to be good enough at this point that destroying
18904                            // activities causes more harm than good.
18905                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18906                                    && app != mHomeProcess && app != mPreviousProcess) {
18907                                // Need to do this on its own message because the stack may not
18908                                // be in a consistent state at this point.
18909                                // For these apps we will also finish their activities
18910                                // to help them free memory.
18911                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18912                            }
18913                        }
18914                    }
18915                    app.trimMemoryLevel = curLevel;
18916                    step++;
18917                    if (step >= factor) {
18918                        step = 0;
18919                        switch (curLevel) {
18920                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18921                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18922                                break;
18923                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18924                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18925                                break;
18926                        }
18927                    }
18928                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18929                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18930                            && app.thread != null) {
18931                        try {
18932                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18933                                    "Trimming memory of heavy-weight " + app.processName
18934                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18935                            app.thread.scheduleTrimMemory(
18936                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18937                        } catch (RemoteException e) {
18938                        }
18939                    }
18940                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18941                } else {
18942                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18943                            || app.systemNoUi) && app.pendingUiClean) {
18944                        // If this application is now in the background and it
18945                        // had done UI, then give it the special trim level to
18946                        // have it free UI resources.
18947                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18948                        if (app.trimMemoryLevel < level && app.thread != null) {
18949                            try {
18950                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18951                                        "Trimming memory of bg-ui " + app.processName
18952                                        + " to " + level);
18953                                app.thread.scheduleTrimMemory(level);
18954                            } catch (RemoteException e) {
18955                            }
18956                        }
18957                        app.pendingUiClean = false;
18958                    }
18959                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18960                        try {
18961                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18962                                    "Trimming memory of fg " + app.processName
18963                                    + " to " + fgTrimLevel);
18964                            app.thread.scheduleTrimMemory(fgTrimLevel);
18965                        } catch (RemoteException e) {
18966                        }
18967                    }
18968                    app.trimMemoryLevel = fgTrimLevel;
18969                }
18970            }
18971        } else {
18972            if (mLowRamStartTime != 0) {
18973                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18974                mLowRamStartTime = 0;
18975            }
18976            for (int i=N-1; i>=0; i--) {
18977                ProcessRecord app = mLruProcesses.get(i);
18978                if (allChanged || app.procStateChanged) {
18979                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18980                    app.procStateChanged = false;
18981                }
18982                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18983                        || app.systemNoUi) && app.pendingUiClean) {
18984                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18985                            && app.thread != null) {
18986                        try {
18987                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18988                                    "Trimming memory of ui hidden " + app.processName
18989                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18990                            app.thread.scheduleTrimMemory(
18991                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18992                        } catch (RemoteException e) {
18993                        }
18994                    }
18995                    app.pendingUiClean = false;
18996                }
18997                app.trimMemoryLevel = 0;
18998            }
18999        }
19000
19001        if (mAlwaysFinishActivities) {
19002            // Need to do this on its own message because the stack may not
19003            // be in a consistent state at this point.
19004            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19005        }
19006
19007        if (allChanged) {
19008            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19009        }
19010
19011        // Update from any uid changes.
19012        for (int i=mActiveUids.size()-1; i>=0; i--) {
19013            final UidRecord uidRec = mActiveUids.valueAt(i);
19014            if (uidRec.setProcState != uidRec.curProcState) {
19015                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19016                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19017                        + " to " + uidRec.curProcState);
19018                uidRec.setProcState = uidRec.curProcState;
19019                enqueueUidChangeLocked(uidRec, false);
19020            }
19021        }
19022
19023        if (mProcessStats.shouldWriteNowLocked(now)) {
19024            mHandler.post(new Runnable() {
19025                @Override public void run() {
19026                    synchronized (ActivityManagerService.this) {
19027                        mProcessStats.writeStateAsyncLocked();
19028                    }
19029                }
19030            });
19031        }
19032
19033        if (DEBUG_OOM_ADJ) {
19034            final long duration = SystemClock.uptimeMillis() - now;
19035            if (false) {
19036                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19037                        new RuntimeException("here").fillInStackTrace());
19038            } else {
19039                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19040            }
19041        }
19042    }
19043
19044    final void trimApplications() {
19045        synchronized (this) {
19046            int i;
19047
19048            // First remove any unused application processes whose package
19049            // has been removed.
19050            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19051                final ProcessRecord app = mRemovedProcesses.get(i);
19052                if (app.activities.size() == 0
19053                        && app.curReceiver == null && app.services.size() == 0) {
19054                    Slog.i(
19055                        TAG, "Exiting empty application process "
19056                        + app.processName + " ("
19057                        + (app.thread != null ? app.thread.asBinder() : null)
19058                        + ")\n");
19059                    if (app.pid > 0 && app.pid != MY_PID) {
19060                        app.kill("empty", false);
19061                    } else {
19062                        try {
19063                            app.thread.scheduleExit();
19064                        } catch (Exception e) {
19065                            // Ignore exceptions.
19066                        }
19067                    }
19068                    cleanUpApplicationRecordLocked(app, false, true, -1);
19069                    mRemovedProcesses.remove(i);
19070
19071                    if (app.persistent) {
19072                        addAppLocked(app.info, false, null /* ABI override */);
19073                    }
19074                }
19075            }
19076
19077            // Now update the oom adj for all processes.
19078            updateOomAdjLocked();
19079        }
19080    }
19081
19082    /** This method sends the specified signal to each of the persistent apps */
19083    public void signalPersistentProcesses(int sig) throws RemoteException {
19084        if (sig != Process.SIGNAL_USR1) {
19085            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19086        }
19087
19088        synchronized (this) {
19089            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19090                    != PackageManager.PERMISSION_GRANTED) {
19091                throw new SecurityException("Requires permission "
19092                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19093            }
19094
19095            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19096                ProcessRecord r = mLruProcesses.get(i);
19097                if (r.thread != null && r.persistent) {
19098                    Process.sendSignal(r.pid, sig);
19099                }
19100            }
19101        }
19102    }
19103
19104    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19105        if (proc == null || proc == mProfileProc) {
19106            proc = mProfileProc;
19107            profileType = mProfileType;
19108            clearProfilerLocked();
19109        }
19110        if (proc == null) {
19111            return;
19112        }
19113        try {
19114            proc.thread.profilerControl(false, null, profileType);
19115        } catch (RemoteException e) {
19116            throw new IllegalStateException("Process disappeared");
19117        }
19118    }
19119
19120    private void clearProfilerLocked() {
19121        if (mProfileFd != null) {
19122            try {
19123                mProfileFd.close();
19124            } catch (IOException e) {
19125            }
19126        }
19127        mProfileApp = null;
19128        mProfileProc = null;
19129        mProfileFile = null;
19130        mProfileType = 0;
19131        mAutoStopProfiler = false;
19132        mSamplingInterval = 0;
19133    }
19134
19135    public boolean profileControl(String process, int userId, boolean start,
19136            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19137
19138        try {
19139            synchronized (this) {
19140                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19141                // its own permission.
19142                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19143                        != PackageManager.PERMISSION_GRANTED) {
19144                    throw new SecurityException("Requires permission "
19145                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19146                }
19147
19148                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19149                    throw new IllegalArgumentException("null profile info or fd");
19150                }
19151
19152                ProcessRecord proc = null;
19153                if (process != null) {
19154                    proc = findProcessLocked(process, userId, "profileControl");
19155                }
19156
19157                if (start && (proc == null || proc.thread == null)) {
19158                    throw new IllegalArgumentException("Unknown process: " + process);
19159                }
19160
19161                if (start) {
19162                    stopProfilerLocked(null, 0);
19163                    setProfileApp(proc.info, proc.processName, profilerInfo);
19164                    mProfileProc = proc;
19165                    mProfileType = profileType;
19166                    ParcelFileDescriptor fd = profilerInfo.profileFd;
19167                    try {
19168                        fd = fd.dup();
19169                    } catch (IOException e) {
19170                        fd = null;
19171                    }
19172                    profilerInfo.profileFd = fd;
19173                    proc.thread.profilerControl(start, profilerInfo, profileType);
19174                    fd = null;
19175                    mProfileFd = null;
19176                } else {
19177                    stopProfilerLocked(proc, profileType);
19178                    if (profilerInfo != null && profilerInfo.profileFd != null) {
19179                        try {
19180                            profilerInfo.profileFd.close();
19181                        } catch (IOException e) {
19182                        }
19183                    }
19184                }
19185
19186                return true;
19187            }
19188        } catch (RemoteException e) {
19189            throw new IllegalStateException("Process disappeared");
19190        } finally {
19191            if (profilerInfo != null && profilerInfo.profileFd != null) {
19192                try {
19193                    profilerInfo.profileFd.close();
19194                } catch (IOException e) {
19195                }
19196            }
19197        }
19198    }
19199
19200    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19201        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19202                userId, true, ALLOW_FULL_ONLY, callName, null);
19203        ProcessRecord proc = null;
19204        try {
19205            int pid = Integer.parseInt(process);
19206            synchronized (mPidsSelfLocked) {
19207                proc = mPidsSelfLocked.get(pid);
19208            }
19209        } catch (NumberFormatException e) {
19210        }
19211
19212        if (proc == null) {
19213            ArrayMap<String, SparseArray<ProcessRecord>> all
19214                    = mProcessNames.getMap();
19215            SparseArray<ProcessRecord> procs = all.get(process);
19216            if (procs != null && procs.size() > 0) {
19217                proc = procs.valueAt(0);
19218                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19219                    for (int i=1; i<procs.size(); i++) {
19220                        ProcessRecord thisProc = procs.valueAt(i);
19221                        if (thisProc.userId == userId) {
19222                            proc = thisProc;
19223                            break;
19224                        }
19225                    }
19226                }
19227            }
19228        }
19229
19230        return proc;
19231    }
19232
19233    public boolean dumpHeap(String process, int userId, boolean managed,
19234            String path, ParcelFileDescriptor fd) throws RemoteException {
19235
19236        try {
19237            synchronized (this) {
19238                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19239                // its own permission (same as profileControl).
19240                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19241                        != PackageManager.PERMISSION_GRANTED) {
19242                    throw new SecurityException("Requires permission "
19243                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19244                }
19245
19246                if (fd == null) {
19247                    throw new IllegalArgumentException("null fd");
19248                }
19249
19250                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19251                if (proc == null || proc.thread == null) {
19252                    throw new IllegalArgumentException("Unknown process: " + process);
19253                }
19254
19255                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19256                if (!isDebuggable) {
19257                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19258                        throw new SecurityException("Process not debuggable: " + proc);
19259                    }
19260                }
19261
19262                proc.thread.dumpHeap(managed, path, fd);
19263                fd = null;
19264                return true;
19265            }
19266        } catch (RemoteException e) {
19267            throw new IllegalStateException("Process disappeared");
19268        } finally {
19269            if (fd != null) {
19270                try {
19271                    fd.close();
19272                } catch (IOException e) {
19273                }
19274            }
19275        }
19276    }
19277
19278    @Override
19279    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19280            String reportPackage) {
19281        if (processName != null) {
19282            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19283                    "setDumpHeapDebugLimit()");
19284        } else {
19285            if (!Build.IS_DEBUGGABLE) {
19286                throw new SecurityException("Not running a debuggable build");
19287            }
19288            synchronized (mPidsSelfLocked) {
19289                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19290                if (proc == null) {
19291                    throw new SecurityException("No process found for calling pid "
19292                            + Binder.getCallingPid());
19293                }
19294                processName = proc.processName;
19295                uid = proc.uid;
19296                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19297                    throw new SecurityException("Package " + reportPackage + " is not running in "
19298                            + proc);
19299                }
19300            }
19301        }
19302        synchronized (this) {
19303            if (maxMemSize > 0) {
19304                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19305            } else {
19306                if (uid != 0) {
19307                    mMemWatchProcesses.remove(processName, uid);
19308                } else {
19309                    mMemWatchProcesses.getMap().remove(processName);
19310                }
19311            }
19312        }
19313    }
19314
19315    @Override
19316    public void dumpHeapFinished(String path) {
19317        synchronized (this) {
19318            if (Binder.getCallingPid() != mMemWatchDumpPid) {
19319                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19320                        + " does not match last pid " + mMemWatchDumpPid);
19321                return;
19322            }
19323            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19324                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19325                        + " does not match last path " + mMemWatchDumpFile);
19326                return;
19327            }
19328            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19329            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19330        }
19331    }
19332
19333    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19334    public void monitor() {
19335        synchronized (this) { }
19336    }
19337
19338    void onCoreSettingsChange(Bundle settings) {
19339        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19340            ProcessRecord processRecord = mLruProcesses.get(i);
19341            try {
19342                if (processRecord.thread != null) {
19343                    processRecord.thread.setCoreSettings(settings);
19344                }
19345            } catch (RemoteException re) {
19346                /* ignore */
19347            }
19348        }
19349    }
19350
19351    // Multi-user methods
19352
19353    /**
19354     * Start user, if its not already running, but don't bring it to foreground.
19355     */
19356    @Override
19357    public boolean startUserInBackground(final int userId) {
19358        return startUser(userId, /* foreground */ false);
19359    }
19360
19361    /**
19362     * Start user, if its not already running, and bring it to foreground.
19363     */
19364    boolean startUserInForeground(final int userId, Dialog dlg) {
19365        boolean result = startUser(userId, /* foreground */ true);
19366        dlg.dismiss();
19367        return result;
19368    }
19369
19370    /**
19371     * Refreshes the list of users related to the current user when either a
19372     * user switch happens or when a new related user is started in the
19373     * background.
19374     */
19375    private void updateCurrentProfileIdsLocked() {
19376        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19377                mCurrentUserId, false /* enabledOnly */);
19378        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19379        for (int i = 0; i < currentProfileIds.length; i++) {
19380            currentProfileIds[i] = profiles.get(i).id;
19381        }
19382        mCurrentProfileIds = currentProfileIds;
19383
19384        synchronized (mUserProfileGroupIdsSelfLocked) {
19385            mUserProfileGroupIdsSelfLocked.clear();
19386            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19387            for (int i = 0; i < users.size(); i++) {
19388                UserInfo user = users.get(i);
19389                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19390                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19391                }
19392            }
19393        }
19394    }
19395
19396    private Set<Integer> getProfileIdsLocked(int userId) {
19397        Set<Integer> userIds = new HashSet<Integer>();
19398        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19399                userId, false /* enabledOnly */);
19400        for (UserInfo user : profiles) {
19401            userIds.add(Integer.valueOf(user.id));
19402        }
19403        return userIds;
19404    }
19405
19406    @Override
19407    public boolean switchUser(final int userId) {
19408        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19409        String userName;
19410        synchronized (this) {
19411            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19412            if (userInfo == null) {
19413                Slog.w(TAG, "No user info for user #" + userId);
19414                return false;
19415            }
19416            if (userInfo.isManagedProfile()) {
19417                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19418                return false;
19419            }
19420            userName = userInfo.name;
19421            mTargetUserId = userId;
19422        }
19423        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19424        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19425        return true;
19426    }
19427
19428    private void showUserSwitchDialog(int userId, String userName) {
19429        // The dialog will show and then initiate the user switch by calling startUserInForeground
19430        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19431                true /* above system */);
19432        d.show();
19433    }
19434
19435    private boolean startUser(final int userId, final boolean foreground) {
19436        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19437                != PackageManager.PERMISSION_GRANTED) {
19438            String msg = "Permission Denial: switchUser() from pid="
19439                    + Binder.getCallingPid()
19440                    + ", uid=" + Binder.getCallingUid()
19441                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19442            Slog.w(TAG, msg);
19443            throw new SecurityException(msg);
19444        }
19445
19446        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19447
19448        final long ident = Binder.clearCallingIdentity();
19449        try {
19450            synchronized (this) {
19451                final int oldUserId = mCurrentUserId;
19452                if (oldUserId == userId) {
19453                    return true;
19454                }
19455
19456                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19457                        "startUser");
19458
19459                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19460                if (userInfo == null) {
19461                    Slog.w(TAG, "No user info for user #" + userId);
19462                    return false;
19463                }
19464                if (foreground && userInfo.isManagedProfile()) {
19465                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19466                    return false;
19467                }
19468
19469                if (foreground) {
19470                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19471                            R.anim.screen_user_enter);
19472                }
19473
19474                boolean needStart = false;
19475
19476                // If the user we are switching to is not currently started, then
19477                // we need to start it now.
19478                if (mStartedUsers.get(userId) == null) {
19479                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
19480                    updateStartedUserArrayLocked();
19481                    needStart = true;
19482                }
19483
19484                final Integer userIdInt = Integer.valueOf(userId);
19485                mUserLru.remove(userIdInt);
19486                mUserLru.add(userIdInt);
19487
19488                if (foreground) {
19489                    mCurrentUserId = userId;
19490                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19491                    updateCurrentProfileIdsLocked();
19492                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19493                    // Once the internal notion of the active user has switched, we lock the device
19494                    // with the option to show the user switcher on the keyguard.
19495                    mWindowManager.lockNow(null);
19496                } else {
19497                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19498                    updateCurrentProfileIdsLocked();
19499                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19500                    mUserLru.remove(currentUserIdInt);
19501                    mUserLru.add(currentUserIdInt);
19502                }
19503
19504                final UserStartedState uss = mStartedUsers.get(userId);
19505
19506                // Make sure user is in the started state.  If it is currently
19507                // stopping, we need to knock that off.
19508                if (uss.mState == UserStartedState.STATE_STOPPING) {
19509                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19510                    // so we can just fairly silently bring the user back from
19511                    // the almost-dead.
19512                    uss.mState = UserStartedState.STATE_RUNNING;
19513                    updateStartedUserArrayLocked();
19514                    needStart = true;
19515                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
19516                    // This means ACTION_SHUTDOWN has been sent, so we will
19517                    // need to treat this as a new boot of the user.
19518                    uss.mState = UserStartedState.STATE_BOOTING;
19519                    updateStartedUserArrayLocked();
19520                    needStart = true;
19521                }
19522
19523                if (uss.mState == UserStartedState.STATE_BOOTING) {
19524                    // Booting up a new user, need to tell system services about it.
19525                    // Note that this is on the same handler as scheduling of broadcasts,
19526                    // which is important because it needs to go first.
19527                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19528                }
19529
19530                if (foreground) {
19531                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19532                            oldUserId));
19533                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19534                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19535                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19536                            oldUserId, userId, uss));
19537                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19538                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19539                }
19540
19541                if (needStart) {
19542                    // Send USER_STARTED broadcast
19543                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19544                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19545                            | Intent.FLAG_RECEIVER_FOREGROUND);
19546                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19547                    broadcastIntentLocked(null, null, intent,
19548                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19549                            false, false, MY_PID, Process.SYSTEM_UID, userId);
19550                }
19551
19552                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19553                    if (userId != UserHandle.USER_OWNER) {
19554                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19555                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19556                        broadcastIntentLocked(null, null, intent, null,
19557                                new IIntentReceiver.Stub() {
19558                                    public void performReceive(Intent intent, int resultCode,
19559                                            String data, Bundle extras, boolean ordered,
19560                                            boolean sticky, int sendingUser) {
19561                                        onUserInitialized(uss, foreground, oldUserId, userId);
19562                                    }
19563                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19564                                true, false, MY_PID, Process.SYSTEM_UID,
19565                                userId);
19566                        uss.initializing = true;
19567                    } else {
19568                        getUserManagerLocked().makeInitialized(userInfo.id);
19569                    }
19570                }
19571
19572                if (foreground) {
19573                    if (!uss.initializing) {
19574                        moveUserToForeground(uss, oldUserId, userId);
19575                    }
19576                } else {
19577                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19578                }
19579
19580                if (needStart) {
19581                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19582                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19583                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19584                    broadcastIntentLocked(null, null, intent,
19585                            null, new IIntentReceiver.Stub() {
19586                                @Override
19587                                public void performReceive(Intent intent, int resultCode, String data,
19588                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
19589                                        throws RemoteException {
19590                                }
19591                            }, 0, null, null,
19592                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19593                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19594                }
19595            }
19596        } finally {
19597            Binder.restoreCallingIdentity(ident);
19598        }
19599
19600        return true;
19601    }
19602
19603    void dispatchForegroundProfileChanged(int userId) {
19604        final int N = mUserSwitchObservers.beginBroadcast();
19605        for (int i = 0; i < N; i++) {
19606            try {
19607                mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19608            } catch (RemoteException e) {
19609                // Ignore
19610            }
19611        }
19612        mUserSwitchObservers.finishBroadcast();
19613    }
19614
19615    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19616        long ident = Binder.clearCallingIdentity();
19617        try {
19618            Intent intent;
19619            if (oldUserId >= 0) {
19620                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19621                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19622                int count = profiles.size();
19623                for (int i = 0; i < count; i++) {
19624                    int profileUserId = profiles.get(i).id;
19625                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19626                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19627                            | Intent.FLAG_RECEIVER_FOREGROUND);
19628                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19629                    broadcastIntentLocked(null, null, intent,
19630                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19631                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19632                }
19633            }
19634            if (newUserId >= 0) {
19635                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19636                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19637                int count = profiles.size();
19638                for (int i = 0; i < count; i++) {
19639                    int profileUserId = profiles.get(i).id;
19640                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19641                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19642                            | Intent.FLAG_RECEIVER_FOREGROUND);
19643                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19644                    broadcastIntentLocked(null, null, intent,
19645                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19646                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19647                }
19648                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19649                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19650                        | Intent.FLAG_RECEIVER_FOREGROUND);
19651                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19652                broadcastIntentLocked(null, null, intent,
19653                        null, null, 0, null, null,
19654                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19655                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19656            }
19657        } finally {
19658            Binder.restoreCallingIdentity(ident);
19659        }
19660    }
19661
19662    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
19663            final int newUserId) {
19664        final int N = mUserSwitchObservers.beginBroadcast();
19665        if (N > 0) {
19666            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19667                int mCount = 0;
19668                @Override
19669                public void sendResult(Bundle data) throws RemoteException {
19670                    synchronized (ActivityManagerService.this) {
19671                        if (mCurUserSwitchCallback == this) {
19672                            mCount++;
19673                            if (mCount == N) {
19674                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19675                            }
19676                        }
19677                    }
19678                }
19679            };
19680            synchronized (this) {
19681                uss.switching = true;
19682                mCurUserSwitchCallback = callback;
19683            }
19684            for (int i=0; i<N; i++) {
19685                try {
19686                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19687                            newUserId, callback);
19688                } catch (RemoteException e) {
19689                }
19690            }
19691        } else {
19692            synchronized (this) {
19693                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19694            }
19695        }
19696        mUserSwitchObservers.finishBroadcast();
19697    }
19698
19699    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19700        synchronized (this) {
19701            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19702            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19703        }
19704    }
19705
19706    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
19707        mCurUserSwitchCallback = null;
19708        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19709        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19710                oldUserId, newUserId, uss));
19711    }
19712
19713    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
19714        synchronized (this) {
19715            if (foreground) {
19716                moveUserToForeground(uss, oldUserId, newUserId);
19717            }
19718        }
19719
19720        completeSwitchAndInitalize(uss, newUserId, true, false);
19721    }
19722
19723    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19724        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19725        if (homeInFront) {
19726            startHomeActivityLocked(newUserId, "moveUserToFroreground");
19727        } else {
19728            mStackSupervisor.resumeTopActivitiesLocked();
19729        }
19730        EventLogTags.writeAmSwitchUser(newUserId);
19731        getUserManagerLocked().onUserForeground(newUserId);
19732        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19733    }
19734
19735    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19736        completeSwitchAndInitalize(uss, newUserId, false, true);
19737    }
19738
19739    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19740            boolean clearInitializing, boolean clearSwitching) {
19741        boolean unfrozen = false;
19742        synchronized (this) {
19743            if (clearInitializing) {
19744                uss.initializing = false;
19745                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19746            }
19747            if (clearSwitching) {
19748                uss.switching = false;
19749            }
19750            if (!uss.switching && !uss.initializing) {
19751                mWindowManager.stopFreezingScreen();
19752                unfrozen = true;
19753            }
19754        }
19755        if (unfrozen) {
19756            final int N = mUserSwitchObservers.beginBroadcast();
19757            for (int i=0; i<N; i++) {
19758                try {
19759                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19760                } catch (RemoteException e) {
19761                }
19762            }
19763            mUserSwitchObservers.finishBroadcast();
19764        }
19765        stopGuestUserIfBackground();
19766    }
19767
19768    /**
19769     * Stops the guest user if it has gone to the background.
19770     */
19771    private void stopGuestUserIfBackground() {
19772        synchronized (this) {
19773            final int num = mUserLru.size();
19774            for (int i = 0; i < num; i++) {
19775                Integer oldUserId = mUserLru.get(i);
19776                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19777                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19778                        || oldUss.mState == UserStartedState.STATE_STOPPING
19779                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19780                    continue;
19781                }
19782                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19783                if (userInfo.isGuest()) {
19784                    // This is a user to be stopped.
19785                    stopUserLocked(oldUserId, null);
19786                    break;
19787                }
19788            }
19789        }
19790    }
19791
19792    void scheduleStartProfilesLocked() {
19793        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19794            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19795                    DateUtils.SECOND_IN_MILLIS);
19796        }
19797    }
19798
19799    void startProfilesLocked() {
19800        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19801        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19802                mCurrentUserId, false /* enabledOnly */);
19803        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19804        for (UserInfo user : profiles) {
19805            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19806                    && user.id != mCurrentUserId) {
19807                toStart.add(user);
19808            }
19809        }
19810        final int n = toStart.size();
19811        int i = 0;
19812        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19813            startUserInBackground(toStart.get(i).id);
19814        }
19815        if (i < n) {
19816            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19817        }
19818    }
19819
19820    void finishUserBoot(UserStartedState uss) {
19821        synchronized (this) {
19822            if (uss.mState == UserStartedState.STATE_BOOTING
19823                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19824                uss.mState = UserStartedState.STATE_RUNNING;
19825                final int userId = uss.mHandle.getIdentifier();
19826                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19827                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19828                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19829                broadcastIntentLocked(null, null, intent,
19830                        null, null, 0, null, null,
19831                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19832                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19833            }
19834        }
19835    }
19836
19837    void finishUserSwitch(UserStartedState uss) {
19838        synchronized (this) {
19839            finishUserBoot(uss);
19840
19841            startProfilesLocked();
19842
19843            int num = mUserLru.size();
19844            int i = 0;
19845            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19846                Integer oldUserId = mUserLru.get(i);
19847                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19848                if (oldUss == null) {
19849                    // Shouldn't happen, but be sane if it does.
19850                    mUserLru.remove(i);
19851                    num--;
19852                    continue;
19853                }
19854                if (oldUss.mState == UserStartedState.STATE_STOPPING
19855                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19856                    // This user is already stopping, doesn't count.
19857                    num--;
19858                    i++;
19859                    continue;
19860                }
19861                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19862                    // Owner and current can't be stopped, but count as running.
19863                    i++;
19864                    continue;
19865                }
19866                // This is a user to be stopped.
19867                stopUserLocked(oldUserId, null);
19868                num--;
19869                i++;
19870            }
19871        }
19872    }
19873
19874    @Override
19875    public int stopUser(final int userId, final IStopUserCallback callback) {
19876        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19877                != PackageManager.PERMISSION_GRANTED) {
19878            String msg = "Permission Denial: switchUser() from pid="
19879                    + Binder.getCallingPid()
19880                    + ", uid=" + Binder.getCallingUid()
19881                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19882            Slog.w(TAG, msg);
19883            throw new SecurityException(msg);
19884        }
19885        if (userId < 0 || userId == UserHandle.USER_OWNER) {
19886            throw new IllegalArgumentException("Can't stop primary user " + userId);
19887        }
19888        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19889        synchronized (this) {
19890            return stopUserLocked(userId, callback);
19891        }
19892    }
19893
19894    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19895        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19896        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19897            return ActivityManager.USER_OP_IS_CURRENT;
19898        }
19899
19900        final UserStartedState uss = mStartedUsers.get(userId);
19901        if (uss == null) {
19902            // User is not started, nothing to do...  but we do need to
19903            // callback if requested.
19904            if (callback != null) {
19905                mHandler.post(new Runnable() {
19906                    @Override
19907                    public void run() {
19908                        try {
19909                            callback.userStopped(userId);
19910                        } catch (RemoteException e) {
19911                        }
19912                    }
19913                });
19914            }
19915            return ActivityManager.USER_OP_SUCCESS;
19916        }
19917
19918        if (callback != null) {
19919            uss.mStopCallbacks.add(callback);
19920        }
19921
19922        if (uss.mState != UserStartedState.STATE_STOPPING
19923                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19924            uss.mState = UserStartedState.STATE_STOPPING;
19925            updateStartedUserArrayLocked();
19926
19927            long ident = Binder.clearCallingIdentity();
19928            try {
19929                // We are going to broadcast ACTION_USER_STOPPING and then
19930                // once that is done send a final ACTION_SHUTDOWN and then
19931                // stop the user.
19932                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19933                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19934                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19935                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19936                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19937                // This is the result receiver for the final shutdown broadcast.
19938                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19939                    @Override
19940                    public void performReceive(Intent intent, int resultCode, String data,
19941                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19942                        finishUserStop(uss);
19943                    }
19944                };
19945                // This is the result receiver for the initial stopping broadcast.
19946                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19947                    @Override
19948                    public void performReceive(Intent intent, int resultCode, String data,
19949                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19950                        // On to the next.
19951                        synchronized (ActivityManagerService.this) {
19952                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19953                                // Whoops, we are being started back up.  Abort, abort!
19954                                return;
19955                            }
19956                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19957                        }
19958                        mBatteryStatsService.noteEvent(
19959                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19960                                Integer.toString(userId), userId);
19961                        mSystemServiceManager.stopUser(userId);
19962                        broadcastIntentLocked(null, null, shutdownIntent,
19963                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19964                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19965                    }
19966                };
19967                // Kick things off.
19968                broadcastIntentLocked(null, null, stoppingIntent,
19969                        null, stoppingReceiver, 0, null, null,
19970                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19971                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19972            } finally {
19973                Binder.restoreCallingIdentity(ident);
19974            }
19975        }
19976
19977        return ActivityManager.USER_OP_SUCCESS;
19978    }
19979
19980    void finishUserStop(UserStartedState uss) {
19981        final int userId = uss.mHandle.getIdentifier();
19982        boolean stopped;
19983        ArrayList<IStopUserCallback> callbacks;
19984        synchronized (this) {
19985            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19986            if (mStartedUsers.get(userId) != uss) {
19987                stopped = false;
19988            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19989                stopped = false;
19990            } else {
19991                stopped = true;
19992                // User can no longer run.
19993                mStartedUsers.remove(userId);
19994                mUserLru.remove(Integer.valueOf(userId));
19995                updateStartedUserArrayLocked();
19996
19997                // Clean up all state and processes associated with the user.
19998                // Kill all the processes for the user.
19999                forceStopUserLocked(userId, "finish user");
20000            }
20001
20002            // Explicitly remove the old information in mRecentTasks.
20003            mRecentTasks.removeTasksForUserLocked(userId);
20004        }
20005
20006        for (int i=0; i<callbacks.size(); i++) {
20007            try {
20008                if (stopped) callbacks.get(i).userStopped(userId);
20009                else callbacks.get(i).userStopAborted(userId);
20010            } catch (RemoteException e) {
20011            }
20012        }
20013
20014        if (stopped) {
20015            mSystemServiceManager.cleanupUser(userId);
20016            synchronized (this) {
20017                mStackSupervisor.removeUserLocked(userId);
20018            }
20019        }
20020    }
20021
20022    @Override
20023    public UserInfo getCurrentUser() {
20024        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20025                != PackageManager.PERMISSION_GRANTED) && (
20026                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20027                != PackageManager.PERMISSION_GRANTED)) {
20028            String msg = "Permission Denial: getCurrentUser() from pid="
20029                    + Binder.getCallingPid()
20030                    + ", uid=" + Binder.getCallingUid()
20031                    + " requires " + INTERACT_ACROSS_USERS;
20032            Slog.w(TAG, msg);
20033            throw new SecurityException(msg);
20034        }
20035        synchronized (this) {
20036            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20037            return getUserManagerLocked().getUserInfo(userId);
20038        }
20039    }
20040
20041    int getCurrentUserIdLocked() {
20042        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20043    }
20044
20045    @Override
20046    public boolean isUserRunning(int userId, boolean orStopped) {
20047        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20048                != PackageManager.PERMISSION_GRANTED) {
20049            String msg = "Permission Denial: isUserRunning() from pid="
20050                    + Binder.getCallingPid()
20051                    + ", uid=" + Binder.getCallingUid()
20052                    + " requires " + INTERACT_ACROSS_USERS;
20053            Slog.w(TAG, msg);
20054            throw new SecurityException(msg);
20055        }
20056        synchronized (this) {
20057            return isUserRunningLocked(userId, orStopped);
20058        }
20059    }
20060
20061    boolean isUserRunningLocked(int userId, boolean orStopped) {
20062        UserStartedState state = mStartedUsers.get(userId);
20063        if (state == null) {
20064            return false;
20065        }
20066        if (orStopped) {
20067            return true;
20068        }
20069        return state.mState != UserStartedState.STATE_STOPPING
20070                && state.mState != UserStartedState.STATE_SHUTDOWN;
20071    }
20072
20073    @Override
20074    public int[] getRunningUserIds() {
20075        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20076                != PackageManager.PERMISSION_GRANTED) {
20077            String msg = "Permission Denial: isUserRunning() from pid="
20078                    + Binder.getCallingPid()
20079                    + ", uid=" + Binder.getCallingUid()
20080                    + " requires " + INTERACT_ACROSS_USERS;
20081            Slog.w(TAG, msg);
20082            throw new SecurityException(msg);
20083        }
20084        synchronized (this) {
20085            return mStartedUserArray;
20086        }
20087    }
20088
20089    private void updateStartedUserArrayLocked() {
20090        int num = 0;
20091        for (int i=0; i<mStartedUsers.size();  i++) {
20092            UserStartedState uss = mStartedUsers.valueAt(i);
20093            // This list does not include stopping users.
20094            if (uss.mState != UserStartedState.STATE_STOPPING
20095                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
20096                num++;
20097            }
20098        }
20099        mStartedUserArray = new int[num];
20100        num = 0;
20101        for (int i=0; i<mStartedUsers.size();  i++) {
20102            UserStartedState uss = mStartedUsers.valueAt(i);
20103            if (uss.mState != UserStartedState.STATE_STOPPING
20104                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
20105                mStartedUserArray[num] = mStartedUsers.keyAt(i);
20106                num++;
20107            }
20108        }
20109    }
20110
20111    @Override
20112    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20113        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20114                != PackageManager.PERMISSION_GRANTED) {
20115            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20116                    + Binder.getCallingPid()
20117                    + ", uid=" + Binder.getCallingUid()
20118                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20119            Slog.w(TAG, msg);
20120            throw new SecurityException(msg);
20121        }
20122
20123        mUserSwitchObservers.register(observer);
20124    }
20125
20126    @Override
20127    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20128        mUserSwitchObservers.unregister(observer);
20129    }
20130
20131    int[] getUsersLocked() {
20132        UserManagerService ums = getUserManagerLocked();
20133        return ums != null ? ums.getUserIds() : new int[] { 0 };
20134    }
20135
20136    UserManagerService getUserManagerLocked() {
20137        if (mUserManager == null) {
20138            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20139            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20140        }
20141        return mUserManager;
20142    }
20143
20144    private int applyUserId(int uid, int userId) {
20145        return UserHandle.getUid(userId, uid);
20146    }
20147
20148    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20149        if (info == null) return null;
20150        ApplicationInfo newInfo = new ApplicationInfo(info);
20151        newInfo.uid = applyUserId(info.uid, userId);
20152        newInfo.dataDir = PackageManager.getDataDirForUser(info.volumeUuid, info.packageName,
20153                userId).getAbsolutePath();
20154        return newInfo;
20155    }
20156
20157    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20158        if (aInfo == null
20159                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20160            return aInfo;
20161        }
20162
20163        ActivityInfo info = new ActivityInfo(aInfo);
20164        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20165        return info;
20166    }
20167
20168    private final class LocalService extends ActivityManagerInternal {
20169        @Override
20170        public void onWakefulnessChanged(int wakefulness) {
20171            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20172        }
20173
20174        @Override
20175        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20176                String processName, String abiOverride, int uid, Runnable crashHandler) {
20177            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20178                    processName, abiOverride, uid, crashHandler);
20179        }
20180
20181        @Override
20182        public SleepToken acquireSleepToken(String tag) {
20183            Preconditions.checkNotNull(tag);
20184
20185            synchronized (ActivityManagerService.this) {
20186                SleepTokenImpl token = new SleepTokenImpl(tag);
20187                mSleepTokens.add(token);
20188                updateSleepIfNeededLocked();
20189                return token;
20190            }
20191        }
20192
20193        @Override
20194        public ComponentName getHomeActivityForUser(int userId) {
20195            synchronized (ActivityManagerService.this) {
20196                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20197                return homeActivity == null ? null : homeActivity.realActivity;
20198            }
20199        }
20200    }
20201
20202    private final class SleepTokenImpl extends SleepToken {
20203        private final String mTag;
20204        private final long mAcquireTime;
20205
20206        public SleepTokenImpl(String tag) {
20207            mTag = tag;
20208            mAcquireTime = SystemClock.uptimeMillis();
20209        }
20210
20211        @Override
20212        public void release() {
20213            synchronized (ActivityManagerService.this) {
20214                if (mSleepTokens.remove(this)) {
20215                    updateSleepIfNeededLocked();
20216                }
20217            }
20218        }
20219
20220        @Override
20221        public String toString() {
20222            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20223        }
20224    }
20225
20226    /**
20227     * An implementation of IAppTask, that allows an app to manage its own tasks via
20228     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20229     * only the process that calls getAppTasks() can call the AppTask methods.
20230     */
20231    class AppTaskImpl extends IAppTask.Stub {
20232        private int mTaskId;
20233        private int mCallingUid;
20234
20235        public AppTaskImpl(int taskId, int callingUid) {
20236            mTaskId = taskId;
20237            mCallingUid = callingUid;
20238        }
20239
20240        private void checkCaller() {
20241            if (mCallingUid != Binder.getCallingUid()) {
20242                throw new SecurityException("Caller " + mCallingUid
20243                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20244            }
20245        }
20246
20247        @Override
20248        public void finishAndRemoveTask() {
20249            checkCaller();
20250
20251            synchronized (ActivityManagerService.this) {
20252                long origId = Binder.clearCallingIdentity();
20253                try {
20254                    if (!removeTaskByIdLocked(mTaskId, false)) {
20255                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20256                    }
20257                } finally {
20258                    Binder.restoreCallingIdentity(origId);
20259                }
20260            }
20261        }
20262
20263        @Override
20264        public ActivityManager.RecentTaskInfo getTaskInfo() {
20265            checkCaller();
20266
20267            synchronized (ActivityManagerService.this) {
20268                long origId = Binder.clearCallingIdentity();
20269                try {
20270                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20271                    if (tr == null) {
20272                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20273                    }
20274                    return createRecentTaskInfoFromTaskRecord(tr);
20275                } finally {
20276                    Binder.restoreCallingIdentity(origId);
20277                }
20278            }
20279        }
20280
20281        @Override
20282        public void moveToFront() {
20283            checkCaller();
20284            // Will bring task to front if it already has a root activity.
20285            startActivityFromRecentsInner(mTaskId, null);
20286        }
20287
20288        @Override
20289        public int startActivity(IBinder whoThread, String callingPackage,
20290                Intent intent, String resolvedType, Bundle options) {
20291            checkCaller();
20292
20293            int callingUser = UserHandle.getCallingUserId();
20294            TaskRecord tr;
20295            IApplicationThread appThread;
20296            synchronized (ActivityManagerService.this) {
20297                tr = mRecentTasks.taskForIdLocked(mTaskId);
20298                if (tr == null) {
20299                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20300                }
20301                appThread = ApplicationThreadNative.asInterface(whoThread);
20302                if (appThread == null) {
20303                    throw new IllegalArgumentException("Bad app thread " + appThread);
20304                }
20305            }
20306            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20307                    resolvedType, null, null, null, null, 0, 0, null, null,
20308                    null, options, callingUser, null, tr);
20309        }
20310
20311        @Override
20312        public void setExcludeFromRecents(boolean exclude) {
20313            checkCaller();
20314
20315            synchronized (ActivityManagerService.this) {
20316                long origId = Binder.clearCallingIdentity();
20317                try {
20318                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20319                    if (tr == null) {
20320                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20321                    }
20322                    Intent intent = tr.getBaseIntent();
20323                    if (exclude) {
20324                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20325                    } else {
20326                        intent.setFlags(intent.getFlags()
20327                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20328                    }
20329                } finally {
20330                    Binder.restoreCallingIdentity(origId);
20331                }
20332            }
20333        }
20334    }
20335}
20336