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_PRIV;
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.BroadcastOptions;
43import android.app.IActivityContainer;
44import android.app.IActivityContainerCallback;
45import android.app.IAppTask;
46import android.app.ITaskStackListener;
47import android.app.ProfilerInfo;
48import android.app.assist.AssistContent;
49import android.app.assist.AssistStructure;
50import android.app.usage.UsageEvents;
51import android.app.usage.UsageStatsManagerInternal;
52import android.appwidget.AppWidgetManager;
53import android.content.pm.PermissionInfo;
54import android.content.res.Resources;
55import android.graphics.Bitmap;
56import android.graphics.Point;
57import android.graphics.Rect;
58import android.os.BatteryStats;
59import android.os.PersistableBundle;
60import android.os.PowerManager;
61import android.os.Trace;
62import android.os.TransactionTooLargeException;
63import android.os.WorkSource;
64import android.os.storage.IMountService;
65import android.os.storage.MountServiceInternal;
66import android.os.storage.StorageManager;
67import android.service.voice.IVoiceInteractionSession;
68import android.service.voice.VoiceInteractionSession;
69import android.util.ArrayMap;
70import android.util.ArraySet;
71import android.util.DebugUtils;
72import android.util.SparseIntArray;
73import android.view.Display;
74
75import com.android.internal.R;
76import com.android.internal.annotations.GuardedBy;
77import com.android.internal.app.AssistUtils;
78import com.android.internal.app.DumpHeapActivity;
79import com.android.internal.app.IAppOpsService;
80import com.android.internal.app.IVoiceInteractor;
81import com.android.internal.app.ProcessMap;
82import com.android.internal.app.ProcessStats;
83import com.android.internal.os.BackgroundThread;
84import com.android.internal.os.BatteryStatsImpl;
85import com.android.internal.os.IResultReceiver;
86import com.android.internal.os.ProcessCpuTracker;
87import com.android.internal.os.TransferPipe;
88import com.android.internal.os.Zygote;
89import com.android.internal.util.ArrayUtils;
90import com.android.internal.util.FastPrintWriter;
91import com.android.internal.util.FastXmlSerializer;
92import com.android.internal.util.MemInfoReader;
93import com.android.internal.util.Preconditions;
94import com.android.server.AppOpsService;
95import com.android.server.AttributeCache;
96import com.android.server.DeviceIdleController;
97import com.android.server.IntentResolver;
98import com.android.server.LocalServices;
99import com.android.server.ServiceThread;
100import com.android.server.SystemService;
101import com.android.server.SystemServiceManager;
102import com.android.server.Watchdog;
103import com.android.server.am.ActivityStack.ActivityState;
104import com.android.server.firewall.IntentFirewall;
105import com.android.server.pm.Installer;
106import com.android.server.pm.UserManagerService;
107import com.android.server.statusbar.StatusBarManagerInternal;
108import com.android.server.wm.AppTransition;
109import com.android.server.wm.WindowManagerService;
110import com.google.android.collect.Lists;
111import com.google.android.collect.Maps;
112
113import libcore.io.IoUtils;
114import libcore.util.EmptyArray;
115
116import org.xmlpull.v1.XmlPullParser;
117import org.xmlpull.v1.XmlPullParserException;
118import org.xmlpull.v1.XmlSerializer;
119
120import android.app.Activity;
121import android.app.ActivityManager;
122import android.app.ActivityManager.RunningTaskInfo;
123import android.app.ActivityManager.StackInfo;
124import android.app.ActivityManagerInternal;
125import android.app.ActivityManagerInternal.SleepToken;
126import android.app.ActivityManagerNative;
127import android.app.ActivityOptions;
128import android.app.ActivityThread;
129import android.app.AlertDialog;
130import android.app.AppGlobals;
131import android.app.ApplicationErrorReport;
132import android.app.Dialog;
133import android.app.IActivityController;
134import android.app.IApplicationThread;
135import android.app.IInstrumentationWatcher;
136import android.app.INotificationManager;
137import android.app.IProcessObserver;
138import android.app.IServiceConnection;
139import android.app.IStopUserCallback;
140import android.app.IUidObserver;
141import android.app.IUiAutomationConnection;
142import android.app.IUserSwitchObserver;
143import android.app.Instrumentation;
144import android.app.Notification;
145import android.app.NotificationManager;
146import android.app.PendingIntent;
147import android.app.backup.IBackupManager;
148import android.app.admin.DevicePolicyManager;
149import android.content.ActivityNotFoundException;
150import android.content.BroadcastReceiver;
151import android.content.ClipData;
152import android.content.ComponentCallbacks2;
153import android.content.ComponentName;
154import android.content.ContentProvider;
155import android.content.ContentResolver;
156import android.content.Context;
157import android.content.DialogInterface;
158import android.content.IContentProvider;
159import android.content.IIntentReceiver;
160import android.content.IIntentSender;
161import android.content.Intent;
162import android.content.IntentFilter;
163import android.content.IntentSender;
164import android.content.pm.ActivityInfo;
165import android.content.pm.ApplicationInfo;
166import android.content.pm.ConfigurationInfo;
167import android.content.pm.IPackageDataObserver;
168import android.content.pm.IPackageManager;
169import android.content.pm.InstrumentationInfo;
170import android.content.pm.PackageInfo;
171import android.content.pm.PackageManager;
172import android.content.pm.ParceledListSlice;
173import android.content.pm.UserInfo;
174import android.content.pm.PackageManager.NameNotFoundException;
175import android.content.pm.PathPermission;
176import android.content.pm.ProviderInfo;
177import android.content.pm.ResolveInfo;
178import android.content.pm.ServiceInfo;
179import android.content.res.CompatibilityInfo;
180import android.content.res.Configuration;
181import android.net.Proxy;
182import android.net.ProxyInfo;
183import android.net.Uri;
184import android.os.Binder;
185import android.os.Build;
186import android.os.Bundle;
187import android.os.Debug;
188import android.os.DropBoxManager;
189import android.os.Environment;
190import android.os.FactoryTest;
191import android.os.FileObserver;
192import android.os.FileUtils;
193import android.os.Handler;
194import android.os.IBinder;
195import android.os.IPermissionController;
196import android.os.IProcessInfoService;
197import android.os.IRemoteCallback;
198import android.os.IUserManager;
199import android.os.Looper;
200import android.os.Message;
201import android.os.Parcel;
202import android.os.ParcelFileDescriptor;
203import android.os.PowerManagerInternal;
204import android.os.Process;
205import android.os.RemoteCallbackList;
206import android.os.RemoteException;
207import android.os.SELinux;
208import android.os.ServiceManager;
209import android.os.StrictMode;
210import android.os.SystemClock;
211import android.os.SystemProperties;
212import android.os.UpdateLock;
213import android.os.UserHandle;
214import android.os.UserManager;
215import android.provider.Settings;
216import android.text.format.DateUtils;
217import android.text.format.Time;
218import android.util.AtomicFile;
219import android.util.EventLog;
220import android.util.Log;
221import android.util.Pair;
222import android.util.PrintWriterPrinter;
223import android.util.Slog;
224import android.util.SparseArray;
225import android.util.TimeUtils;
226import android.util.Xml;
227import android.view.Gravity;
228import android.view.LayoutInflater;
229import android.view.View;
230import android.view.WindowManager;
231
232import dalvik.system.VMRuntime;
233
234import java.io.BufferedInputStream;
235import java.io.BufferedOutputStream;
236import java.io.DataInputStream;
237import java.io.DataOutputStream;
238import java.io.File;
239import java.io.FileDescriptor;
240import java.io.FileInputStream;
241import java.io.FileNotFoundException;
242import java.io.FileOutputStream;
243import java.io.IOException;
244import java.io.InputStreamReader;
245import java.io.PrintWriter;
246import java.io.StringWriter;
247import java.lang.ref.WeakReference;
248import java.nio.charset.StandardCharsets;
249import java.util.ArrayList;
250import java.util.Arrays;
251import java.util.Collections;
252import java.util.Comparator;
253import java.util.HashMap;
254import java.util.HashSet;
255import java.util.Iterator;
256import java.util.List;
257import java.util.Locale;
258import java.util.Map;
259import java.util.Set;
260import java.util.concurrent.atomic.AtomicBoolean;
261import java.util.concurrent.atomic.AtomicLong;
262
263public final class ActivityManagerService extends ActivityManagerNative
264        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
265
266    // File that stores last updated system version and called preboot receivers
267    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
268
269    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
270    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
271    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
272    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
273    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
274    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
275    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
276    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
277    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
278    private static final String TAG_LRU = TAG + POSTFIX_LRU;
279    private static final String TAG_MU = TAG + POSTFIX_MU;
280    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
281    private static final String TAG_POWER = TAG + POSTFIX_POWER;
282    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
283    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
284    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
285    private static final String TAG_PSS = TAG + POSTFIX_PSS;
286    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
287    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
288    private static final String TAG_STACK = TAG + POSTFIX_STACK;
289    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
290    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
291    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
292    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
293    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
294
295    /** Control over CPU and battery monitoring */
296    // write battery stats every 30 minutes.
297    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
298    static final boolean MONITOR_CPU_USAGE = true;
299    // don't sample cpu less than every 5 seconds.
300    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
301    // wait possibly forever for next cpu sample.
302    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
303    static final boolean MONITOR_THREAD_CPU_USAGE = false;
304
305    // The flags that are set for all calls we make to the package manager.
306    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
307
308    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
309
310    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
311
312    // Amount of time after a call to stopAppSwitches() during which we will
313    // prevent further untrusted switches from happening.
314    static final long APP_SWITCH_DELAY_TIME = 5*1000;
315
316    // How long we wait for a launched process to attach to the activity manager
317    // before we decide it's never going to come up for real.
318    static final int PROC_START_TIMEOUT = 10*1000;
319
320    // How long we wait for a launched process to attach to the activity manager
321    // before we decide it's never going to come up for real, when the process was
322    // started with a wrapper for instrumentation (such as Valgrind) because it
323    // could take much longer than usual.
324    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
325
326    // How long to wait after going idle before forcing apps to GC.
327    static final int GC_TIMEOUT = 5*1000;
328
329    // The minimum amount of time between successive GC requests for a process.
330    static final int GC_MIN_INTERVAL = 60*1000;
331
332    // The minimum amount of time between successive PSS requests for a process.
333    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
334
335    // The minimum amount of time between successive PSS requests for a process
336    // when the request is due to the memory state being lowered.
337    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
338
339    // The rate at which we check for apps using excessive power -- 15 mins.
340    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
341
342    // The minimum sample duration we will allow before deciding we have
343    // enough data on wake locks to start killing things.
344    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
345
346    // The minimum sample duration we will allow before deciding we have
347    // enough data on CPU usage to start killing things.
348    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
349
350    // How long we allow a receiver to run before giving up on it.
351    static final int BROADCAST_FG_TIMEOUT = 10*1000;
352    static final int BROADCAST_BG_TIMEOUT = 60*1000;
353
354    // How long we wait until we timeout on key dispatching.
355    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
356
357    // How long we wait until we timeout on key dispatching during instrumentation.
358    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
359
360    // Amount of time we wait for observers to handle a user switch before
361    // giving up on them and unfreezing the screen.
362    static final int USER_SWITCH_TIMEOUT = 2*1000;
363
364    // This is the amount of time an app needs to be running a foreground service before
365    // we will consider it to be doing interaction for usage stats.
366    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
367
368    // Maximum number of users we allow to be running at a time.
369    static final int MAX_RUNNING_USERS = 3;
370
371    // How long to wait in getAssistContextExtras for the activity and foreground services
372    // to respond with the result.
373    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
374
375    // How long top wait when going through the modern assist (which doesn't need to block
376    // on getting this result before starting to launch its UI).
377    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
378
379    // Maximum number of persisted Uri grants a package is allowed
380    static final int MAX_PERSISTED_URI_GRANTS = 128;
381
382    static final int MY_PID = Process.myPid();
383
384    static final String[] EMPTY_STRING_ARRAY = new String[0];
385
386    // How many bytes to write into the dropbox log before truncating
387    static final int DROPBOX_MAX_SIZE = 256 * 1024;
388
389    // Access modes for handleIncomingUser.
390    static final int ALLOW_NON_FULL = 0;
391    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
392    static final int ALLOW_FULL_ONLY = 2;
393
394    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
395
396    // Delay in notifying task stack change listeners (in millis)
397    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
398
399    // Necessary ApplicationInfo flags to mark an app as persistent
400    private static final int PERSISTENT_MASK =
401            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
402
403    /** All system services */
404    SystemServiceManager mSystemServiceManager;
405
406    private Installer mInstaller;
407
408    /** Run all ActivityStacks through this */
409    ActivityStackSupervisor mStackSupervisor;
410
411    /** Task stack change listeners. */
412    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
413            new RemoteCallbackList<ITaskStackListener>();
414
415    public IntentFirewall mIntentFirewall;
416
417    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
418    // default actuion automatically.  Important for devices without direct input
419    // devices.
420    private boolean mShowDialogs = true;
421
422    BroadcastQueue mFgBroadcastQueue;
423    BroadcastQueue mBgBroadcastQueue;
424    // Convenient for easy iteration over the queues. Foreground is first
425    // so that dispatch of foreground broadcasts gets precedence.
426    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
427
428    BroadcastQueue broadcastQueueForIntent(Intent intent) {
429        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
430        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
431                "Broadcast intent " + intent + " on "
432                + (isFg ? "foreground" : "background") + " queue");
433        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
434    }
435
436    /**
437     * Activity we have told the window manager to have key focus.
438     */
439    ActivityRecord mFocusedActivity = null;
440
441    /**
442     * User id of the last activity mFocusedActivity was set to.
443     */
444    private int mLastFocusedUserId;
445
446    /**
447     * If non-null, we are tracking the time the user spends in the currently focused app.
448     */
449    private AppTimeTracker mCurAppTimeTracker;
450
451    /**
452     * List of intents that were used to start the most recent tasks.
453     */
454    private final RecentTasks mRecentTasks;
455
456    /**
457     * For addAppTask: cached of the last activity component that was added.
458     */
459    ComponentName mLastAddedTaskComponent;
460
461    /**
462     * For addAppTask: cached of the last activity uid that was added.
463     */
464    int mLastAddedTaskUid;
465
466    /**
467     * For addAppTask: cached of the last ActivityInfo that was added.
468     */
469    ActivityInfo mLastAddedTaskActivity;
470
471    /**
472     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
473     */
474    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
475
476    /**
477     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
478     */
479    String mDeviceOwnerName;
480
481    public class PendingAssistExtras extends Binder implements Runnable {
482        public final ActivityRecord activity;
483        public final Bundle extras;
484        public final Intent intent;
485        public final String hint;
486        public final IResultReceiver receiver;
487        public final int userHandle;
488        public boolean haveResult = false;
489        public Bundle result = null;
490        public AssistStructure structure = null;
491        public AssistContent content = null;
492        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
493                String _hint, IResultReceiver _receiver, int _userHandle) {
494            activity = _activity;
495            extras = _extras;
496            intent = _intent;
497            hint = _hint;
498            receiver = _receiver;
499            userHandle = _userHandle;
500        }
501        @Override
502        public void run() {
503            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
504            synchronized (this) {
505                haveResult = true;
506                notifyAll();
507            }
508            pendingAssistExtrasTimedOut(this);
509        }
510    }
511
512    final ArrayList<PendingAssistExtras> mPendingAssistExtras
513            = new ArrayList<PendingAssistExtras>();
514
515    /**
516     * Process management.
517     */
518    final ProcessList mProcessList = new ProcessList();
519
520    /**
521     * All of the applications we currently have running organized by name.
522     * The keys are strings of the application package name (as
523     * returned by the package manager), and the keys are ApplicationRecord
524     * objects.
525     */
526    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
527
528    /**
529     * Tracking long-term execution of processes to look for abuse and other
530     * bad app behavior.
531     */
532    final ProcessStatsService mProcessStats;
533
534    /**
535     * The currently running isolated processes.
536     */
537    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
538
539    /**
540     * Counter for assigning isolated process uids, to avoid frequently reusing the
541     * same ones.
542     */
543    int mNextIsolatedProcessUid = 0;
544
545    /**
546     * The currently running heavy-weight process, if any.
547     */
548    ProcessRecord mHeavyWeightProcess = null;
549
550    /**
551     * The last time that various processes have crashed.
552     */
553    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
554
555    /**
556     * Information about a process that is currently marked as bad.
557     */
558    static final class BadProcessInfo {
559        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
560            this.time = time;
561            this.shortMsg = shortMsg;
562            this.longMsg = longMsg;
563            this.stack = stack;
564        }
565
566        final long time;
567        final String shortMsg;
568        final String longMsg;
569        final String stack;
570    }
571
572    /**
573     * Set of applications that we consider to be bad, and will reject
574     * incoming broadcasts from (which the user has no control over).
575     * Processes are added to this set when they have crashed twice within
576     * a minimum amount of time; they are removed from it when they are
577     * later restarted (hopefully due to some user action).  The value is the
578     * time it was added to the list.
579     */
580    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
581
582    /**
583     * All of the processes we currently have running organized by pid.
584     * The keys are the pid running the application.
585     *
586     * <p>NOTE: This object is protected by its own lock, NOT the global
587     * activity manager lock!
588     */
589    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
590
591    /**
592     * All of the processes that have been forced to be foreground.  The key
593     * is the pid of the caller who requested it (we hold a death
594     * link on it).
595     */
596    abstract class ForegroundToken implements IBinder.DeathRecipient {
597        int pid;
598        IBinder token;
599    }
600    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
601
602    /**
603     * List of records for processes that someone had tried to start before the
604     * system was ready.  We don't start them at that point, but ensure they
605     * are started by the time booting is complete.
606     */
607    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
608
609    /**
610     * List of persistent applications that are in the process
611     * of being started.
612     */
613    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
614
615    /**
616     * Processes that are being forcibly torn down.
617     */
618    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
619
620    /**
621     * List of running applications, sorted by recent usage.
622     * The first entry in the list is the least recently used.
623     */
624    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
625
626    /**
627     * Where in mLruProcesses that the processes hosting activities start.
628     */
629    int mLruProcessActivityStart = 0;
630
631    /**
632     * Where in mLruProcesses that the processes hosting services start.
633     * This is after (lower index) than mLruProcessesActivityStart.
634     */
635    int mLruProcessServiceStart = 0;
636
637    /**
638     * List of processes that should gc as soon as things are idle.
639     */
640    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
641
642    /**
643     * Processes we want to collect PSS data from.
644     */
645    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
646
647    /**
648     * Last time we requested PSS data of all processes.
649     */
650    long mLastFullPssTime = SystemClock.uptimeMillis();
651
652    /**
653     * If set, the next time we collect PSS data we should do a full collection
654     * with data from native processes and the kernel.
655     */
656    boolean mFullPssPending = false;
657
658    /**
659     * This is the process holding what we currently consider to be
660     * the "home" activity.
661     */
662    ProcessRecord mHomeProcess;
663
664    /**
665     * This is the process holding the activity the user last visited that
666     * is in a different process from the one they are currently in.
667     */
668    ProcessRecord mPreviousProcess;
669
670    /**
671     * The time at which the previous process was last visible.
672     */
673    long mPreviousProcessVisibleTime;
674
675    /**
676     * Track all uids that have actively running processes.
677     */
678    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
679
680    /**
681     * Which users have been started, so are allowed to run code.
682     */
683    final SparseArray<UserState> mStartedUsers = new SparseArray<>();
684
685    /**
686     * LRU list of history of current users.  Most recently current is at the end.
687     */
688    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
689
690    /**
691     * Constant array of the users that are currently started.
692     */
693    int[] mStartedUserArray = new int[] { 0 };
694
695    /**
696     * Registered observers of the user switching mechanics.
697     */
698    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
699            = new RemoteCallbackList<IUserSwitchObserver>();
700
701    /**
702     * Currently active user switch.
703     */
704    Object mCurUserSwitchCallback;
705
706    /**
707     * Packages that the user has asked to have run in screen size
708     * compatibility mode instead of filling the screen.
709     */
710    final CompatModePackages mCompatModePackages;
711
712    /**
713     * Set of IntentSenderRecord objects that are currently active.
714     */
715    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
716            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
717
718    /**
719     * Fingerprints (hashCode()) of stack traces that we've
720     * already logged DropBox entries for.  Guarded by itself.  If
721     * something (rogue user app) forces this over
722     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
723     */
724    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
725    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
726
727    /**
728     * Strict Mode background batched logging state.
729     *
730     * The string buffer is guarded by itself, and its lock is also
731     * used to determine if another batched write is already
732     * in-flight.
733     */
734    private final StringBuilder mStrictModeBuffer = new StringBuilder();
735
736    /**
737     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
738     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
739     */
740    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
741
742    /**
743     * Resolver for broadcast intents to registered receivers.
744     * Holds BroadcastFilter (subclass of IntentFilter).
745     */
746    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
747            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
748        @Override
749        protected boolean allowFilterResult(
750                BroadcastFilter filter, List<BroadcastFilter> dest) {
751            IBinder target = filter.receiverList.receiver.asBinder();
752            for (int i = dest.size() - 1; i >= 0; i--) {
753                if (dest.get(i).receiverList.receiver.asBinder() == target) {
754                    return false;
755                }
756            }
757            return true;
758        }
759
760        @Override
761        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
762            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
763                    || userId == filter.owningUserId) {
764                return super.newResult(filter, match, userId);
765            }
766            return null;
767        }
768
769        @Override
770        protected BroadcastFilter[] newArray(int size) {
771            return new BroadcastFilter[size];
772        }
773
774        @Override
775        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
776            return packageName.equals(filter.packageName);
777        }
778    };
779
780    /**
781     * State of all active sticky broadcasts per user.  Keys are the action of the
782     * sticky Intent, values are an ArrayList of all broadcasted intents with
783     * that action (which should usually be one).  The SparseArray is keyed
784     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
785     * for stickies that are sent to all users.
786     */
787    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
788            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
789
790    final ActiveServices mServices;
791
792    final static class Association {
793        final int mSourceUid;
794        final String mSourceProcess;
795        final int mTargetUid;
796        final ComponentName mTargetComponent;
797        final String mTargetProcess;
798
799        int mCount;
800        long mTime;
801
802        int mNesting;
803        long mStartTime;
804
805        Association(int sourceUid, String sourceProcess, int targetUid,
806                ComponentName targetComponent, String targetProcess) {
807            mSourceUid = sourceUid;
808            mSourceProcess = sourceProcess;
809            mTargetUid = targetUid;
810            mTargetComponent = targetComponent;
811            mTargetProcess = targetProcess;
812        }
813    }
814
815    /**
816     * When service association tracking is enabled, this is all of the associations we
817     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
818     * -> association data.
819     */
820    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
821            mAssociations = new SparseArray<>();
822    boolean mTrackingAssociations;
823
824    /**
825     * Backup/restore process management
826     */
827    String mBackupAppName = null;
828    BackupRecord mBackupTarget = null;
829
830    final ProviderMap mProviderMap;
831
832    /**
833     * List of content providers who have clients waiting for them.  The
834     * application is currently being launched and the provider will be
835     * removed from this list once it is published.
836     */
837    final ArrayList<ContentProviderRecord> mLaunchingProviders
838            = new ArrayList<ContentProviderRecord>();
839
840    /**
841     * File storing persisted {@link #mGrantedUriPermissions}.
842     */
843    private final AtomicFile mGrantFile;
844
845    /** XML constants used in {@link #mGrantFile} */
846    private static final String TAG_URI_GRANTS = "uri-grants";
847    private static final String TAG_URI_GRANT = "uri-grant";
848    private static final String ATTR_USER_HANDLE = "userHandle";
849    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
850    private static final String ATTR_TARGET_USER_ID = "targetUserId";
851    private static final String ATTR_SOURCE_PKG = "sourcePkg";
852    private static final String ATTR_TARGET_PKG = "targetPkg";
853    private static final String ATTR_URI = "uri";
854    private static final String ATTR_MODE_FLAGS = "modeFlags";
855    private static final String ATTR_CREATED_TIME = "createdTime";
856    private static final String ATTR_PREFIX = "prefix";
857
858    /**
859     * Global set of specific {@link Uri} permissions that have been granted.
860     * This optimized lookup structure maps from {@link UriPermission#targetUid}
861     * to {@link UriPermission#uri} to {@link UriPermission}.
862     */
863    @GuardedBy("this")
864    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
865            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
866
867    public static class GrantUri {
868        public final int sourceUserId;
869        public final Uri uri;
870        public boolean prefix;
871
872        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
873            this.sourceUserId = sourceUserId;
874            this.uri = uri;
875            this.prefix = prefix;
876        }
877
878        @Override
879        public int hashCode() {
880            int hashCode = 1;
881            hashCode = 31 * hashCode + sourceUserId;
882            hashCode = 31 * hashCode + uri.hashCode();
883            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
884            return hashCode;
885        }
886
887        @Override
888        public boolean equals(Object o) {
889            if (o instanceof GrantUri) {
890                GrantUri other = (GrantUri) o;
891                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
892                        && prefix == other.prefix;
893            }
894            return false;
895        }
896
897        @Override
898        public String toString() {
899            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
900            if (prefix) result += " [prefix]";
901            return result;
902        }
903
904        public String toSafeString() {
905            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
906            if (prefix) result += " [prefix]";
907            return result;
908        }
909
910        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
911            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
912                    ContentProvider.getUriWithoutUserId(uri), false);
913        }
914    }
915
916    CoreSettingsObserver mCoreSettingsObserver;
917
918    /**
919     * Thread-local storage used to carry caller permissions over through
920     * indirect content-provider access.
921     */
922    private class Identity {
923        public final IBinder token;
924        public final int pid;
925        public final int uid;
926
927        Identity(IBinder _token, int _pid, int _uid) {
928            token = _token;
929            pid = _pid;
930            uid = _uid;
931        }
932    }
933
934    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
935
936    /**
937     * All information we have collected about the runtime performance of
938     * any user id that can impact battery performance.
939     */
940    final BatteryStatsService mBatteryStatsService;
941
942    /**
943     * Information about component usage
944     */
945    UsageStatsManagerInternal mUsageStatsService;
946
947    /**
948     * Access to DeviceIdleController service.
949     */
950    DeviceIdleController.LocalService mLocalDeviceIdleController;
951
952    /**
953     * Information about and control over application operations
954     */
955    final AppOpsService mAppOpsService;
956
957    /**
958     * Save recent tasks information across reboots.
959     */
960    final TaskPersister mTaskPersister;
961
962    /**
963     * Current configuration information.  HistoryRecord objects are given
964     * a reference to this object to indicate which configuration they are
965     * currently running in, so this object must be kept immutable.
966     */
967    Configuration mConfiguration = new Configuration();
968
969    /**
970     * Current sequencing integer of the configuration, for skipping old
971     * configurations.
972     */
973    int mConfigurationSeq = 0;
974
975    /**
976     * Hardware-reported OpenGLES version.
977     */
978    final int GL_ES_VERSION;
979
980    /**
981     * List of initialization arguments to pass to all processes when binding applications to them.
982     * For example, references to the commonly used services.
983     */
984    HashMap<String, IBinder> mAppBindArgs;
985
986    /**
987     * Temporary to avoid allocations.  Protected by main lock.
988     */
989    final StringBuilder mStringBuilder = new StringBuilder(256);
990
991    /**
992     * Used to control how we initialize the service.
993     */
994    ComponentName mTopComponent;
995    String mTopAction = Intent.ACTION_MAIN;
996    String mTopData;
997    boolean mProcessesReady = false;
998    boolean mSystemReady = false;
999    boolean mBooting = false;
1000    boolean mCallFinishBooting = false;
1001    boolean mBootAnimationComplete = false;
1002    boolean mWaitingUpdate = false;
1003    boolean mDidUpdate = false;
1004    boolean mOnBattery = false;
1005    boolean mLaunchWarningShown = false;
1006
1007    Context mContext;
1008
1009    int mFactoryTest;
1010
1011    boolean mCheckedForSetup;
1012
1013    /**
1014     * The time at which we will allow normal application switches again,
1015     * after a call to {@link #stopAppSwitches()}.
1016     */
1017    long mAppSwitchesAllowedTime;
1018
1019    /**
1020     * This is set to true after the first switch after mAppSwitchesAllowedTime
1021     * is set; any switches after that will clear the time.
1022     */
1023    boolean mDidAppSwitch;
1024
1025    /**
1026     * Last time (in realtime) at which we checked for power usage.
1027     */
1028    long mLastPowerCheckRealtime;
1029
1030    /**
1031     * Last time (in uptime) at which we checked for power usage.
1032     */
1033    long mLastPowerCheckUptime;
1034
1035    /**
1036     * Set while we are wanting to sleep, to prevent any
1037     * activities from being started/resumed.
1038     */
1039    private boolean mSleeping = false;
1040
1041    /**
1042     * The process state used for processes that are running the top activities.
1043     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1044     */
1045    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1046
1047    /**
1048     * Set while we are running a voice interaction.  This overrides
1049     * sleeping while it is active.
1050     */
1051    private IVoiceInteractionSession mRunningVoice;
1052
1053    /**
1054     * For some direct access we need to power manager.
1055     */
1056    PowerManagerInternal mLocalPowerManager;
1057
1058    /**
1059     * We want to hold a wake lock while running a voice interaction session, since
1060     * this may happen with the screen off and we need to keep the CPU running to
1061     * be able to continue to interact with the user.
1062     */
1063    PowerManager.WakeLock mVoiceWakeLock;
1064
1065    /**
1066     * State of external calls telling us if the device is awake or asleep.
1067     */
1068    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1069
1070    /**
1071     * A list of tokens that cause the top activity to be put to sleep.
1072     * They are used by components that may hide and block interaction with underlying
1073     * activities.
1074     */
1075    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1076
1077    static final int LOCK_SCREEN_HIDDEN = 0;
1078    static final int LOCK_SCREEN_LEAVING = 1;
1079    static final int LOCK_SCREEN_SHOWN = 2;
1080    /**
1081     * State of external call telling us if the lock screen is shown.
1082     */
1083    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1084
1085    /**
1086     * Set if we are shutting down the system, similar to sleeping.
1087     */
1088    boolean mShuttingDown = false;
1089
1090    /**
1091     * Current sequence id for oom_adj computation traversal.
1092     */
1093    int mAdjSeq = 0;
1094
1095    /**
1096     * Current sequence id for process LRU updating.
1097     */
1098    int mLruSeq = 0;
1099
1100    /**
1101     * Keep track of the non-cached/empty process we last found, to help
1102     * determine how to distribute cached/empty processes next time.
1103     */
1104    int mNumNonCachedProcs = 0;
1105
1106    /**
1107     * Keep track of the number of cached hidden procs, to balance oom adj
1108     * distribution between those and empty procs.
1109     */
1110    int mNumCachedHiddenProcs = 0;
1111
1112    /**
1113     * Keep track of the number of service processes we last found, to
1114     * determine on the next iteration which should be B services.
1115     */
1116    int mNumServiceProcs = 0;
1117    int mNewNumAServiceProcs = 0;
1118    int mNewNumServiceProcs = 0;
1119
1120    /**
1121     * Allow the current computed overall memory level of the system to go down?
1122     * This is set to false when we are killing processes for reasons other than
1123     * memory management, so that the now smaller process list will not be taken as
1124     * an indication that memory is tighter.
1125     */
1126    boolean mAllowLowerMemLevel = false;
1127
1128    /**
1129     * The last computed memory level, for holding when we are in a state that
1130     * processes are going away for other reasons.
1131     */
1132    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1133
1134    /**
1135     * The last total number of process we have, to determine if changes actually look
1136     * like a shrinking number of process due to lower RAM.
1137     */
1138    int mLastNumProcesses;
1139
1140    /**
1141     * The uptime of the last time we performed idle maintenance.
1142     */
1143    long mLastIdleTime = SystemClock.uptimeMillis();
1144
1145    /**
1146     * Total time spent with RAM that has been added in the past since the last idle time.
1147     */
1148    long mLowRamTimeSinceLastIdle = 0;
1149
1150    /**
1151     * If RAM is currently low, when that horrible situation started.
1152     */
1153    long mLowRamStartTime = 0;
1154
1155    /**
1156     * For reporting to battery stats the current top application.
1157     */
1158    private String mCurResumedPackage = null;
1159    private int mCurResumedUid = -1;
1160
1161    /**
1162     * For reporting to battery stats the apps currently running foreground
1163     * service.  The ProcessMap is package/uid tuples; each of these contain
1164     * an array of the currently foreground processes.
1165     */
1166    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1167            = new ProcessMap<ArrayList<ProcessRecord>>();
1168
1169    /**
1170     * This is set if we had to do a delayed dexopt of an app before launching
1171     * it, to increase the ANR timeouts in that case.
1172     */
1173    boolean mDidDexOpt;
1174
1175    /**
1176     * Set if the systemServer made a call to enterSafeMode.
1177     */
1178    boolean mSafeMode;
1179
1180    /**
1181     * If true, we are running under a test environment so will sample PSS from processes
1182     * much more rapidly to try to collect better data when the tests are rapidly
1183     * running through apps.
1184     */
1185    boolean mTestPssMode = false;
1186
1187    String mDebugApp = null;
1188    boolean mWaitForDebugger = false;
1189    boolean mDebugTransient = false;
1190    String mOrigDebugApp = null;
1191    boolean mOrigWaitForDebugger = false;
1192    boolean mAlwaysFinishActivities = false;
1193    IActivityController mController = null;
1194    String mProfileApp = null;
1195    ProcessRecord mProfileProc = null;
1196    String mProfileFile;
1197    ParcelFileDescriptor mProfileFd;
1198    int mSamplingInterval = 0;
1199    boolean mAutoStopProfiler = false;
1200    int mProfileType = 0;
1201    String mOpenGlTraceApp = null;
1202    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1203    String mMemWatchDumpProcName;
1204    String mMemWatchDumpFile;
1205    int mMemWatchDumpPid;
1206    int mMemWatchDumpUid;
1207
1208    final long[] mTmpLong = new long[1];
1209
1210    static final class ProcessChangeItem {
1211        static final int CHANGE_ACTIVITIES = 1<<0;
1212        static final int CHANGE_PROCESS_STATE = 1<<1;
1213        int changes;
1214        int uid;
1215        int pid;
1216        int processState;
1217        boolean foregroundActivities;
1218    }
1219
1220    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1221    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1222
1223    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1224    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1225
1226    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1227    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1228
1229    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1230    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1231
1232    /**
1233     * Runtime CPU use collection thread.  This object's lock is used to
1234     * perform synchronization with the thread (notifying it to run).
1235     */
1236    final Thread mProcessCpuThread;
1237
1238    /**
1239     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1240     * Must acquire this object's lock when accessing it.
1241     * NOTE: this lock will be held while doing long operations (trawling
1242     * through all processes in /proc), so it should never be acquired by
1243     * any critical paths such as when holding the main activity manager lock.
1244     */
1245    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1246            MONITOR_THREAD_CPU_USAGE);
1247    final AtomicLong mLastCpuTime = new AtomicLong(0);
1248    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1249
1250    long mLastWriteTime = 0;
1251
1252    /**
1253     * Used to retain an update lock when the foreground activity is in
1254     * immersive mode.
1255     */
1256    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1257
1258    /**
1259     * Set to true after the system has finished booting.
1260     */
1261    boolean mBooted = false;
1262
1263    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1264    int mProcessLimitOverride = -1;
1265
1266    WindowManagerService mWindowManager;
1267
1268    final ActivityThread mSystemThread;
1269
1270    // Holds the current foreground user's id
1271    int mCurrentUserId = 0;
1272    // Holds the target user's id during a user switch
1273    int mTargetUserId = UserHandle.USER_NULL;
1274    // If there are multiple profiles for the current user, their ids are here
1275    // Currently only the primary user can have managed profiles
1276    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1277
1278    /**
1279     * Mapping from each known user ID to the profile group ID it is associated with.
1280     */
1281    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1282
1283    private UserManagerService mUserManager;
1284
1285    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1286        final ProcessRecord mApp;
1287        final int mPid;
1288        final IApplicationThread mAppThread;
1289
1290        AppDeathRecipient(ProcessRecord app, int pid,
1291                IApplicationThread thread) {
1292            if (DEBUG_ALL) Slog.v(
1293                TAG, "New death recipient " + this
1294                + " for thread " + thread.asBinder());
1295            mApp = app;
1296            mPid = pid;
1297            mAppThread = thread;
1298        }
1299
1300        @Override
1301        public void binderDied() {
1302            if (DEBUG_ALL) Slog.v(
1303                TAG, "Death received in " + this
1304                + " for thread " + mAppThread.asBinder());
1305            synchronized(ActivityManagerService.this) {
1306                appDiedLocked(mApp, mPid, mAppThread, true);
1307            }
1308        }
1309    }
1310
1311    static final int SHOW_ERROR_MSG = 1;
1312    static final int SHOW_NOT_RESPONDING_MSG = 2;
1313    static final int SHOW_FACTORY_ERROR_MSG = 3;
1314    static final int UPDATE_CONFIGURATION_MSG = 4;
1315    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1316    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1317    static final int SERVICE_TIMEOUT_MSG = 12;
1318    static final int UPDATE_TIME_ZONE = 13;
1319    static final int SHOW_UID_ERROR_MSG = 14;
1320    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1321    static final int PROC_START_TIMEOUT_MSG = 20;
1322    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1323    static final int KILL_APPLICATION_MSG = 22;
1324    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1325    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1326    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1327    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1328    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1329    static final int CLEAR_DNS_CACHE_MSG = 28;
1330    static final int UPDATE_HTTP_PROXY_MSG = 29;
1331    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1332    static final int DISPATCH_PROCESSES_CHANGED = 31;
1333    static final int DISPATCH_PROCESS_DIED = 32;
1334    static final int REPORT_MEM_USAGE_MSG = 33;
1335    static final int REPORT_USER_SWITCH_MSG = 34;
1336    static final int CONTINUE_USER_SWITCH_MSG = 35;
1337    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1338    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1339    static final int PERSIST_URI_GRANTS_MSG = 38;
1340    static final int REQUEST_ALL_PSS_MSG = 39;
1341    static final int START_PROFILES_MSG = 40;
1342    static final int UPDATE_TIME = 41;
1343    static final int SYSTEM_USER_START_MSG = 42;
1344    static final int SYSTEM_USER_CURRENT_MSG = 43;
1345    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1346    static final int FINISH_BOOTING_MSG = 45;
1347    static final int START_USER_SWITCH_MSG = 46;
1348    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1349    static final int DISMISS_DIALOG_MSG = 48;
1350    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1351    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1352    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1353    static final int DELETE_DUMPHEAP_MSG = 52;
1354    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1355    static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1356    static final int REPORT_TIME_TRACKER_MSG = 55;
1357    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1358    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1359
1360    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1361    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1362    static final int FIRST_COMPAT_MODE_MSG = 300;
1363    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1364
1365    CompatModeDialog mCompatModeDialog;
1366    long mLastMemUsageReportTime = 0;
1367
1368    /**
1369     * Flag whether the current user is a "monkey", i.e. whether
1370     * the UI is driven by a UI automation tool.
1371     */
1372    private boolean mUserIsMonkey;
1373
1374    /** Flag whether the device has a Recents UI */
1375    boolean mHasRecents;
1376
1377    /** The dimensions of the thumbnails in the Recents UI. */
1378    int mThumbnailWidth;
1379    int mThumbnailHeight;
1380
1381    final ServiceThread mHandlerThread;
1382    final MainHandler mHandler;
1383    final UiHandler mUiHandler;
1384
1385    final class UiHandler extends Handler {
1386        public UiHandler() {
1387            super(com.android.server.UiThread.get().getLooper(), null, true);
1388        }
1389
1390        @Override
1391        public void handleMessage(Message msg) {
1392            switch (msg.what) {
1393            case SHOW_ERROR_MSG: {
1394                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1395                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1396                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1397                synchronized (ActivityManagerService.this) {
1398                    ProcessRecord proc = (ProcessRecord)data.get("app");
1399                    AppErrorResult res = (AppErrorResult) data.get("result");
1400                    if (proc != null && proc.crashDialog != null) {
1401                        Slog.e(TAG, "App already has crash dialog: " + proc);
1402                        if (res != null) {
1403                            res.set(0);
1404                        }
1405                        return;
1406                    }
1407                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1408                            >= Process.FIRST_APPLICATION_UID
1409                            && proc.pid != MY_PID);
1410                    for (int userId : mCurrentProfileIds) {
1411                        isBackground &= (proc.userId != userId);
1412                    }
1413                    if (isBackground && !showBackground) {
1414                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1415                        if (res != null) {
1416                            res.set(0);
1417                        }
1418                        return;
1419                    }
1420                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1421                        Dialog d = new AppErrorDialog(mContext,
1422                                ActivityManagerService.this, res, proc);
1423                        d.show();
1424                        proc.crashDialog = d;
1425                    } else {
1426                        // The device is asleep, so just pretend that the user
1427                        // saw a crash dialog and hit "force quit".
1428                        if (res != null) {
1429                            res.set(0);
1430                        }
1431                    }
1432                }
1433
1434                ensureBootCompleted();
1435            } break;
1436            case SHOW_NOT_RESPONDING_MSG: {
1437                synchronized (ActivityManagerService.this) {
1438                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1439                    ProcessRecord proc = (ProcessRecord)data.get("app");
1440                    if (proc != null && proc.anrDialog != null) {
1441                        Slog.e(TAG, "App already has anr dialog: " + proc);
1442                        return;
1443                    }
1444
1445                    Intent intent = new Intent("android.intent.action.ANR");
1446                    if (!mProcessesReady) {
1447                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1448                                | Intent.FLAG_RECEIVER_FOREGROUND);
1449                    }
1450                    broadcastIntentLocked(null, null, intent,
1451                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1452                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1453
1454                    if (mShowDialogs) {
1455                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1456                                mContext, proc, (ActivityRecord)data.get("activity"),
1457                                msg.arg1 != 0);
1458                        d.show();
1459                        proc.anrDialog = d;
1460                    } else {
1461                        // Just kill the app if there is no dialog to be shown.
1462                        killAppAtUsersRequest(proc, null);
1463                    }
1464                }
1465
1466                ensureBootCompleted();
1467            } break;
1468            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1469                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1470                synchronized (ActivityManagerService.this) {
1471                    ProcessRecord proc = (ProcessRecord) data.get("app");
1472                    if (proc == null) {
1473                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1474                        break;
1475                    }
1476                    if (proc.crashDialog != null) {
1477                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1478                        return;
1479                    }
1480                    AppErrorResult res = (AppErrorResult) data.get("result");
1481                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1482                        Dialog d = new StrictModeViolationDialog(mContext,
1483                                ActivityManagerService.this, res, proc);
1484                        d.show();
1485                        proc.crashDialog = d;
1486                    } else {
1487                        // The device is asleep, so just pretend that the user
1488                        // saw a crash dialog and hit "force quit".
1489                        res.set(0);
1490                    }
1491                }
1492                ensureBootCompleted();
1493            } break;
1494            case SHOW_FACTORY_ERROR_MSG: {
1495                Dialog d = new FactoryErrorDialog(
1496                    mContext, msg.getData().getCharSequence("msg"));
1497                d.show();
1498                ensureBootCompleted();
1499            } break;
1500            case WAIT_FOR_DEBUGGER_MSG: {
1501                synchronized (ActivityManagerService.this) {
1502                    ProcessRecord app = (ProcessRecord)msg.obj;
1503                    if (msg.arg1 != 0) {
1504                        if (!app.waitedForDebugger) {
1505                            Dialog d = new AppWaitingForDebuggerDialog(
1506                                    ActivityManagerService.this,
1507                                    mContext, app);
1508                            app.waitDialog = d;
1509                            app.waitedForDebugger = true;
1510                            d.show();
1511                        }
1512                    } else {
1513                        if (app.waitDialog != null) {
1514                            app.waitDialog.dismiss();
1515                            app.waitDialog = null;
1516                        }
1517                    }
1518                }
1519            } break;
1520            case SHOW_UID_ERROR_MSG: {
1521                if (mShowDialogs) {
1522                    AlertDialog d = new BaseErrorDialog(mContext);
1523                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1524                    d.setCancelable(false);
1525                    d.setTitle(mContext.getText(R.string.android_system_label));
1526                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1527                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1528                            obtainMessage(DISMISS_DIALOG_MSG, d));
1529                    d.show();
1530                }
1531            } break;
1532            case SHOW_FINGERPRINT_ERROR_MSG: {
1533                if (mShowDialogs) {
1534                    AlertDialog d = new BaseErrorDialog(mContext);
1535                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1536                    d.setCancelable(false);
1537                    d.setTitle(mContext.getText(R.string.android_system_label));
1538                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1539                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1540                            obtainMessage(DISMISS_DIALOG_MSG, d));
1541                    d.show();
1542                }
1543            } break;
1544            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1545                synchronized (ActivityManagerService.this) {
1546                    ActivityRecord ar = (ActivityRecord) msg.obj;
1547                    if (mCompatModeDialog != null) {
1548                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1549                                ar.info.applicationInfo.packageName)) {
1550                            return;
1551                        }
1552                        mCompatModeDialog.dismiss();
1553                        mCompatModeDialog = null;
1554                    }
1555                    if (ar != null && false) {
1556                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1557                                ar.packageName)) {
1558                            int mode = mCompatModePackages.computeCompatModeLocked(
1559                                    ar.info.applicationInfo);
1560                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1561                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1562                                mCompatModeDialog = new CompatModeDialog(
1563                                        ActivityManagerService.this, mContext,
1564                                        ar.info.applicationInfo);
1565                                mCompatModeDialog.show();
1566                            }
1567                        }
1568                    }
1569                }
1570                break;
1571            }
1572            case START_USER_SWITCH_MSG: {
1573                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1574                break;
1575            }
1576            case DISMISS_DIALOG_MSG: {
1577                final Dialog d = (Dialog) msg.obj;
1578                d.dismiss();
1579                break;
1580            }
1581            case DISPATCH_PROCESSES_CHANGED: {
1582                dispatchProcessesChanged();
1583                break;
1584            }
1585            case DISPATCH_PROCESS_DIED: {
1586                final int pid = msg.arg1;
1587                final int uid = msg.arg2;
1588                dispatchProcessDied(pid, uid);
1589                break;
1590            }
1591            case DISPATCH_UIDS_CHANGED_MSG: {
1592                dispatchUidsChanged();
1593            } break;
1594            }
1595        }
1596    }
1597
1598    final class MainHandler extends Handler {
1599        public MainHandler(Looper looper) {
1600            super(looper, null, true);
1601        }
1602
1603        @Override
1604        public void handleMessage(Message msg) {
1605            switch (msg.what) {
1606            case UPDATE_CONFIGURATION_MSG: {
1607                final ContentResolver resolver = mContext.getContentResolver();
1608                Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1609            } break;
1610            case GC_BACKGROUND_PROCESSES_MSG: {
1611                synchronized (ActivityManagerService.this) {
1612                    performAppGcsIfAppropriateLocked();
1613                }
1614            } break;
1615            case SERVICE_TIMEOUT_MSG: {
1616                if (mDidDexOpt) {
1617                    mDidDexOpt = false;
1618                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1619                    nmsg.obj = msg.obj;
1620                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1621                    return;
1622                }
1623                mServices.serviceTimeout((ProcessRecord)msg.obj);
1624            } break;
1625            case UPDATE_TIME_ZONE: {
1626                synchronized (ActivityManagerService.this) {
1627                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1628                        ProcessRecord r = mLruProcesses.get(i);
1629                        if (r.thread != null) {
1630                            try {
1631                                r.thread.updateTimeZone();
1632                            } catch (RemoteException ex) {
1633                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1634                            }
1635                        }
1636                    }
1637                }
1638            } break;
1639            case CLEAR_DNS_CACHE_MSG: {
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.clearDnsCache();
1646                            } catch (RemoteException ex) {
1647                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1648                            }
1649                        }
1650                    }
1651                }
1652            } break;
1653            case UPDATE_HTTP_PROXY_MSG: {
1654                ProxyInfo proxy = (ProxyInfo)msg.obj;
1655                String host = "";
1656                String port = "";
1657                String exclList = "";
1658                Uri pacFileUrl = Uri.EMPTY;
1659                if (proxy != null) {
1660                    host = proxy.getHost();
1661                    port = Integer.toString(proxy.getPort());
1662                    exclList = proxy.getExclusionListAsString();
1663                    pacFileUrl = proxy.getPacFileUrl();
1664                }
1665                synchronized (ActivityManagerService.this) {
1666                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1667                        ProcessRecord r = mLruProcesses.get(i);
1668                        if (r.thread != null) {
1669                            try {
1670                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1671                            } catch (RemoteException ex) {
1672                                Slog.w(TAG, "Failed to update http proxy for: " +
1673                                        r.info.processName);
1674                            }
1675                        }
1676                    }
1677                }
1678            } break;
1679            case PROC_START_TIMEOUT_MSG: {
1680                if (mDidDexOpt) {
1681                    mDidDexOpt = false;
1682                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1683                    nmsg.obj = msg.obj;
1684                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1685                    return;
1686                }
1687                ProcessRecord app = (ProcessRecord)msg.obj;
1688                synchronized (ActivityManagerService.this) {
1689                    processStartTimedOutLocked(app);
1690                }
1691            } break;
1692            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1693                synchronized (ActivityManagerService.this) {
1694                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1695                }
1696            } break;
1697            case KILL_APPLICATION_MSG: {
1698                synchronized (ActivityManagerService.this) {
1699                    int appid = msg.arg1;
1700                    boolean restart = (msg.arg2 == 1);
1701                    Bundle bundle = (Bundle)msg.obj;
1702                    String pkg = bundle.getString("pkg");
1703                    String reason = bundle.getString("reason");
1704                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1705                            false, UserHandle.USER_ALL, reason);
1706                }
1707            } break;
1708            case FINALIZE_PENDING_INTENT_MSG: {
1709                ((PendingIntentRecord)msg.obj).completeFinalize();
1710            } break;
1711            case POST_HEAVY_NOTIFICATION_MSG: {
1712                INotificationManager inm = NotificationManager.getService();
1713                if (inm == null) {
1714                    return;
1715                }
1716
1717                ActivityRecord root = (ActivityRecord)msg.obj;
1718                ProcessRecord process = root.app;
1719                if (process == null) {
1720                    return;
1721                }
1722
1723                try {
1724                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1725                    String text = mContext.getString(R.string.heavy_weight_notification,
1726                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1727                    Notification notification = new Notification.Builder(context)
1728                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1729                            .setWhen(0)
1730                            .setOngoing(true)
1731                            .setTicker(text)
1732                            .setColor(mContext.getColor(
1733                                    com.android.internal.R.color.system_notification_accent_color))
1734                            .setContentTitle(text)
1735                            .setContentText(
1736                                    mContext.getText(R.string.heavy_weight_notification_detail))
1737                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1738                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1739                                    new UserHandle(root.userId)))
1740                            .build();
1741                    try {
1742                        int[] outId = new int[1];
1743                        inm.enqueueNotificationWithTag("android", "android", null,
1744                                R.string.heavy_weight_notification,
1745                                notification, outId, root.userId);
1746                    } catch (RuntimeException e) {
1747                        Slog.w(ActivityManagerService.TAG,
1748                                "Error showing notification for heavy-weight app", e);
1749                    } catch (RemoteException e) {
1750                    }
1751                } catch (NameNotFoundException e) {
1752                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1753                }
1754            } break;
1755            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1756                INotificationManager inm = NotificationManager.getService();
1757                if (inm == null) {
1758                    return;
1759                }
1760                try {
1761                    inm.cancelNotificationWithTag("android", null,
1762                            R.string.heavy_weight_notification,  msg.arg1);
1763                } catch (RuntimeException e) {
1764                    Slog.w(ActivityManagerService.TAG,
1765                            "Error canceling notification for service", e);
1766                } catch (RemoteException e) {
1767                }
1768            } break;
1769            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1770                synchronized (ActivityManagerService.this) {
1771                    checkExcessivePowerUsageLocked(true);
1772                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1773                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1774                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1775                }
1776            } break;
1777            case REPORT_MEM_USAGE_MSG: {
1778                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1779                Thread thread = new Thread() {
1780                    @Override public void run() {
1781                        reportMemUsage(memInfos);
1782                    }
1783                };
1784                thread.start();
1785                break;
1786            }
1787            case REPORT_USER_SWITCH_MSG: {
1788                dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1789                break;
1790            }
1791            case CONTINUE_USER_SWITCH_MSG: {
1792                continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1793                break;
1794            }
1795            case USER_SWITCH_TIMEOUT_MSG: {
1796                timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1797                break;
1798            }
1799            case IMMERSIVE_MODE_LOCK_MSG: {
1800                final boolean nextState = (msg.arg1 != 0);
1801                if (mUpdateLock.isHeld() != nextState) {
1802                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1803                            "Applying new update lock state '" + nextState
1804                            + "' for " + (ActivityRecord)msg.obj);
1805                    if (nextState) {
1806                        mUpdateLock.acquire();
1807                    } else {
1808                        mUpdateLock.release();
1809                    }
1810                }
1811                break;
1812            }
1813            case PERSIST_URI_GRANTS_MSG: {
1814                writeGrantedUriPermissions();
1815                break;
1816            }
1817            case REQUEST_ALL_PSS_MSG: {
1818                synchronized (ActivityManagerService.this) {
1819                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1820                }
1821                break;
1822            }
1823            case START_PROFILES_MSG: {
1824                synchronized (ActivityManagerService.this) {
1825                    startProfilesLocked();
1826                }
1827                break;
1828            }
1829            case UPDATE_TIME: {
1830                synchronized (ActivityManagerService.this) {
1831                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1832                        ProcessRecord r = mLruProcesses.get(i);
1833                        if (r.thread != null) {
1834                            try {
1835                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1836                            } catch (RemoteException ex) {
1837                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1838                            }
1839                        }
1840                    }
1841                }
1842                break;
1843            }
1844            case SYSTEM_USER_START_MSG: {
1845                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1846                        Integer.toString(msg.arg1), msg.arg1);
1847                mSystemServiceManager.startUser(msg.arg1);
1848                break;
1849            }
1850            case SYSTEM_USER_CURRENT_MSG: {
1851                mBatteryStatsService.noteEvent(
1852                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1853                        Integer.toString(msg.arg2), msg.arg2);
1854                mBatteryStatsService.noteEvent(
1855                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1856                        Integer.toString(msg.arg1), msg.arg1);
1857                mSystemServiceManager.switchUser(msg.arg1);
1858                break;
1859            }
1860            case ENTER_ANIMATION_COMPLETE_MSG: {
1861                synchronized (ActivityManagerService.this) {
1862                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1863                    if (r != null && r.app != null && r.app.thread != null) {
1864                        try {
1865                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1866                        } catch (RemoteException e) {
1867                        }
1868                    }
1869                }
1870                break;
1871            }
1872            case FINISH_BOOTING_MSG: {
1873                if (msg.arg1 != 0) {
1874                    finishBooting();
1875                }
1876                if (msg.arg2 != 0) {
1877                    enableScreenAfterBoot();
1878                }
1879                break;
1880            }
1881            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1882                try {
1883                    Locale l = (Locale) msg.obj;
1884                    IBinder service = ServiceManager.getService("mount");
1885                    IMountService mountService = IMountService.Stub.asInterface(service);
1886                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1887                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1888                } catch (RemoteException e) {
1889                    Log.e(TAG, "Error storing locale for decryption UI", e);
1890                }
1891                break;
1892            }
1893            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1894                synchronized (ActivityManagerService.this) {
1895                    int i = mTaskStackListeners.beginBroadcast();
1896                    while (i > 0) {
1897                        i--;
1898                        try {
1899                            // Make a one-way callback to the listener
1900                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1901                        } catch (RemoteException e){
1902                            // Handled by the RemoteCallbackList
1903                        }
1904                    }
1905                    mTaskStackListeners.finishBroadcast();
1906                }
1907                break;
1908            }
1909            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1910                final int uid = msg.arg1;
1911                final byte[] firstPacket = (byte[]) msg.obj;
1912
1913                synchronized (mPidsSelfLocked) {
1914                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1915                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1916                        if (p.uid == uid) {
1917                            try {
1918                                p.thread.notifyCleartextNetwork(firstPacket);
1919                            } catch (RemoteException ignored) {
1920                            }
1921                        }
1922                    }
1923                }
1924                break;
1925            }
1926            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1927                final String procName;
1928                final int uid;
1929                final long memLimit;
1930                final String reportPackage;
1931                synchronized (ActivityManagerService.this) {
1932                    procName = mMemWatchDumpProcName;
1933                    uid = mMemWatchDumpUid;
1934                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1935                    if (val == null) {
1936                        val = mMemWatchProcesses.get(procName, 0);
1937                    }
1938                    if (val != null) {
1939                        memLimit = val.first;
1940                        reportPackage = val.second;
1941                    } else {
1942                        memLimit = 0;
1943                        reportPackage = null;
1944                    }
1945                }
1946                if (procName == null) {
1947                    return;
1948                }
1949
1950                if (DEBUG_PSS) Slog.d(TAG_PSS,
1951                        "Showing dump heap notification from " + procName + "/" + uid);
1952
1953                INotificationManager inm = NotificationManager.getService();
1954                if (inm == null) {
1955                    return;
1956                }
1957
1958                String text = mContext.getString(R.string.dump_heap_notification, procName);
1959
1960
1961                Intent deleteIntent = new Intent();
1962                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1963                Intent intent = new Intent();
1964                intent.setClassName("android", DumpHeapActivity.class.getName());
1965                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1966                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1967                if (reportPackage != null) {
1968                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1969                }
1970                int userId = UserHandle.getUserId(uid);
1971                Notification notification = new Notification.Builder(mContext)
1972                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1973                        .setWhen(0)
1974                        .setOngoing(true)
1975                        .setAutoCancel(true)
1976                        .setTicker(text)
1977                        .setColor(mContext.getColor(
1978                                com.android.internal.R.color.system_notification_accent_color))
1979                        .setContentTitle(text)
1980                        .setContentText(
1981                                mContext.getText(R.string.dump_heap_notification_detail))
1982                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1983                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1984                                new UserHandle(userId)))
1985                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
1986                                deleteIntent, 0, UserHandle.OWNER))
1987                        .build();
1988
1989                try {
1990                    int[] outId = new int[1];
1991                    inm.enqueueNotificationWithTag("android", "android", null,
1992                            R.string.dump_heap_notification,
1993                            notification, outId, userId);
1994                } catch (RuntimeException e) {
1995                    Slog.w(ActivityManagerService.TAG,
1996                            "Error showing notification for dump heap", e);
1997                } catch (RemoteException e) {
1998                }
1999            } break;
2000            case DELETE_DUMPHEAP_MSG: {
2001                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2002                        DumpHeapActivity.JAVA_URI,
2003                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2004                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2005                        UserHandle.myUserId());
2006                synchronized (ActivityManagerService.this) {
2007                    mMemWatchDumpFile = null;
2008                    mMemWatchDumpProcName = null;
2009                    mMemWatchDumpPid = -1;
2010                    mMemWatchDumpUid = -1;
2011                }
2012            } break;
2013            case FOREGROUND_PROFILE_CHANGED_MSG: {
2014                dispatchForegroundProfileChanged(msg.arg1);
2015            } break;
2016            case REPORT_TIME_TRACKER_MSG: {
2017                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2018                tracker.deliverResult(mContext);
2019            } break;
2020            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2021                dispatchUserSwitchComplete(msg.arg1);
2022            } break;
2023            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2024                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2025                try {
2026                    connection.shutdown();
2027                } catch (RemoteException e) {
2028                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2029                }
2030                // Only a UiAutomation can set this flag and now that
2031                // it is finished we make sure it is reset to its default.
2032                mUserIsMonkey = false;
2033            } break;
2034            }
2035        }
2036    };
2037
2038    static final int COLLECT_PSS_BG_MSG = 1;
2039
2040    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2041        @Override
2042        public void handleMessage(Message msg) {
2043            switch (msg.what) {
2044            case COLLECT_PSS_BG_MSG: {
2045                long start = SystemClock.uptimeMillis();
2046                MemInfoReader memInfo = null;
2047                synchronized (ActivityManagerService.this) {
2048                    if (mFullPssPending) {
2049                        mFullPssPending = false;
2050                        memInfo = new MemInfoReader();
2051                    }
2052                }
2053                if (memInfo != null) {
2054                    updateCpuStatsNow();
2055                    long nativeTotalPss = 0;
2056                    synchronized (mProcessCpuTracker) {
2057                        final int N = mProcessCpuTracker.countStats();
2058                        for (int j=0; j<N; j++) {
2059                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2060                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2061                                // This is definitely an application process; skip it.
2062                                continue;
2063                            }
2064                            synchronized (mPidsSelfLocked) {
2065                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2066                                    // This is one of our own processes; skip it.
2067                                    continue;
2068                                }
2069                            }
2070                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2071                        }
2072                    }
2073                    memInfo.readMemInfo();
2074                    synchronized (ActivityManagerService.this) {
2075                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2076                                + (SystemClock.uptimeMillis()-start) + "ms");
2077                        final long cachedKb = memInfo.getCachedSizeKb();
2078                        final long freeKb = memInfo.getFreeSizeKb();
2079                        final long zramKb = memInfo.getZramTotalSizeKb();
2080                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2081                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2082                                kernelKb*1024, nativeTotalPss*1024);
2083                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2084                                nativeTotalPss);
2085                    }
2086                }
2087
2088                int num = 0;
2089                long[] tmp = new long[1];
2090                do {
2091                    ProcessRecord proc;
2092                    int procState;
2093                    int pid;
2094                    long lastPssTime;
2095                    synchronized (ActivityManagerService.this) {
2096                        if (mPendingPssProcesses.size() <= 0) {
2097                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2098                                    "Collected PSS of " + num + " processes in "
2099                                    + (SystemClock.uptimeMillis() - start) + "ms");
2100                            mPendingPssProcesses.clear();
2101                            return;
2102                        }
2103                        proc = mPendingPssProcesses.remove(0);
2104                        procState = proc.pssProcState;
2105                        lastPssTime = proc.lastPssTime;
2106                        if (proc.thread != null && procState == proc.setProcState
2107                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2108                                        < SystemClock.uptimeMillis()) {
2109                            pid = proc.pid;
2110                        } else {
2111                            proc = null;
2112                            pid = 0;
2113                        }
2114                    }
2115                    if (proc != null) {
2116                        long pss = Debug.getPss(pid, tmp, null);
2117                        synchronized (ActivityManagerService.this) {
2118                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2119                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2120                                num++;
2121                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2122                                        SystemClock.uptimeMillis());
2123                            }
2124                        }
2125                    }
2126                } while (true);
2127            }
2128            }
2129        }
2130    };
2131
2132    public void setSystemProcess() {
2133        try {
2134            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2135            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2136            ServiceManager.addService("meminfo", new MemBinder(this));
2137            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2138            ServiceManager.addService("dbinfo", new DbBinder(this));
2139            if (MONITOR_CPU_USAGE) {
2140                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2141            }
2142            ServiceManager.addService("permission", new PermissionController(this));
2143            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2144
2145            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2146                    "android", STOCK_PM_FLAGS);
2147            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2148
2149            synchronized (this) {
2150                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2151                app.persistent = true;
2152                app.pid = MY_PID;
2153                app.maxAdj = ProcessList.SYSTEM_ADJ;
2154                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2155                synchronized (mPidsSelfLocked) {
2156                    mPidsSelfLocked.put(app.pid, app);
2157                }
2158                updateLruProcessLocked(app, false, null);
2159                updateOomAdjLocked();
2160            }
2161        } catch (PackageManager.NameNotFoundException e) {
2162            throw new RuntimeException(
2163                    "Unable to find android system package", e);
2164        }
2165    }
2166
2167    public void setWindowManager(WindowManagerService wm) {
2168        mWindowManager = wm;
2169        mStackSupervisor.setWindowManager(wm);
2170    }
2171
2172    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2173        mUsageStatsService = usageStatsManager;
2174    }
2175
2176    public void startObservingNativeCrashes() {
2177        final NativeCrashListener ncl = new NativeCrashListener(this);
2178        ncl.start();
2179    }
2180
2181    public IAppOpsService getAppOpsService() {
2182        return mAppOpsService;
2183    }
2184
2185    static class MemBinder extends Binder {
2186        ActivityManagerService mActivityManagerService;
2187        MemBinder(ActivityManagerService activityManagerService) {
2188            mActivityManagerService = activityManagerService;
2189        }
2190
2191        @Override
2192        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2193            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2194                    != PackageManager.PERMISSION_GRANTED) {
2195                pw.println("Permission Denial: can't dump meminfo from from pid="
2196                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2197                        + " without permission " + android.Manifest.permission.DUMP);
2198                return;
2199            }
2200
2201            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2202        }
2203    }
2204
2205    static class GraphicsBinder extends Binder {
2206        ActivityManagerService mActivityManagerService;
2207        GraphicsBinder(ActivityManagerService activityManagerService) {
2208            mActivityManagerService = activityManagerService;
2209        }
2210
2211        @Override
2212        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2213            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2214                    != PackageManager.PERMISSION_GRANTED) {
2215                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2216                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2217                        + " without permission " + android.Manifest.permission.DUMP);
2218                return;
2219            }
2220
2221            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2222        }
2223    }
2224
2225    static class DbBinder extends Binder {
2226        ActivityManagerService mActivityManagerService;
2227        DbBinder(ActivityManagerService activityManagerService) {
2228            mActivityManagerService = activityManagerService;
2229        }
2230
2231        @Override
2232        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2233            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2234                    != PackageManager.PERMISSION_GRANTED) {
2235                pw.println("Permission Denial: can't dump dbinfo from from pid="
2236                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2237                        + " without permission " + android.Manifest.permission.DUMP);
2238                return;
2239            }
2240
2241            mActivityManagerService.dumpDbInfo(fd, pw, args);
2242        }
2243    }
2244
2245    static class CpuBinder extends Binder {
2246        ActivityManagerService mActivityManagerService;
2247        CpuBinder(ActivityManagerService activityManagerService) {
2248            mActivityManagerService = activityManagerService;
2249        }
2250
2251        @Override
2252        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2253            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2254                    != PackageManager.PERMISSION_GRANTED) {
2255                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2256                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2257                        + " without permission " + android.Manifest.permission.DUMP);
2258                return;
2259            }
2260
2261            synchronized (mActivityManagerService.mProcessCpuTracker) {
2262                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2263                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2264                        SystemClock.uptimeMillis()));
2265            }
2266        }
2267    }
2268
2269    public static final class Lifecycle extends SystemService {
2270        private final ActivityManagerService mService;
2271
2272        public Lifecycle(Context context) {
2273            super(context);
2274            mService = new ActivityManagerService(context);
2275        }
2276
2277        @Override
2278        public void onStart() {
2279            mService.start();
2280        }
2281
2282        public ActivityManagerService getService() {
2283            return mService;
2284        }
2285    }
2286
2287    // Note: This method is invoked on the main thread but may need to attach various
2288    // handlers to other threads.  So take care to be explicit about the looper.
2289    public ActivityManagerService(Context systemContext) {
2290        mContext = systemContext;
2291        mFactoryTest = FactoryTest.getMode();
2292        mSystemThread = ActivityThread.currentActivityThread();
2293
2294        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2295
2296        mHandlerThread = new ServiceThread(TAG,
2297                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2298        mHandlerThread.start();
2299        mHandler = new MainHandler(mHandlerThread.getLooper());
2300        mUiHandler = new UiHandler();
2301
2302        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2303                "foreground", BROADCAST_FG_TIMEOUT, false);
2304        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2305                "background", BROADCAST_BG_TIMEOUT, true);
2306        mBroadcastQueues[0] = mFgBroadcastQueue;
2307        mBroadcastQueues[1] = mBgBroadcastQueue;
2308
2309        mServices = new ActiveServices(this);
2310        mProviderMap = new ProviderMap(this);
2311
2312        // TODO: Move creation of battery stats service outside of activity manager service.
2313        File dataDir = Environment.getDataDirectory();
2314        File systemDir = new File(dataDir, "system");
2315        systemDir.mkdirs();
2316        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2317        mBatteryStatsService.getActiveStatistics().readLocked();
2318        mBatteryStatsService.scheduleWriteToDisk();
2319        mOnBattery = DEBUG_POWER ? true
2320                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2321        mBatteryStatsService.getActiveStatistics().setCallback(this);
2322
2323        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2324
2325        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2326
2327        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2328
2329        // User 0 is the first and only user that runs at boot.
2330        mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2331        mUserLru.add(UserHandle.USER_OWNER);
2332        updateStartedUserArrayLocked();
2333
2334        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2335            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2336
2337        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2338
2339        mConfiguration.setToDefaults();
2340        mConfiguration.setLocale(Locale.getDefault());
2341
2342        mConfigurationSeq = mConfiguration.seq = 1;
2343        mProcessCpuTracker.init();
2344
2345        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2346        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2347        mRecentTasks = new RecentTasks(this);
2348        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2349        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2350
2351        mProcessCpuThread = new Thread("CpuTracker") {
2352            @Override
2353            public void run() {
2354                while (true) {
2355                    try {
2356                        try {
2357                            synchronized(this) {
2358                                final long now = SystemClock.uptimeMillis();
2359                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2360                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2361                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2362                                //        + ", write delay=" + nextWriteDelay);
2363                                if (nextWriteDelay < nextCpuDelay) {
2364                                    nextCpuDelay = nextWriteDelay;
2365                                }
2366                                if (nextCpuDelay > 0) {
2367                                    mProcessCpuMutexFree.set(true);
2368                                    this.wait(nextCpuDelay);
2369                                }
2370                            }
2371                        } catch (InterruptedException e) {
2372                        }
2373                        updateCpuStatsNow();
2374                    } catch (Exception e) {
2375                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2376                    }
2377                }
2378            }
2379        };
2380
2381        Watchdog.getInstance().addMonitor(this);
2382        Watchdog.getInstance().addThread(mHandler);
2383    }
2384
2385    public void setSystemServiceManager(SystemServiceManager mgr) {
2386        mSystemServiceManager = mgr;
2387    }
2388
2389    public void setInstaller(Installer installer) {
2390        mInstaller = installer;
2391    }
2392
2393    private void start() {
2394        Process.removeAllProcessGroups();
2395        mProcessCpuThread.start();
2396
2397        mBatteryStatsService.publish(mContext);
2398        mAppOpsService.publish(mContext);
2399        Slog.d("AppOps", "AppOpsService published");
2400        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2401    }
2402
2403    public void initPowerManagement() {
2404        mStackSupervisor.initPowerManagement();
2405        mBatteryStatsService.initPowerManagement();
2406        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2407        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2408        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2409        mVoiceWakeLock.setReferenceCounted(false);
2410    }
2411
2412    @Override
2413    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2414            throws RemoteException {
2415        if (code == SYSPROPS_TRANSACTION) {
2416            // We need to tell all apps about the system property change.
2417            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2418            synchronized(this) {
2419                final int NP = mProcessNames.getMap().size();
2420                for (int ip=0; ip<NP; ip++) {
2421                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2422                    final int NA = apps.size();
2423                    for (int ia=0; ia<NA; ia++) {
2424                        ProcessRecord app = apps.valueAt(ia);
2425                        if (app.thread != null) {
2426                            procs.add(app.thread.asBinder());
2427                        }
2428                    }
2429                }
2430            }
2431
2432            int N = procs.size();
2433            for (int i=0; i<N; i++) {
2434                Parcel data2 = Parcel.obtain();
2435                try {
2436                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2437                } catch (RemoteException e) {
2438                }
2439                data2.recycle();
2440            }
2441        }
2442        try {
2443            return super.onTransact(code, data, reply, flags);
2444        } catch (RuntimeException e) {
2445            // The activity manager only throws security exceptions, so let's
2446            // log all others.
2447            if (!(e instanceof SecurityException)) {
2448                Slog.wtf(TAG, "Activity Manager Crash", e);
2449            }
2450            throw e;
2451        }
2452    }
2453
2454    void updateCpuStats() {
2455        final long now = SystemClock.uptimeMillis();
2456        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2457            return;
2458        }
2459        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2460            synchronized (mProcessCpuThread) {
2461                mProcessCpuThread.notify();
2462            }
2463        }
2464    }
2465
2466    void updateCpuStatsNow() {
2467        synchronized (mProcessCpuTracker) {
2468            mProcessCpuMutexFree.set(false);
2469            final long now = SystemClock.uptimeMillis();
2470            boolean haveNewCpuStats = false;
2471
2472            if (MONITOR_CPU_USAGE &&
2473                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2474                mLastCpuTime.set(now);
2475                mProcessCpuTracker.update();
2476                if (mProcessCpuTracker.hasGoodLastStats()) {
2477                    haveNewCpuStats = true;
2478                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2479                    //Slog.i(TAG, "Total CPU usage: "
2480                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2481
2482                    // Slog the cpu usage if the property is set.
2483                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2484                        int user = mProcessCpuTracker.getLastUserTime();
2485                        int system = mProcessCpuTracker.getLastSystemTime();
2486                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2487                        int irq = mProcessCpuTracker.getLastIrqTime();
2488                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2489                        int idle = mProcessCpuTracker.getLastIdleTime();
2490
2491                        int total = user + system + iowait + irq + softIrq + idle;
2492                        if (total == 0) total = 1;
2493
2494                        EventLog.writeEvent(EventLogTags.CPU,
2495                                ((user+system+iowait+irq+softIrq) * 100) / total,
2496                                (user * 100) / total,
2497                                (system * 100) / total,
2498                                (iowait * 100) / total,
2499                                (irq * 100) / total,
2500                                (softIrq * 100) / total);
2501                    }
2502                }
2503            }
2504
2505            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2506            synchronized(bstats) {
2507                synchronized(mPidsSelfLocked) {
2508                    if (haveNewCpuStats) {
2509                        if (bstats.startAddingCpuLocked()) {
2510                            int totalUTime = 0;
2511                            int totalSTime = 0;
2512                            final int N = mProcessCpuTracker.countStats();
2513                            for (int i=0; i<N; i++) {
2514                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2515                                if (!st.working) {
2516                                    continue;
2517                                }
2518                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2519                                totalUTime += st.rel_utime;
2520                                totalSTime += st.rel_stime;
2521                                if (pr != null) {
2522                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2523                                    if (ps == null || !ps.isActive()) {
2524                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2525                                                pr.info.uid, pr.processName);
2526                                    }
2527                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2528                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2529                                } else {
2530                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2531                                    if (ps == null || !ps.isActive()) {
2532                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2533                                                bstats.mapUid(st.uid), st.name);
2534                                    }
2535                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2536                                }
2537                            }
2538                            final int userTime = mProcessCpuTracker.getLastUserTime();
2539                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2540                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2541                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2542                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2543                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2544                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2545                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2546                        }
2547                    }
2548                }
2549
2550                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2551                    mLastWriteTime = now;
2552                    mBatteryStatsService.scheduleWriteToDisk();
2553                }
2554            }
2555        }
2556    }
2557
2558    @Override
2559    public void batteryNeedsCpuUpdate() {
2560        updateCpuStatsNow();
2561    }
2562
2563    @Override
2564    public void batteryPowerChanged(boolean onBattery) {
2565        // When plugging in, update the CPU stats first before changing
2566        // the plug state.
2567        updateCpuStatsNow();
2568        synchronized (this) {
2569            synchronized(mPidsSelfLocked) {
2570                mOnBattery = DEBUG_POWER ? true : onBattery;
2571            }
2572        }
2573    }
2574
2575    @Override
2576    public void batterySendBroadcast(Intent intent) {
2577        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2578                AppOpsManager.OP_NONE, null, false, false,
2579                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2580    }
2581
2582    /**
2583     * Initialize the application bind args. These are passed to each
2584     * process when the bindApplication() IPC is sent to the process. They're
2585     * lazily setup to make sure the services are running when they're asked for.
2586     */
2587    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2588        if (mAppBindArgs == null) {
2589            mAppBindArgs = new HashMap<>();
2590
2591            // Isolated processes won't get this optimization, so that we don't
2592            // violate the rules about which services they have access to.
2593            if (!isolated) {
2594                // Setup the application init args
2595                mAppBindArgs.put("package", ServiceManager.getService("package"));
2596                mAppBindArgs.put("window", ServiceManager.getService("window"));
2597                mAppBindArgs.put(Context.ALARM_SERVICE,
2598                        ServiceManager.getService(Context.ALARM_SERVICE));
2599            }
2600        }
2601        return mAppBindArgs;
2602    }
2603
2604    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2605        if (r != null && mFocusedActivity != r) {
2606            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2607            ActivityRecord last = mFocusedActivity;
2608            mFocusedActivity = r;
2609            if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2610                    && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2611                if (mCurAppTimeTracker != r.appTimeTracker) {
2612                    // We are switching app tracking.  Complete the current one.
2613                    if (mCurAppTimeTracker != null) {
2614                        mCurAppTimeTracker.stop();
2615                        mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2616                                mCurAppTimeTracker).sendToTarget();
2617                        mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2618                        mCurAppTimeTracker = null;
2619                    }
2620                    if (r.appTimeTracker != null) {
2621                        mCurAppTimeTracker = r.appTimeTracker;
2622                        startTimeTrackingFocusedActivityLocked();
2623                    }
2624                } else {
2625                    startTimeTrackingFocusedActivityLocked();
2626                }
2627            } else {
2628                r.appTimeTracker = null;
2629            }
2630            if (r.task != null && r.task.voiceInteractor != null) {
2631                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2632            } else {
2633                finishRunningVoiceLocked();
2634                if (last != null && last.task.voiceSession != null) {
2635                    // We had been in a voice interaction session, but now focused has
2636                    // move to something different.  Just finish the session, we can't
2637                    // return to it and retain the proper state and synchronization with
2638                    // the voice interaction service.
2639                    finishVoiceTask(last.task.voiceSession);
2640                }
2641            }
2642            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2643                mWindowManager.setFocusedApp(r.appToken, true);
2644            }
2645            applyUpdateLockStateLocked(r);
2646            if (mFocusedActivity.userId != mLastFocusedUserId) {
2647                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2648                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2649                        mFocusedActivity.userId, 0));
2650                mLastFocusedUserId = mFocusedActivity.userId;
2651            }
2652        }
2653        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2654                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2655                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2656    }
2657
2658    final void clearFocusedActivity(ActivityRecord r) {
2659        if (mFocusedActivity == r) {
2660            ActivityStack stack = mStackSupervisor.getFocusedStack();
2661            if (stack != null) {
2662                ActivityRecord top = stack.topActivity();
2663                if (top != null && top.userId != mLastFocusedUserId) {
2664                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2665                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2666                                    top.userId, 0));
2667                    mLastFocusedUserId = top.userId;
2668                }
2669            }
2670            mFocusedActivity = null;
2671            EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2672        }
2673    }
2674
2675    @Override
2676    public void setFocusedStack(int stackId) {
2677        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2678        synchronized (ActivityManagerService.this) {
2679            ActivityStack stack = mStackSupervisor.getStack(stackId);
2680            if (stack != null) {
2681                ActivityRecord r = stack.topRunningActivityLocked(null);
2682                if (r != null) {
2683                    setFocusedActivityLocked(r, "setFocusedStack");
2684                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2685                }
2686            }
2687        }
2688    }
2689
2690    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2691    @Override
2692    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2693        synchronized (ActivityManagerService.this) {
2694            if (listener != null) {
2695                mTaskStackListeners.register(listener);
2696            }
2697        }
2698    }
2699
2700    @Override
2701    public void notifyActivityDrawn(IBinder token) {
2702        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2703        synchronized (this) {
2704            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2705            if (r != null) {
2706                r.task.stack.notifyActivityDrawnLocked(r);
2707            }
2708        }
2709    }
2710
2711    final void applyUpdateLockStateLocked(ActivityRecord r) {
2712        // Modifications to the UpdateLock state are done on our handler, outside
2713        // the activity manager's locks.  The new state is determined based on the
2714        // state *now* of the relevant activity record.  The object is passed to
2715        // the handler solely for logging detail, not to be consulted/modified.
2716        final boolean nextState = r != null && r.immersive;
2717        mHandler.sendMessage(
2718                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2719    }
2720
2721    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2722        Message msg = Message.obtain();
2723        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2724        msg.obj = r.task.askedCompatMode ? null : r;
2725        mUiHandler.sendMessage(msg);
2726    }
2727
2728    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2729            String what, Object obj, ProcessRecord srcApp) {
2730        app.lastActivityTime = now;
2731
2732        if (app.activities.size() > 0) {
2733            // Don't want to touch dependent processes that are hosting activities.
2734            return index;
2735        }
2736
2737        int lrui = mLruProcesses.lastIndexOf(app);
2738        if (lrui < 0) {
2739            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2740                    + what + " " + obj + " from " + srcApp);
2741            return index;
2742        }
2743
2744        if (lrui >= index) {
2745            // Don't want to cause this to move dependent processes *back* in the
2746            // list as if they were less frequently used.
2747            return index;
2748        }
2749
2750        if (lrui >= mLruProcessActivityStart) {
2751            // Don't want to touch dependent processes that are hosting activities.
2752            return index;
2753        }
2754
2755        mLruProcesses.remove(lrui);
2756        if (index > 0) {
2757            index--;
2758        }
2759        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2760                + " in LRU list: " + app);
2761        mLruProcesses.add(index, app);
2762        return index;
2763    }
2764
2765    private static void killProcessGroup(int uid, int pid) {
2766        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2767        Process.killProcessGroup(uid, pid);
2768        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2769    }
2770
2771    final void removeLruProcessLocked(ProcessRecord app) {
2772        int lrui = mLruProcesses.lastIndexOf(app);
2773        if (lrui >= 0) {
2774            if (!app.killed) {
2775                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2776                Process.killProcessQuiet(app.pid);
2777                killProcessGroup(app.info.uid, app.pid);
2778            }
2779            if (lrui <= mLruProcessActivityStart) {
2780                mLruProcessActivityStart--;
2781            }
2782            if (lrui <= mLruProcessServiceStart) {
2783                mLruProcessServiceStart--;
2784            }
2785            mLruProcesses.remove(lrui);
2786        }
2787    }
2788
2789    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2790            ProcessRecord client) {
2791        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2792                || app.treatLikeActivity;
2793        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2794        if (!activityChange && hasActivity) {
2795            // The process has activities, so we are only allowing activity-based adjustments
2796            // to move it.  It should be kept in the front of the list with other
2797            // processes that have activities, and we don't want those to change their
2798            // order except due to activity operations.
2799            return;
2800        }
2801
2802        mLruSeq++;
2803        final long now = SystemClock.uptimeMillis();
2804        app.lastActivityTime = now;
2805
2806        // First a quick reject: if the app is already at the position we will
2807        // put it, then there is nothing to do.
2808        if (hasActivity) {
2809            final int N = mLruProcesses.size();
2810            if (N > 0 && mLruProcesses.get(N-1) == app) {
2811                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2812                return;
2813            }
2814        } else {
2815            if (mLruProcessServiceStart > 0
2816                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2817                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2818                return;
2819            }
2820        }
2821
2822        int lrui = mLruProcesses.lastIndexOf(app);
2823
2824        if (app.persistent && lrui >= 0) {
2825            // We don't care about the position of persistent processes, as long as
2826            // they are in the list.
2827            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2828            return;
2829        }
2830
2831        /* In progress: compute new position first, so we can avoid doing work
2832           if the process is not actually going to move.  Not yet working.
2833        int addIndex;
2834        int nextIndex;
2835        boolean inActivity = false, inService = false;
2836        if (hasActivity) {
2837            // Process has activities, put it at the very tipsy-top.
2838            addIndex = mLruProcesses.size();
2839            nextIndex = mLruProcessServiceStart;
2840            inActivity = true;
2841        } else if (hasService) {
2842            // Process has services, put it at the top of the service list.
2843            addIndex = mLruProcessActivityStart;
2844            nextIndex = mLruProcessServiceStart;
2845            inActivity = true;
2846            inService = true;
2847        } else  {
2848            // Process not otherwise of interest, it goes to the top of the non-service area.
2849            addIndex = mLruProcessServiceStart;
2850            if (client != null) {
2851                int clientIndex = mLruProcesses.lastIndexOf(client);
2852                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2853                        + app);
2854                if (clientIndex >= 0 && addIndex > clientIndex) {
2855                    addIndex = clientIndex;
2856                }
2857            }
2858            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2859        }
2860
2861        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2862                + mLruProcessActivityStart + "): " + app);
2863        */
2864
2865        if (lrui >= 0) {
2866            if (lrui < mLruProcessActivityStart) {
2867                mLruProcessActivityStart--;
2868            }
2869            if (lrui < mLruProcessServiceStart) {
2870                mLruProcessServiceStart--;
2871            }
2872            /*
2873            if (addIndex > lrui) {
2874                addIndex--;
2875            }
2876            if (nextIndex > lrui) {
2877                nextIndex--;
2878            }
2879            */
2880            mLruProcesses.remove(lrui);
2881        }
2882
2883        /*
2884        mLruProcesses.add(addIndex, app);
2885        if (inActivity) {
2886            mLruProcessActivityStart++;
2887        }
2888        if (inService) {
2889            mLruProcessActivityStart++;
2890        }
2891        */
2892
2893        int nextIndex;
2894        if (hasActivity) {
2895            final int N = mLruProcesses.size();
2896            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2897                // Process doesn't have activities, but has clients with
2898                // activities...  move it up, but one below the top (the top
2899                // should always have a real activity).
2900                if (DEBUG_LRU) Slog.d(TAG_LRU,
2901                        "Adding to second-top of LRU activity list: " + app);
2902                mLruProcesses.add(N - 1, app);
2903                // To keep it from spamming the LRU list (by making a bunch of clients),
2904                // we will push down any other entries owned by the app.
2905                final int uid = app.info.uid;
2906                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2907                    ProcessRecord subProc = mLruProcesses.get(i);
2908                    if (subProc.info.uid == uid) {
2909                        // We want to push this one down the list.  If the process after
2910                        // it is for the same uid, however, don't do so, because we don't
2911                        // want them internally to be re-ordered.
2912                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2913                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2914                                    "Pushing uid " + uid + " swapping at " + i + ": "
2915                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2916                            ProcessRecord tmp = mLruProcesses.get(i);
2917                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2918                            mLruProcesses.set(i - 1, tmp);
2919                            i--;
2920                        }
2921                    } else {
2922                        // A gap, we can stop here.
2923                        break;
2924                    }
2925                }
2926            } else {
2927                // Process has activities, put it at the very tipsy-top.
2928                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2929                mLruProcesses.add(app);
2930            }
2931            nextIndex = mLruProcessServiceStart;
2932        } else if (hasService) {
2933            // Process has services, put it at the top of the service list.
2934            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2935            mLruProcesses.add(mLruProcessActivityStart, app);
2936            nextIndex = mLruProcessServiceStart;
2937            mLruProcessActivityStart++;
2938        } else  {
2939            // Process not otherwise of interest, it goes to the top of the non-service area.
2940            int index = mLruProcessServiceStart;
2941            if (client != null) {
2942                // If there is a client, don't allow the process to be moved up higher
2943                // in the list than that client.
2944                int clientIndex = mLruProcesses.lastIndexOf(client);
2945                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2946                        + " when updating " + app);
2947                if (clientIndex <= lrui) {
2948                    // Don't allow the client index restriction to push it down farther in the
2949                    // list than it already is.
2950                    clientIndex = lrui;
2951                }
2952                if (clientIndex >= 0 && index > clientIndex) {
2953                    index = clientIndex;
2954                }
2955            }
2956            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2957            mLruProcesses.add(index, app);
2958            nextIndex = index-1;
2959            mLruProcessActivityStart++;
2960            mLruProcessServiceStart++;
2961        }
2962
2963        // If the app is currently using a content provider or service,
2964        // bump those processes as well.
2965        for (int j=app.connections.size()-1; j>=0; j--) {
2966            ConnectionRecord cr = app.connections.valueAt(j);
2967            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2968                    && cr.binding.service.app != null
2969                    && cr.binding.service.app.lruSeq != mLruSeq
2970                    && !cr.binding.service.app.persistent) {
2971                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2972                        "service connection", cr, app);
2973            }
2974        }
2975        for (int j=app.conProviders.size()-1; j>=0; j--) {
2976            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2977            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2978                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2979                        "provider reference", cpr, app);
2980            }
2981        }
2982    }
2983
2984    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2985        if (uid == Process.SYSTEM_UID) {
2986            // The system gets to run in any process.  If there are multiple
2987            // processes with the same uid, just pick the first (this
2988            // should never happen).
2989            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2990            if (procs == null) return null;
2991            final int procCount = procs.size();
2992            for (int i = 0; i < procCount; i++) {
2993                final int procUid = procs.keyAt(i);
2994                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
2995                    // Don't use an app process or different user process for system component.
2996                    continue;
2997                }
2998                return procs.valueAt(i);
2999            }
3000        }
3001        ProcessRecord proc = mProcessNames.get(processName, uid);
3002        if (false && proc != null && !keepIfLarge
3003                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3004                && proc.lastCachedPss >= 4000) {
3005            // Turn this condition on to cause killing to happen regularly, for testing.
3006            if (proc.baseProcessTracker != null) {
3007                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3008            }
3009            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3010        } else if (proc != null && !keepIfLarge
3011                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3012                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3013            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3014            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3015                if (proc.baseProcessTracker != null) {
3016                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3017                }
3018                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3019            }
3020        }
3021        return proc;
3022    }
3023
3024    void ensurePackageDexOpt(String packageName) {
3025        IPackageManager pm = AppGlobals.getPackageManager();
3026        try {
3027            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3028                mDidDexOpt = true;
3029            }
3030        } catch (RemoteException e) {
3031        }
3032    }
3033
3034    boolean isNextTransitionForward() {
3035        int transit = mWindowManager.getPendingAppTransition();
3036        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3037                || transit == AppTransition.TRANSIT_TASK_OPEN
3038                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3039    }
3040
3041    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3042            String processName, String abiOverride, int uid, Runnable crashHandler) {
3043        synchronized(this) {
3044            ApplicationInfo info = new ApplicationInfo();
3045            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3046            // For isolated processes, the former contains the parent's uid and the latter the
3047            // actual uid of the isolated process.
3048            // In the special case introduced by this method (which is, starting an isolated
3049            // process directly from the SystemServer without an actual parent app process) the
3050            // closest thing to a parent's uid is SYSTEM_UID.
3051            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3052            // the |isolated| logic in the ProcessRecord constructor.
3053            info.uid = Process.SYSTEM_UID;
3054            info.processName = processName;
3055            info.className = entryPoint;
3056            info.packageName = "android";
3057            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3058                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3059                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3060                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3061                    crashHandler);
3062            return proc != null ? proc.pid : 0;
3063        }
3064    }
3065
3066    final ProcessRecord startProcessLocked(String processName,
3067            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3068            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3069            boolean isolated, boolean keepIfLarge) {
3070        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3071                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3072                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3073                null /* crashHandler */);
3074    }
3075
3076    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3077            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3078            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3079            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3080        long startTime = SystemClock.elapsedRealtime();
3081        ProcessRecord app;
3082        if (!isolated) {
3083            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3084            checkTime(startTime, "startProcess: after getProcessRecord");
3085
3086            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3087                // If we are in the background, then check to see if this process
3088                // is bad.  If so, we will just silently fail.
3089                if (mBadProcesses.get(info.processName, info.uid) != null) {
3090                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3091                            + "/" + info.processName);
3092                    return null;
3093                }
3094            } else {
3095                // When the user is explicitly starting a process, then clear its
3096                // crash count so that we won't make it bad until they see at
3097                // least one crash dialog again, and make the process good again
3098                // if it had been bad.
3099                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3100                        + "/" + info.processName);
3101                mProcessCrashTimes.remove(info.processName, info.uid);
3102                if (mBadProcesses.get(info.processName, info.uid) != null) {
3103                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3104                            UserHandle.getUserId(info.uid), info.uid,
3105                            info.processName);
3106                    mBadProcesses.remove(info.processName, info.uid);
3107                    if (app != null) {
3108                        app.bad = false;
3109                    }
3110                }
3111            }
3112        } else {
3113            // If this is an isolated process, it can't re-use an existing process.
3114            app = null;
3115        }
3116
3117        // We don't have to do anything more if:
3118        // (1) There is an existing application record; and
3119        // (2) The caller doesn't think it is dead, OR there is no thread
3120        //     object attached to it so we know it couldn't have crashed; and
3121        // (3) There is a pid assigned to it, so it is either starting or
3122        //     already running.
3123        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3124                + " app=" + app + " knownToBeDead=" + knownToBeDead
3125                + " thread=" + (app != null ? app.thread : null)
3126                + " pid=" + (app != null ? app.pid : -1));
3127        if (app != null && app.pid > 0) {
3128            if (!knownToBeDead || app.thread == null) {
3129                // We already have the app running, or are waiting for it to
3130                // come up (we have a pid but not yet its thread), so keep it.
3131                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3132                // If this is a new package in the process, add the package to the list
3133                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3134                checkTime(startTime, "startProcess: done, added package to proc");
3135                return app;
3136            }
3137
3138            // An application record is attached to a previous process,
3139            // clean it up now.
3140            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3141            checkTime(startTime, "startProcess: bad proc running, killing");
3142            killProcessGroup(app.info.uid, app.pid);
3143            handleAppDiedLocked(app, true, true);
3144            checkTime(startTime, "startProcess: done killing old proc");
3145        }
3146
3147        String hostingNameStr = hostingName != null
3148                ? hostingName.flattenToShortString() : null;
3149
3150        if (app == null) {
3151            checkTime(startTime, "startProcess: creating new process record");
3152            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3153            if (app == null) {
3154                Slog.w(TAG, "Failed making new process record for "
3155                        + processName + "/" + info.uid + " isolated=" + isolated);
3156                return null;
3157            }
3158            app.crashHandler = crashHandler;
3159            checkTime(startTime, "startProcess: done creating new process record");
3160        } else {
3161            // If this is a new package in the process, add the package to the list
3162            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3163            checkTime(startTime, "startProcess: added package to existing proc");
3164        }
3165
3166        // If the system is not ready yet, then hold off on starting this
3167        // process until it is.
3168        if (!mProcessesReady
3169                && !isAllowedWhileBooting(info)
3170                && !allowWhileBooting) {
3171            if (!mProcessesOnHold.contains(app)) {
3172                mProcessesOnHold.add(app);
3173            }
3174            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3175                    "System not ready, putting on hold: " + app);
3176            checkTime(startTime, "startProcess: returning with proc on hold");
3177            return app;
3178        }
3179
3180        checkTime(startTime, "startProcess: stepping in to startProcess");
3181        startProcessLocked(
3182                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3183        checkTime(startTime, "startProcess: done starting proc!");
3184        return (app.pid != 0) ? app : null;
3185    }
3186
3187    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3188        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3189    }
3190
3191    private final void startProcessLocked(ProcessRecord app,
3192            String hostingType, String hostingNameStr) {
3193        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3194                null /* entryPoint */, null /* entryPointArgs */);
3195    }
3196
3197    private final void startProcessLocked(ProcessRecord app, String hostingType,
3198            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3199        long startTime = SystemClock.elapsedRealtime();
3200        if (app.pid > 0 && app.pid != MY_PID) {
3201            checkTime(startTime, "startProcess: removing from pids map");
3202            synchronized (mPidsSelfLocked) {
3203                mPidsSelfLocked.remove(app.pid);
3204                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3205            }
3206            checkTime(startTime, "startProcess: done removing from pids map");
3207            app.setPid(0);
3208        }
3209
3210        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3211                "startProcessLocked removing on hold: " + app);
3212        mProcessesOnHold.remove(app);
3213
3214        checkTime(startTime, "startProcess: starting to update cpu stats");
3215        updateCpuStats();
3216        checkTime(startTime, "startProcess: done updating cpu stats");
3217
3218        try {
3219            try {
3220                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3221                    // This is caught below as if we had failed to fork zygote
3222                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3223                }
3224            } catch (RemoteException e) {
3225                throw e.rethrowAsRuntimeException();
3226            }
3227
3228            int uid = app.uid;
3229            int[] gids = null;
3230            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3231            if (!app.isolated) {
3232                int[] permGids = null;
3233                try {
3234                    checkTime(startTime, "startProcess: getting gids from package manager");
3235                    final IPackageManager pm = AppGlobals.getPackageManager();
3236                    permGids = pm.getPackageGids(app.info.packageName, app.userId);
3237                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3238                            MountServiceInternal.class);
3239                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3240                            app.info.packageName);
3241                } catch (RemoteException e) {
3242                    throw e.rethrowAsRuntimeException();
3243                }
3244
3245                /*
3246                 * Add shared application and profile GIDs so applications can share some
3247                 * resources like shared libraries and access user-wide resources
3248                 */
3249                if (ArrayUtils.isEmpty(permGids)) {
3250                    gids = new int[2];
3251                } else {
3252                    gids = new int[permGids.length + 2];
3253                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3254                }
3255                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3256                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3257            }
3258            checkTime(startTime, "startProcess: building args");
3259            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3260                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3261                        && mTopComponent != null
3262                        && app.processName.equals(mTopComponent.getPackageName())) {
3263                    uid = 0;
3264                }
3265                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3266                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3267                    uid = 0;
3268                }
3269            }
3270            int debugFlags = 0;
3271            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3272                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3273                // Also turn on CheckJNI for debuggable apps. It's quite
3274                // awkward to turn on otherwise.
3275                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3276            }
3277            // Run the app in safe mode if its manifest requests so or the
3278            // system is booted in safe mode.
3279            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3280                mSafeMode == true) {
3281                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3282            }
3283            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3284                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3285            }
3286            String jitDebugProperty = SystemProperties.get("debug.usejit");
3287            if ("true".equals(jitDebugProperty)) {
3288                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3289            } else if (!"false".equals(jitDebugProperty)) {
3290                // If we didn't force disable by setting false, defer to the dalvik vm options.
3291                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3292                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3293                }
3294            }
3295            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3296            if ("true".equals(genDebugInfoProperty)) {
3297                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3298            }
3299            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3300                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3301            }
3302            if ("1".equals(SystemProperties.get("debug.assert"))) {
3303                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3304            }
3305
3306            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3307            if (requiredAbi == null) {
3308                requiredAbi = Build.SUPPORTED_ABIS[0];
3309            }
3310
3311            String instructionSet = null;
3312            if (app.info.primaryCpuAbi != null) {
3313                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3314            }
3315
3316            app.gids = gids;
3317            app.requiredAbi = requiredAbi;
3318            app.instructionSet = instructionSet;
3319
3320            // Start the process.  It will either succeed and return a result containing
3321            // the PID of the new process, or else throw a RuntimeException.
3322            boolean isActivityProcess = (entryPoint == null);
3323            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3324            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3325                    app.processName);
3326            checkTime(startTime, "startProcess: asking zygote to start proc");
3327            Process.ProcessStartResult startResult = Process.start(entryPoint,
3328                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3329                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3330                    app.info.dataDir, entryPointArgs);
3331            checkTime(startTime, "startProcess: returned from zygote!");
3332            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3333
3334            if (app.isolated) {
3335                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3336            }
3337            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3338            checkTime(startTime, "startProcess: done updating battery stats");
3339
3340            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3341                    UserHandle.getUserId(uid), startResult.pid, uid,
3342                    app.processName, hostingType,
3343                    hostingNameStr != null ? hostingNameStr : "");
3344
3345            if (app.persistent) {
3346                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3347            }
3348
3349            checkTime(startTime, "startProcess: building log message");
3350            StringBuilder buf = mStringBuilder;
3351            buf.setLength(0);
3352            buf.append("Start proc ");
3353            buf.append(startResult.pid);
3354            buf.append(':');
3355            buf.append(app.processName);
3356            buf.append('/');
3357            UserHandle.formatUid(buf, uid);
3358            if (!isActivityProcess) {
3359                buf.append(" [");
3360                buf.append(entryPoint);
3361                buf.append("]");
3362            }
3363            buf.append(" for ");
3364            buf.append(hostingType);
3365            if (hostingNameStr != null) {
3366                buf.append(" ");
3367                buf.append(hostingNameStr);
3368            }
3369            Slog.i(TAG, buf.toString());
3370            app.setPid(startResult.pid);
3371            app.usingWrapper = startResult.usingWrapper;
3372            app.removed = false;
3373            app.killed = false;
3374            app.killedByAm = false;
3375            checkTime(startTime, "startProcess: starting to update pids map");
3376            synchronized (mPidsSelfLocked) {
3377                this.mPidsSelfLocked.put(startResult.pid, app);
3378                if (isActivityProcess) {
3379                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3380                    msg.obj = app;
3381                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3382                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3383                }
3384            }
3385            checkTime(startTime, "startProcess: done updating pids map");
3386        } catch (RuntimeException e) {
3387            // XXX do better error recovery.
3388            app.setPid(0);
3389            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3390            if (app.isolated) {
3391                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3392            }
3393            Slog.e(TAG, "Failure starting process " + app.processName, e);
3394        }
3395    }
3396
3397    void updateUsageStats(ActivityRecord component, boolean resumed) {
3398        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3399                "updateUsageStats: comp=" + component + "res=" + resumed);
3400        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3401        if (resumed) {
3402            if (mUsageStatsService != null) {
3403                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3404                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3405            }
3406            synchronized (stats) {
3407                stats.noteActivityResumedLocked(component.app.uid);
3408            }
3409        } else {
3410            if (mUsageStatsService != null) {
3411                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3412                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3413            }
3414            synchronized (stats) {
3415                stats.noteActivityPausedLocked(component.app.uid);
3416            }
3417        }
3418    }
3419
3420    Intent getHomeIntent() {
3421        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3422        intent.setComponent(mTopComponent);
3423        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3424            intent.addCategory(Intent.CATEGORY_HOME);
3425        }
3426        return intent;
3427    }
3428
3429    boolean startHomeActivityLocked(int userId, String reason) {
3430        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3431                && mTopAction == null) {
3432            // We are running in factory test mode, but unable to find
3433            // the factory test app, so just sit around displaying the
3434            // error message and don't try to start anything.
3435            return false;
3436        }
3437        Intent intent = getHomeIntent();
3438        ActivityInfo aInfo =
3439            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3440        if (aInfo != null) {
3441            intent.setComponent(new ComponentName(
3442                    aInfo.applicationInfo.packageName, aInfo.name));
3443            // Don't do this if the home app is currently being
3444            // instrumented.
3445            aInfo = new ActivityInfo(aInfo);
3446            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3447            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3448                    aInfo.applicationInfo.uid, true);
3449            if (app == null || app.instrumentationClass == null) {
3450                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3451                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3452            }
3453        }
3454
3455        return true;
3456    }
3457
3458    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3459        ActivityInfo ai = null;
3460        ComponentName comp = intent.getComponent();
3461        try {
3462            if (comp != null) {
3463                // Factory test.
3464                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3465            } else {
3466                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3467                        intent,
3468                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3469                        flags, userId);
3470
3471                if (info != null) {
3472                    ai = info.activityInfo;
3473                }
3474            }
3475        } catch (RemoteException e) {
3476            // ignore
3477        }
3478
3479        return ai;
3480    }
3481
3482    /**
3483     * Starts the "new version setup screen" if appropriate.
3484     */
3485    void startSetupActivityLocked() {
3486        // Only do this once per boot.
3487        if (mCheckedForSetup) {
3488            return;
3489        }
3490
3491        // We will show this screen if the current one is a different
3492        // version than the last one shown, and we are not running in
3493        // low-level factory test mode.
3494        final ContentResolver resolver = mContext.getContentResolver();
3495        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3496                Settings.Global.getInt(resolver,
3497                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3498            mCheckedForSetup = true;
3499
3500            // See if we should be showing the platform update setup UI.
3501            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3502            List<ResolveInfo> ris = mContext.getPackageManager()
3503                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3504
3505            // We don't allow third party apps to replace this.
3506            ResolveInfo ri = null;
3507            for (int i=0; ris != null && i<ris.size(); i++) {
3508                if ((ris.get(i).activityInfo.applicationInfo.flags
3509                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3510                    ri = ris.get(i);
3511                    break;
3512                }
3513            }
3514
3515            if (ri != null) {
3516                String vers = ri.activityInfo.metaData != null
3517                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3518                        : null;
3519                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3520                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3521                            Intent.METADATA_SETUP_VERSION);
3522                }
3523                String lastVers = Settings.Secure.getString(
3524                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3525                if (vers != null && !vers.equals(lastVers)) {
3526                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3527                    intent.setComponent(new ComponentName(
3528                            ri.activityInfo.packageName, ri.activityInfo.name));
3529                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3530                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3531                            null, null, null);
3532                }
3533            }
3534        }
3535    }
3536
3537    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3538        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3539    }
3540
3541    void enforceNotIsolatedCaller(String caller) {
3542        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3543            throw new SecurityException("Isolated process not allowed to call " + caller);
3544        }
3545    }
3546
3547    void enforceShellRestriction(String restriction, int userHandle) {
3548        if (Binder.getCallingUid() == Process.SHELL_UID) {
3549            if (userHandle < 0
3550                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3551                throw new SecurityException("Shell does not have permission to access user "
3552                        + userHandle);
3553            }
3554        }
3555    }
3556
3557    @Override
3558    public int getFrontActivityScreenCompatMode() {
3559        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3560        synchronized (this) {
3561            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3562        }
3563    }
3564
3565    @Override
3566    public void setFrontActivityScreenCompatMode(int mode) {
3567        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3568                "setFrontActivityScreenCompatMode");
3569        synchronized (this) {
3570            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3571        }
3572    }
3573
3574    @Override
3575    public int getPackageScreenCompatMode(String packageName) {
3576        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3577        synchronized (this) {
3578            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3579        }
3580    }
3581
3582    @Override
3583    public void setPackageScreenCompatMode(String packageName, int mode) {
3584        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3585                "setPackageScreenCompatMode");
3586        synchronized (this) {
3587            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3588        }
3589    }
3590
3591    @Override
3592    public boolean getPackageAskScreenCompat(String packageName) {
3593        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3594        synchronized (this) {
3595            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3596        }
3597    }
3598
3599    @Override
3600    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3601        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3602                "setPackageAskScreenCompat");
3603        synchronized (this) {
3604            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3605        }
3606    }
3607
3608    private boolean hasUsageStatsPermission(String callingPackage) {
3609        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3610                Binder.getCallingUid(), callingPackage);
3611        if (mode == AppOpsManager.MODE_DEFAULT) {
3612            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3613                    == PackageManager.PERMISSION_GRANTED;
3614        }
3615        return mode == AppOpsManager.MODE_ALLOWED;
3616    }
3617
3618    @Override
3619    public int getPackageProcessState(String packageName, String callingPackage) {
3620        if (!hasUsageStatsPermission(callingPackage)) {
3621            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3622                    "getPackageProcessState");
3623        }
3624
3625        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3626        synchronized (this) {
3627            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3628                final ProcessRecord proc = mLruProcesses.get(i);
3629                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3630                        || procState > proc.setProcState) {
3631                    boolean found = false;
3632                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3633                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3634                            procState = proc.setProcState;
3635                            found = true;
3636                        }
3637                    }
3638                    if (proc.pkgDeps != null && !found) {
3639                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3640                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3641                                procState = proc.setProcState;
3642                                break;
3643                            }
3644                        }
3645                    }
3646                }
3647            }
3648        }
3649        return procState;
3650    }
3651
3652    @Override
3653    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3654        synchronized (this) {
3655            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3656            if (app == null) {
3657                return false;
3658            }
3659            if (app.trimMemoryLevel < level && app.thread != null &&
3660                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3661                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3662                try {
3663                    app.thread.scheduleTrimMemory(level);
3664                    app.trimMemoryLevel = level;
3665                    return true;
3666                } catch (RemoteException e) {
3667                    // Fallthrough to failure case.
3668                }
3669            }
3670        }
3671        return false;
3672    }
3673
3674    private void dispatchProcessesChanged() {
3675        int N;
3676        synchronized (this) {
3677            N = mPendingProcessChanges.size();
3678            if (mActiveProcessChanges.length < N) {
3679                mActiveProcessChanges = new ProcessChangeItem[N];
3680            }
3681            mPendingProcessChanges.toArray(mActiveProcessChanges);
3682            mPendingProcessChanges.clear();
3683            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3684                    "*** Delivering " + N + " process changes");
3685        }
3686
3687        int i = mProcessObservers.beginBroadcast();
3688        while (i > 0) {
3689            i--;
3690            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3691            if (observer != null) {
3692                try {
3693                    for (int j=0; j<N; j++) {
3694                        ProcessChangeItem item = mActiveProcessChanges[j];
3695                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3696                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3697                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3698                                    + item.uid + ": " + item.foregroundActivities);
3699                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3700                                    item.foregroundActivities);
3701                        }
3702                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3703                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3704                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3705                                    + ": " + item.processState);
3706                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3707                        }
3708                    }
3709                } catch (RemoteException e) {
3710                }
3711            }
3712        }
3713        mProcessObservers.finishBroadcast();
3714
3715        synchronized (this) {
3716            for (int j=0; j<N; j++) {
3717                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3718            }
3719        }
3720    }
3721
3722    private void dispatchProcessDied(int pid, int uid) {
3723        int i = mProcessObservers.beginBroadcast();
3724        while (i > 0) {
3725            i--;
3726            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3727            if (observer != null) {
3728                try {
3729                    observer.onProcessDied(pid, uid);
3730                } catch (RemoteException e) {
3731                }
3732            }
3733        }
3734        mProcessObservers.finishBroadcast();
3735    }
3736
3737    private void dispatchUidsChanged() {
3738        int N;
3739        synchronized (this) {
3740            N = mPendingUidChanges.size();
3741            if (mActiveUidChanges.length < N) {
3742                mActiveUidChanges = new UidRecord.ChangeItem[N];
3743            }
3744            for (int i=0; i<N; i++) {
3745                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3746                mActiveUidChanges[i] = change;
3747                change.uidRecord.pendingChange = null;
3748                change.uidRecord = null;
3749            }
3750            mPendingUidChanges.clear();
3751            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3752                    "*** Delivering " + N + " uid changes");
3753        }
3754
3755        if (mLocalPowerManager != null) {
3756            for (int j=0; j<N; j++) {
3757                UidRecord.ChangeItem item = mActiveUidChanges[j];
3758                if (item.gone) {
3759                    mLocalPowerManager.uidGone(item.uid);
3760                } else {
3761                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3762                }
3763            }
3764        }
3765
3766        int i = mUidObservers.beginBroadcast();
3767        while (i > 0) {
3768            i--;
3769            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3770            if (observer != null) {
3771                try {
3772                    for (int j=0; j<N; j++) {
3773                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3774                        if (item.gone) {
3775                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3776                                    "UID gone uid=" + item.uid);
3777                            observer.onUidGone(item.uid);
3778                        } else {
3779                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3780                                    "UID CHANGED uid=" + item.uid
3781                                    + ": " + item.processState);
3782                            observer.onUidStateChanged(item.uid, item.processState);
3783                        }
3784                    }
3785                } catch (RemoteException e) {
3786                }
3787            }
3788        }
3789        mUidObservers.finishBroadcast();
3790
3791        synchronized (this) {
3792            for (int j=0; j<N; j++) {
3793                mAvailUidChanges.add(mActiveUidChanges[j]);
3794            }
3795        }
3796    }
3797
3798    @Override
3799    public final int startActivity(IApplicationThread caller, String callingPackage,
3800            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3801            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3802        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3803            resultWho, requestCode, startFlags, profilerInfo, options,
3804            UserHandle.getCallingUserId());
3805    }
3806
3807    @Override
3808    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3809            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3810            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3811        enforceNotIsolatedCaller("startActivity");
3812        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3813                false, ALLOW_FULL_ONLY, "startActivity", null);
3814        // TODO: Switch to user app stacks here.
3815        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3816                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3817                profilerInfo, null, null, options, false, userId, null, null);
3818    }
3819
3820    @Override
3821    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3822            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3823            int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
3824            int userId) {
3825
3826        // This is very dangerous -- it allows you to perform a start activity (including
3827        // permission grants) as any app that may launch one of your own activities.  So
3828        // we will only allow this to be done from activities that are part of the core framework,
3829        // and then only when they are running as the system.
3830        final ActivityRecord sourceRecord;
3831        final int targetUid;
3832        final String targetPackage;
3833        synchronized (this) {
3834            if (resultTo == null) {
3835                throw new SecurityException("Must be called from an activity");
3836            }
3837            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3838            if (sourceRecord == null) {
3839                throw new SecurityException("Called with bad activity token: " + resultTo);
3840            }
3841            if (!sourceRecord.info.packageName.equals("android")) {
3842                throw new SecurityException(
3843                        "Must be called from an activity that is declared in the android package");
3844            }
3845            if (sourceRecord.app == null) {
3846                throw new SecurityException("Called without a process attached to activity");
3847            }
3848            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3849                // This is still okay, as long as this activity is running under the
3850                // uid of the original calling activity.
3851                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3852                    throw new SecurityException(
3853                            "Calling activity in uid " + sourceRecord.app.uid
3854                                    + " must be system uid or original calling uid "
3855                                    + sourceRecord.launchedFromUid);
3856                }
3857            }
3858            if (ignoreTargetSecurity) {
3859                if (intent.getComponent() == null) {
3860                    throw new SecurityException(
3861                            "Component must be specified with ignoreTargetSecurity");
3862                }
3863                if (intent.getSelector() != null) {
3864                    throw new SecurityException(
3865                            "Selector not allowed with ignoreTargetSecurity");
3866                }
3867            }
3868            targetUid = sourceRecord.launchedFromUid;
3869            targetPackage = sourceRecord.launchedFromPackage;
3870        }
3871
3872        if (userId == UserHandle.USER_NULL) {
3873            userId = UserHandle.getUserId(sourceRecord.app.uid);
3874        }
3875
3876        // TODO: Switch to user app stacks here.
3877        try {
3878            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3879                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3880                    null, null, options, ignoreTargetSecurity, userId, null, null);
3881            return ret;
3882        } catch (SecurityException e) {
3883            // XXX need to figure out how to propagate to original app.
3884            // A SecurityException here is generally actually a fault of the original
3885            // calling activity (such as a fairly granting permissions), so propagate it
3886            // back to them.
3887            /*
3888            StringBuilder msg = new StringBuilder();
3889            msg.append("While launching");
3890            msg.append(intent.toString());
3891            msg.append(": ");
3892            msg.append(e.getMessage());
3893            */
3894            throw e;
3895        }
3896    }
3897
3898    @Override
3899    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3900            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3901            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3902        enforceNotIsolatedCaller("startActivityAndWait");
3903        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3904                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3905        WaitResult res = new WaitResult();
3906        // TODO: Switch to user app stacks here.
3907        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3908                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3909                options, false, userId, null, null);
3910        return res;
3911    }
3912
3913    @Override
3914    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3915            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3916            int startFlags, Configuration config, Bundle options, int userId) {
3917        enforceNotIsolatedCaller("startActivityWithConfig");
3918        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3919                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3920        // TODO: Switch to user app stacks here.
3921        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3922                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3923                null, null, config, options, false, userId, null, null);
3924        return ret;
3925    }
3926
3927    @Override
3928    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3929            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3930            int requestCode, int flagsMask, int flagsValues, Bundle options)
3931            throws TransactionTooLargeException {
3932        enforceNotIsolatedCaller("startActivityIntentSender");
3933        // Refuse possible leaked file descriptors
3934        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3935            throw new IllegalArgumentException("File descriptors passed in Intent");
3936        }
3937
3938        IIntentSender sender = intent.getTarget();
3939        if (!(sender instanceof PendingIntentRecord)) {
3940            throw new IllegalArgumentException("Bad PendingIntent object");
3941        }
3942
3943        PendingIntentRecord pir = (PendingIntentRecord)sender;
3944
3945        synchronized (this) {
3946            // If this is coming from the currently resumed activity, it is
3947            // effectively saying that app switches are allowed at this point.
3948            final ActivityStack stack = getFocusedStack();
3949            if (stack.mResumedActivity != null &&
3950                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3951                mAppSwitchesAllowedTime = 0;
3952            }
3953        }
3954        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3955                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3956        return ret;
3957    }
3958
3959    @Override
3960    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3961            Intent intent, String resolvedType, IVoiceInteractionSession session,
3962            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3963            Bundle options, int userId) {
3964        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3965                != PackageManager.PERMISSION_GRANTED) {
3966            String msg = "Permission Denial: startVoiceActivity() from pid="
3967                    + Binder.getCallingPid()
3968                    + ", uid=" + Binder.getCallingUid()
3969                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3970            Slog.w(TAG, msg);
3971            throw new SecurityException(msg);
3972        }
3973        if (session == null || interactor == null) {
3974            throw new NullPointerException("null session or interactor");
3975        }
3976        userId = handleIncomingUser(callingPid, callingUid, userId,
3977                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3978        // TODO: Switch to user app stacks here.
3979        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3980                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3981                null, options, false, userId, null, null);
3982    }
3983
3984    @Override
3985    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3986        synchronized (this) {
3987            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3988                if (keepAwake) {
3989                    mVoiceWakeLock.acquire();
3990                } else {
3991                    mVoiceWakeLock.release();
3992                }
3993            }
3994        }
3995    }
3996
3997    @Override
3998    public boolean startNextMatchingActivity(IBinder callingActivity,
3999            Intent intent, Bundle options) {
4000        // Refuse possible leaked file descriptors
4001        if (intent != null && intent.hasFileDescriptors() == true) {
4002            throw new IllegalArgumentException("File descriptors passed in Intent");
4003        }
4004
4005        synchronized (this) {
4006            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4007            if (r == null) {
4008                ActivityOptions.abort(options);
4009                return false;
4010            }
4011            if (r.app == null || r.app.thread == null) {
4012                // The caller is not running...  d'oh!
4013                ActivityOptions.abort(options);
4014                return false;
4015            }
4016            intent = new Intent(intent);
4017            // The caller is not allowed to change the data.
4018            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4019            // And we are resetting to find the next component...
4020            intent.setComponent(null);
4021
4022            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4023
4024            ActivityInfo aInfo = null;
4025            try {
4026                List<ResolveInfo> resolves =
4027                    AppGlobals.getPackageManager().queryIntentActivities(
4028                            intent, r.resolvedType,
4029                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4030                            UserHandle.getCallingUserId());
4031
4032                // Look for the original activity in the list...
4033                final int N = resolves != null ? resolves.size() : 0;
4034                for (int i=0; i<N; i++) {
4035                    ResolveInfo rInfo = resolves.get(i);
4036                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4037                            && rInfo.activityInfo.name.equals(r.info.name)) {
4038                        // We found the current one...  the next matching is
4039                        // after it.
4040                        i++;
4041                        if (i<N) {
4042                            aInfo = resolves.get(i).activityInfo;
4043                        }
4044                        if (debug) {
4045                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4046                                    + "/" + r.info.name);
4047                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4048                                    + "/" + aInfo.name);
4049                        }
4050                        break;
4051                    }
4052                }
4053            } catch (RemoteException e) {
4054            }
4055
4056            if (aInfo == null) {
4057                // Nobody who is next!
4058                ActivityOptions.abort(options);
4059                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4060                return false;
4061            }
4062
4063            intent.setComponent(new ComponentName(
4064                    aInfo.applicationInfo.packageName, aInfo.name));
4065            intent.setFlags(intent.getFlags()&~(
4066                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4067                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4068                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4069                    Intent.FLAG_ACTIVITY_NEW_TASK));
4070
4071            // Okay now we need to start the new activity, replacing the
4072            // currently running activity.  This is a little tricky because
4073            // we want to start the new one as if the current one is finished,
4074            // but not finish the current one first so that there is no flicker.
4075            // And thus...
4076            final boolean wasFinishing = r.finishing;
4077            r.finishing = true;
4078
4079            // Propagate reply information over to the new activity.
4080            final ActivityRecord resultTo = r.resultTo;
4081            final String resultWho = r.resultWho;
4082            final int requestCode = r.requestCode;
4083            r.resultTo = null;
4084            if (resultTo != null) {
4085                resultTo.removeResultsLocked(r, resultWho, requestCode);
4086            }
4087
4088            final long origId = Binder.clearCallingIdentity();
4089            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4090                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4091                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4092                    -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4093            Binder.restoreCallingIdentity(origId);
4094
4095            r.finishing = wasFinishing;
4096            if (res != ActivityManager.START_SUCCESS) {
4097                return false;
4098            }
4099            return true;
4100        }
4101    }
4102
4103    @Override
4104    public final int startActivityFromRecents(int taskId, Bundle options) {
4105        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4106            String msg = "Permission Denial: startActivityFromRecents called without " +
4107                    START_TASKS_FROM_RECENTS;
4108            Slog.w(TAG, msg);
4109            throw new SecurityException(msg);
4110        }
4111        return startActivityFromRecentsInner(taskId, options);
4112    }
4113
4114    final int startActivityFromRecentsInner(int taskId, Bundle options) {
4115        final TaskRecord task;
4116        final int callingUid;
4117        final String callingPackage;
4118        final Intent intent;
4119        final int userId;
4120        synchronized (this) {
4121            task = mStackSupervisor.anyTaskForIdLocked(taskId);
4122            if (task == null) {
4123                throw new IllegalArgumentException("Task " + taskId + " not found.");
4124            }
4125            if (task.getRootActivity() != null) {
4126                moveTaskToFrontLocked(task.taskId, 0, null);
4127                return ActivityManager.START_TASK_TO_FRONT;
4128            }
4129            callingUid = task.mCallingUid;
4130            callingPackage = task.mCallingPackage;
4131            intent = task.intent;
4132            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4133            userId = task.userId;
4134        }
4135        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4136                options, userId, null, task);
4137    }
4138
4139    final int startActivityInPackage(int uid, String callingPackage,
4140            Intent intent, String resolvedType, IBinder resultTo,
4141            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4142            IActivityContainer container, TaskRecord inTask) {
4143
4144        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4145                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4146
4147        // TODO: Switch to user app stacks here.
4148        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4149                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4150                null, null, null, options, false, userId, container, inTask);
4151        return ret;
4152    }
4153
4154    @Override
4155    public final int startActivities(IApplicationThread caller, String callingPackage,
4156            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4157            int userId) {
4158        enforceNotIsolatedCaller("startActivities");
4159        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4160                false, ALLOW_FULL_ONLY, "startActivity", null);
4161        // TODO: Switch to user app stacks here.
4162        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4163                resolvedTypes, resultTo, options, userId);
4164        return ret;
4165    }
4166
4167    final int startActivitiesInPackage(int uid, String callingPackage,
4168            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4169            Bundle options, int userId) {
4170
4171        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4172                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4173        // TODO: Switch to user app stacks here.
4174        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4175                resultTo, options, userId);
4176        return ret;
4177    }
4178
4179    @Override
4180    public void reportActivityFullyDrawn(IBinder token) {
4181        synchronized (this) {
4182            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4183            if (r == null) {
4184                return;
4185            }
4186            r.reportFullyDrawnLocked();
4187        }
4188    }
4189
4190    @Override
4191    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4192        synchronized (this) {
4193            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4194            if (r == null) {
4195                return;
4196            }
4197            if (r.task != null && r.task.mResizeable) {
4198                // Fixed screen orientation isn't supported with resizeable activities.
4199                return;
4200            }
4201            final long origId = Binder.clearCallingIdentity();
4202            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4203            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4204                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4205            if (config != null) {
4206                r.frozenBeforeDestroy = true;
4207                if (!updateConfigurationLocked(config, r, false, false)) {
4208                    mStackSupervisor.resumeTopActivitiesLocked();
4209                }
4210            }
4211            Binder.restoreCallingIdentity(origId);
4212        }
4213    }
4214
4215    @Override
4216    public int getRequestedOrientation(IBinder token) {
4217        synchronized (this) {
4218            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4219            if (r == null) {
4220                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4221            }
4222            return mWindowManager.getAppOrientation(r.appToken);
4223        }
4224    }
4225
4226    /**
4227     * This is the internal entry point for handling Activity.finish().
4228     *
4229     * @param token The Binder token referencing the Activity we want to finish.
4230     * @param resultCode Result code, if any, from this Activity.
4231     * @param resultData Result data (Intent), if any, from this Activity.
4232     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4233     *            the root Activity in the task.
4234     *
4235     * @return Returns true if the activity successfully finished, or false if it is still running.
4236     */
4237    @Override
4238    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4239            boolean finishTask) {
4240        // Refuse possible leaked file descriptors
4241        if (resultData != null && resultData.hasFileDescriptors() == true) {
4242            throw new IllegalArgumentException("File descriptors passed in Intent");
4243        }
4244
4245        synchronized(this) {
4246            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4247            if (r == null) {
4248                return true;
4249            }
4250            // Keep track of the root activity of the task before we finish it
4251            TaskRecord tr = r.task;
4252            ActivityRecord rootR = tr.getRootActivity();
4253            if (rootR == null) {
4254                Slog.w(TAG, "Finishing task with all activities already finished");
4255            }
4256            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4257            // finish.
4258            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4259                    mStackSupervisor.isLastLockedTask(tr)) {
4260                Slog.i(TAG, "Not finishing task in lock task mode");
4261                mStackSupervisor.showLockTaskToast();
4262                return false;
4263            }
4264            if (mController != null) {
4265                // Find the first activity that is not finishing.
4266                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4267                if (next != null) {
4268                    // ask watcher if this is allowed
4269                    boolean resumeOK = true;
4270                    try {
4271                        resumeOK = mController.activityResuming(next.packageName);
4272                    } catch (RemoteException e) {
4273                        mController = null;
4274                        Watchdog.getInstance().setActivityController(null);
4275                    }
4276
4277                    if (!resumeOK) {
4278                        Slog.i(TAG, "Not finishing activity because controller resumed");
4279                        return false;
4280                    }
4281                }
4282            }
4283            final long origId = Binder.clearCallingIdentity();
4284            try {
4285                boolean res;
4286                if (finishTask && r == rootR) {
4287                    // If requested, remove the task that is associated to this activity only if it
4288                    // was the root activity in the task. The result code and data is ignored
4289                    // because we don't support returning them across task boundaries.
4290                    res = removeTaskByIdLocked(tr.taskId, false);
4291                    if (!res) {
4292                        Slog.i(TAG, "Removing task failed to finish activity");
4293                    }
4294                } else {
4295                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4296                            resultData, "app-request", true);
4297                    if (!res) {
4298                        Slog.i(TAG, "Failed to finish by app-request");
4299                    }
4300                }
4301                return res;
4302            } finally {
4303                Binder.restoreCallingIdentity(origId);
4304            }
4305        }
4306    }
4307
4308    @Override
4309    public final void finishHeavyWeightApp() {
4310        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4311                != PackageManager.PERMISSION_GRANTED) {
4312            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4313                    + Binder.getCallingPid()
4314                    + ", uid=" + Binder.getCallingUid()
4315                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4316            Slog.w(TAG, msg);
4317            throw new SecurityException(msg);
4318        }
4319
4320        synchronized(this) {
4321            if (mHeavyWeightProcess == null) {
4322                return;
4323            }
4324
4325            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4326            for (int i = 0; i < activities.size(); i++) {
4327                ActivityRecord r = activities.get(i);
4328                if (!r.finishing && r.isInStackLocked()) {
4329                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4330                            null, "finish-heavy", true);
4331                }
4332            }
4333
4334            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4335                    mHeavyWeightProcess.userId, 0));
4336            mHeavyWeightProcess = null;
4337        }
4338    }
4339
4340    @Override
4341    public void crashApplication(int uid, int initialPid, String packageName,
4342            String message) {
4343        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4344                != PackageManager.PERMISSION_GRANTED) {
4345            String msg = "Permission Denial: crashApplication() from pid="
4346                    + Binder.getCallingPid()
4347                    + ", uid=" + Binder.getCallingUid()
4348                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4349            Slog.w(TAG, msg);
4350            throw new SecurityException(msg);
4351        }
4352
4353        synchronized(this) {
4354            ProcessRecord proc = null;
4355
4356            // Figure out which process to kill.  We don't trust that initialPid
4357            // still has any relation to current pids, so must scan through the
4358            // list.
4359            synchronized (mPidsSelfLocked) {
4360                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4361                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4362                    if (p.uid != uid) {
4363                        continue;
4364                    }
4365                    if (p.pid == initialPid) {
4366                        proc = p;
4367                        break;
4368                    }
4369                    if (p.pkgList.containsKey(packageName)) {
4370                        proc = p;
4371                    }
4372                }
4373            }
4374
4375            if (proc == null) {
4376                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4377                        + " initialPid=" + initialPid
4378                        + " packageName=" + packageName);
4379                return;
4380            }
4381
4382            if (proc.thread != null) {
4383                if (proc.pid == Process.myPid()) {
4384                    Log.w(TAG, "crashApplication: trying to crash self!");
4385                    return;
4386                }
4387                long ident = Binder.clearCallingIdentity();
4388                try {
4389                    proc.thread.scheduleCrash(message);
4390                } catch (RemoteException e) {
4391                }
4392                Binder.restoreCallingIdentity(ident);
4393            }
4394        }
4395    }
4396
4397    @Override
4398    public final void finishSubActivity(IBinder token, String resultWho,
4399            int requestCode) {
4400        synchronized(this) {
4401            final long origId = Binder.clearCallingIdentity();
4402            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4403            if (r != null) {
4404                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4405            }
4406            Binder.restoreCallingIdentity(origId);
4407        }
4408    }
4409
4410    @Override
4411    public boolean finishActivityAffinity(IBinder token) {
4412        synchronized(this) {
4413            final long origId = Binder.clearCallingIdentity();
4414            try {
4415                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4416                if (r == null) {
4417                    return false;
4418                }
4419
4420                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4421                // can finish.
4422                final TaskRecord task = r.task;
4423                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4424                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4425                    mStackSupervisor.showLockTaskToast();
4426                    return false;
4427                }
4428                return task.stack.finishActivityAffinityLocked(r);
4429            } finally {
4430                Binder.restoreCallingIdentity(origId);
4431            }
4432        }
4433    }
4434
4435    @Override
4436    public void finishVoiceTask(IVoiceInteractionSession session) {
4437        synchronized(this) {
4438            final long origId = Binder.clearCallingIdentity();
4439            try {
4440                mStackSupervisor.finishVoiceTask(session);
4441            } finally {
4442                Binder.restoreCallingIdentity(origId);
4443            }
4444        }
4445
4446    }
4447
4448    @Override
4449    public boolean releaseActivityInstance(IBinder token) {
4450        synchronized(this) {
4451            final long origId = Binder.clearCallingIdentity();
4452            try {
4453                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4454                if (r == null) {
4455                    return false;
4456                }
4457                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4458            } finally {
4459                Binder.restoreCallingIdentity(origId);
4460            }
4461        }
4462    }
4463
4464    @Override
4465    public void releaseSomeActivities(IApplicationThread appInt) {
4466        synchronized(this) {
4467            final long origId = Binder.clearCallingIdentity();
4468            try {
4469                ProcessRecord app = getRecordForAppLocked(appInt);
4470                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4471            } finally {
4472                Binder.restoreCallingIdentity(origId);
4473            }
4474        }
4475    }
4476
4477    @Override
4478    public boolean willActivityBeVisible(IBinder token) {
4479        synchronized(this) {
4480            ActivityStack stack = ActivityRecord.getStackLocked(token);
4481            if (stack != null) {
4482                return stack.willActivityBeVisibleLocked(token);
4483            }
4484            return false;
4485        }
4486    }
4487
4488    @Override
4489    public void overridePendingTransition(IBinder token, String packageName,
4490            int enterAnim, int exitAnim) {
4491        synchronized(this) {
4492            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4493            if (self == null) {
4494                return;
4495            }
4496
4497            final long origId = Binder.clearCallingIdentity();
4498
4499            if (self.state == ActivityState.RESUMED
4500                    || self.state == ActivityState.PAUSING) {
4501                mWindowManager.overridePendingAppTransition(packageName,
4502                        enterAnim, exitAnim, null);
4503            }
4504
4505            Binder.restoreCallingIdentity(origId);
4506        }
4507    }
4508
4509    /**
4510     * Main function for removing an existing process from the activity manager
4511     * as a result of that process going away.  Clears out all connections
4512     * to the process.
4513     */
4514    private final void handleAppDiedLocked(ProcessRecord app,
4515            boolean restarting, boolean allowRestart) {
4516        int pid = app.pid;
4517        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4518        if (!kept && !restarting) {
4519            removeLruProcessLocked(app);
4520            if (pid > 0) {
4521                ProcessList.remove(pid);
4522            }
4523        }
4524
4525        if (mProfileProc == app) {
4526            clearProfilerLocked();
4527        }
4528
4529        // Remove this application's activities from active lists.
4530        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4531
4532        app.activities.clear();
4533
4534        if (app.instrumentationClass != null) {
4535            Slog.w(TAG, "Crash of app " + app.processName
4536                  + " running instrumentation " + app.instrumentationClass);
4537            Bundle info = new Bundle();
4538            info.putString("shortMsg", "Process crashed.");
4539            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4540        }
4541
4542        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4543            // If there was nothing to resume, and we are not already
4544            // restarting this process, but there is a visible activity that
4545            // is hosted by the process...  then make sure all visible
4546            // activities are running, taking care of restarting this
4547            // process.
4548            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4549        }
4550    }
4551
4552    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4553        IBinder threadBinder = thread.asBinder();
4554        // Find the application record.
4555        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4556            ProcessRecord rec = mLruProcesses.get(i);
4557            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4558                return i;
4559            }
4560        }
4561        return -1;
4562    }
4563
4564    final ProcessRecord getRecordForAppLocked(
4565            IApplicationThread thread) {
4566        if (thread == null) {
4567            return null;
4568        }
4569
4570        int appIndex = getLRURecordIndexForAppLocked(thread);
4571        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4572    }
4573
4574    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4575        // If there are no longer any background processes running,
4576        // and the app that died was not running instrumentation,
4577        // then tell everyone we are now low on memory.
4578        boolean haveBg = false;
4579        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4580            ProcessRecord rec = mLruProcesses.get(i);
4581            if (rec.thread != null
4582                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4583                haveBg = true;
4584                break;
4585            }
4586        }
4587
4588        if (!haveBg) {
4589            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4590            if (doReport) {
4591                long now = SystemClock.uptimeMillis();
4592                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4593                    doReport = false;
4594                } else {
4595                    mLastMemUsageReportTime = now;
4596                }
4597            }
4598            final ArrayList<ProcessMemInfo> memInfos
4599                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4600            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4601            long now = SystemClock.uptimeMillis();
4602            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4603                ProcessRecord rec = mLruProcesses.get(i);
4604                if (rec == dyingProc || rec.thread == null) {
4605                    continue;
4606                }
4607                if (doReport) {
4608                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4609                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4610                }
4611                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4612                    // The low memory report is overriding any current
4613                    // state for a GC request.  Make sure to do
4614                    // heavy/important/visible/foreground processes first.
4615                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4616                        rec.lastRequestedGc = 0;
4617                    } else {
4618                        rec.lastRequestedGc = rec.lastLowMemory;
4619                    }
4620                    rec.reportLowMemory = true;
4621                    rec.lastLowMemory = now;
4622                    mProcessesToGc.remove(rec);
4623                    addProcessToGcListLocked(rec);
4624                }
4625            }
4626            if (doReport) {
4627                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4628                mHandler.sendMessage(msg);
4629            }
4630            scheduleAppGcsLocked();
4631        }
4632    }
4633
4634    final void appDiedLocked(ProcessRecord app) {
4635       appDiedLocked(app, app.pid, app.thread, false);
4636    }
4637
4638    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4639            boolean fromBinderDied) {
4640        // First check if this ProcessRecord is actually active for the pid.
4641        synchronized (mPidsSelfLocked) {
4642            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4643            if (curProc != app) {
4644                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4645                return;
4646            }
4647        }
4648
4649        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4650        synchronized (stats) {
4651            stats.noteProcessDiedLocked(app.info.uid, pid);
4652        }
4653
4654        if (!app.killed) {
4655            if (!fromBinderDied) {
4656                Process.killProcessQuiet(pid);
4657            }
4658            killProcessGroup(app.info.uid, pid);
4659            app.killed = true;
4660        }
4661
4662        // Clean up already done if the process has been re-started.
4663        if (app.pid == pid && app.thread != null &&
4664                app.thread.asBinder() == thread.asBinder()) {
4665            boolean doLowMem = app.instrumentationClass == null;
4666            boolean doOomAdj = doLowMem;
4667            if (!app.killedByAm) {
4668                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4669                        + ") has died");
4670                mAllowLowerMemLevel = true;
4671            } else {
4672                // Note that we always want to do oom adj to update our state with the
4673                // new number of procs.
4674                mAllowLowerMemLevel = false;
4675                doLowMem = false;
4676            }
4677            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4678            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4679                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4680            handleAppDiedLocked(app, false, true);
4681
4682            if (doOomAdj) {
4683                updateOomAdjLocked();
4684            }
4685            if (doLowMem) {
4686                doLowMemReportIfNeededLocked(app);
4687            }
4688        } else if (app.pid != pid) {
4689            // A new process has already been started.
4690            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4691                    + ") has died and restarted (pid " + app.pid + ").");
4692            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4693        } else if (DEBUG_PROCESSES) {
4694            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4695                    + thread.asBinder());
4696        }
4697    }
4698
4699    /**
4700     * If a stack trace dump file is configured, dump process stack traces.
4701     * @param clearTraces causes the dump file to be erased prior to the new
4702     *    traces being written, if true; when false, the new traces will be
4703     *    appended to any existing file content.
4704     * @param firstPids of dalvik VM processes to dump stack traces for first
4705     * @param lastPids of dalvik VM processes to dump stack traces for last
4706     * @param nativeProcs optional list of native process names to dump stack crawls
4707     * @return file containing stack traces, or null if no dump file is configured
4708     */
4709    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4710            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4711        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4712        if (tracesPath == null || tracesPath.length() == 0) {
4713            return null;
4714        }
4715
4716        File tracesFile = new File(tracesPath);
4717        try {
4718            File tracesDir = tracesFile.getParentFile();
4719            if (!tracesDir.exists()) {
4720                tracesDir.mkdirs();
4721                if (!SELinux.restorecon(tracesDir)) {
4722                    return null;
4723                }
4724            }
4725            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4726
4727            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4728            tracesFile.createNewFile();
4729            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4730        } catch (IOException e) {
4731            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4732            return null;
4733        }
4734
4735        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4736        return tracesFile;
4737    }
4738
4739    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4740            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4741        // Use a FileObserver to detect when traces finish writing.
4742        // The order of traces is considered important to maintain for legibility.
4743        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4744            @Override
4745            public synchronized void onEvent(int event, String path) { notify(); }
4746        };
4747
4748        try {
4749            observer.startWatching();
4750
4751            // First collect all of the stacks of the most important pids.
4752            if (firstPids != null) {
4753                try {
4754                    int num = firstPids.size();
4755                    for (int i = 0; i < num; i++) {
4756                        synchronized (observer) {
4757                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4758                            observer.wait(200);  // Wait for write-close, give up after 200msec
4759                        }
4760                    }
4761                } catch (InterruptedException e) {
4762                    Slog.wtf(TAG, e);
4763                }
4764            }
4765
4766            // Next collect the stacks of the native pids
4767            if (nativeProcs != null) {
4768                int[] pids = Process.getPidsForCommands(nativeProcs);
4769                if (pids != null) {
4770                    for (int pid : pids) {
4771                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4772                    }
4773                }
4774            }
4775
4776            // Lastly, measure CPU usage.
4777            if (processCpuTracker != null) {
4778                processCpuTracker.init();
4779                System.gc();
4780                processCpuTracker.update();
4781                try {
4782                    synchronized (processCpuTracker) {
4783                        processCpuTracker.wait(500); // measure over 1/2 second.
4784                    }
4785                } catch (InterruptedException e) {
4786                }
4787                processCpuTracker.update();
4788
4789                // We'll take the stack crawls of just the top apps using CPU.
4790                final int N = processCpuTracker.countWorkingStats();
4791                int numProcs = 0;
4792                for (int i=0; i<N && numProcs<5; i++) {
4793                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4794                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4795                        numProcs++;
4796                        try {
4797                            synchronized (observer) {
4798                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4799                                observer.wait(200);  // Wait for write-close, give up after 200msec
4800                            }
4801                        } catch (InterruptedException e) {
4802                            Slog.wtf(TAG, e);
4803                        }
4804
4805                    }
4806                }
4807            }
4808        } finally {
4809            observer.stopWatching();
4810        }
4811    }
4812
4813    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4814        if (true || IS_USER_BUILD) {
4815            return;
4816        }
4817        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4818        if (tracesPath == null || tracesPath.length() == 0) {
4819            return;
4820        }
4821
4822        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4823        StrictMode.allowThreadDiskWrites();
4824        try {
4825            final File tracesFile = new File(tracesPath);
4826            final File tracesDir = tracesFile.getParentFile();
4827            final File tracesTmp = new File(tracesDir, "__tmp__");
4828            try {
4829                if (!tracesDir.exists()) {
4830                    tracesDir.mkdirs();
4831                    if (!SELinux.restorecon(tracesDir.getPath())) {
4832                        return;
4833                    }
4834                }
4835                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4836
4837                if (tracesFile.exists()) {
4838                    tracesTmp.delete();
4839                    tracesFile.renameTo(tracesTmp);
4840                }
4841                StringBuilder sb = new StringBuilder();
4842                Time tobj = new Time();
4843                tobj.set(System.currentTimeMillis());
4844                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4845                sb.append(": ");
4846                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4847                sb.append(" since ");
4848                sb.append(msg);
4849                FileOutputStream fos = new FileOutputStream(tracesFile);
4850                fos.write(sb.toString().getBytes());
4851                if (app == null) {
4852                    fos.write("\n*** No application process!".getBytes());
4853                }
4854                fos.close();
4855                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4856            } catch (IOException e) {
4857                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4858                return;
4859            }
4860
4861            if (app != null) {
4862                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4863                firstPids.add(app.pid);
4864                dumpStackTraces(tracesPath, firstPids, null, null, null);
4865            }
4866
4867            File lastTracesFile = null;
4868            File curTracesFile = null;
4869            for (int i=9; i>=0; i--) {
4870                String name = String.format(Locale.US, "slow%02d.txt", i);
4871                curTracesFile = new File(tracesDir, name);
4872                if (curTracesFile.exists()) {
4873                    if (lastTracesFile != null) {
4874                        curTracesFile.renameTo(lastTracesFile);
4875                    } else {
4876                        curTracesFile.delete();
4877                    }
4878                }
4879                lastTracesFile = curTracesFile;
4880            }
4881            tracesFile.renameTo(curTracesFile);
4882            if (tracesTmp.exists()) {
4883                tracesTmp.renameTo(tracesFile);
4884            }
4885        } finally {
4886            StrictMode.setThreadPolicy(oldPolicy);
4887        }
4888    }
4889
4890    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4891            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4892        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4893        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4894
4895        if (mController != null) {
4896            try {
4897                // 0 == continue, -1 = kill process immediately
4898                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4899                if (res < 0 && app.pid != MY_PID) {
4900                    app.kill("anr", true);
4901                }
4902            } catch (RemoteException e) {
4903                mController = null;
4904                Watchdog.getInstance().setActivityController(null);
4905            }
4906        }
4907
4908        long anrTime = SystemClock.uptimeMillis();
4909        if (MONITOR_CPU_USAGE) {
4910            updateCpuStatsNow();
4911        }
4912
4913        synchronized (this) {
4914            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4915            if (mShuttingDown) {
4916                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4917                return;
4918            } else if (app.notResponding) {
4919                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4920                return;
4921            } else if (app.crashing) {
4922                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4923                return;
4924            }
4925
4926            // In case we come through here for the same app before completing
4927            // this one, mark as anring now so we will bail out.
4928            app.notResponding = true;
4929
4930            // Log the ANR to the event log.
4931            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4932                    app.processName, app.info.flags, annotation);
4933
4934            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4935            firstPids.add(app.pid);
4936
4937            int parentPid = app.pid;
4938            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4939            if (parentPid != app.pid) firstPids.add(parentPid);
4940
4941            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4942
4943            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4944                ProcessRecord r = mLruProcesses.get(i);
4945                if (r != null && r.thread != null) {
4946                    int pid = r.pid;
4947                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4948                        if (r.persistent) {
4949                            firstPids.add(pid);
4950                        } else {
4951                            lastPids.put(pid, Boolean.TRUE);
4952                        }
4953                    }
4954                }
4955            }
4956        }
4957
4958        // Log the ANR to the main log.
4959        StringBuilder info = new StringBuilder();
4960        info.setLength(0);
4961        info.append("ANR in ").append(app.processName);
4962        if (activity != null && activity.shortComponentName != null) {
4963            info.append(" (").append(activity.shortComponentName).append(")");
4964        }
4965        info.append("\n");
4966        info.append("PID: ").append(app.pid).append("\n");
4967        if (annotation != null) {
4968            info.append("Reason: ").append(annotation).append("\n");
4969        }
4970        if (parent != null && parent != activity) {
4971            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4972        }
4973
4974        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4975
4976        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4977                NATIVE_STACKS_OF_INTEREST);
4978
4979        String cpuInfo = null;
4980        if (MONITOR_CPU_USAGE) {
4981            updateCpuStatsNow();
4982            synchronized (mProcessCpuTracker) {
4983                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4984            }
4985            info.append(processCpuTracker.printCurrentLoad());
4986            info.append(cpuInfo);
4987        }
4988
4989        info.append(processCpuTracker.printCurrentState(anrTime));
4990
4991        Slog.e(TAG, info.toString());
4992        if (tracesFile == null) {
4993            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4994            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4995        }
4996
4997        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4998                cpuInfo, tracesFile, null);
4999
5000        if (mController != null) {
5001            try {
5002                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5003                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5004                if (res != 0) {
5005                    if (res < 0 && app.pid != MY_PID) {
5006                        app.kill("anr", true);
5007                    } else {
5008                        synchronized (this) {
5009                            mServices.scheduleServiceTimeoutLocked(app);
5010                        }
5011                    }
5012                    return;
5013                }
5014            } catch (RemoteException e) {
5015                mController = null;
5016                Watchdog.getInstance().setActivityController(null);
5017            }
5018        }
5019
5020        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5021        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5022                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5023
5024        synchronized (this) {
5025            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5026
5027            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5028                app.kill("bg anr", true);
5029                return;
5030            }
5031
5032            // Set the app's notResponding state, and look up the errorReportReceiver
5033            makeAppNotRespondingLocked(app,
5034                    activity != null ? activity.shortComponentName : null,
5035                    annotation != null ? "ANR " + annotation : "ANR",
5036                    info.toString());
5037
5038            // Bring up the infamous App Not Responding dialog
5039            Message msg = Message.obtain();
5040            HashMap<String, Object> map = new HashMap<String, Object>();
5041            msg.what = SHOW_NOT_RESPONDING_MSG;
5042            msg.obj = map;
5043            msg.arg1 = aboveSystem ? 1 : 0;
5044            map.put("app", app);
5045            if (activity != null) {
5046                map.put("activity", activity);
5047            }
5048
5049            mUiHandler.sendMessage(msg);
5050        }
5051    }
5052
5053    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5054        if (!mLaunchWarningShown) {
5055            mLaunchWarningShown = true;
5056            mUiHandler.post(new Runnable() {
5057                @Override
5058                public void run() {
5059                    synchronized (ActivityManagerService.this) {
5060                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5061                        d.show();
5062                        mUiHandler.postDelayed(new Runnable() {
5063                            @Override
5064                            public void run() {
5065                                synchronized (ActivityManagerService.this) {
5066                                    d.dismiss();
5067                                    mLaunchWarningShown = false;
5068                                }
5069                            }
5070                        }, 4000);
5071                    }
5072                }
5073            });
5074        }
5075    }
5076
5077    @Override
5078    public boolean clearApplicationUserData(final String packageName,
5079            final IPackageDataObserver observer, int userId) {
5080        enforceNotIsolatedCaller("clearApplicationUserData");
5081        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5082            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5083        }
5084        int uid = Binder.getCallingUid();
5085        int pid = Binder.getCallingPid();
5086        userId = handleIncomingUser(pid, uid,
5087                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5088        long callingId = Binder.clearCallingIdentity();
5089        try {
5090            IPackageManager pm = AppGlobals.getPackageManager();
5091            int pkgUid = -1;
5092            synchronized(this) {
5093                try {
5094                    pkgUid = pm.getPackageUid(packageName, userId);
5095                } catch (RemoteException e) {
5096                }
5097                if (pkgUid == -1) {
5098                    Slog.w(TAG, "Invalid packageName: " + packageName);
5099                    if (observer != null) {
5100                        try {
5101                            observer.onRemoveCompleted(packageName, false);
5102                        } catch (RemoteException e) {
5103                            Slog.i(TAG, "Observer no longer exists.");
5104                        }
5105                    }
5106                    return false;
5107                }
5108                if (uid == pkgUid || checkComponentPermission(
5109                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5110                        pid, uid, -1, true)
5111                        == PackageManager.PERMISSION_GRANTED) {
5112                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5113                } else {
5114                    throw new SecurityException("PID " + pid + " does not have permission "
5115                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5116                                    + " of package " + packageName);
5117                }
5118
5119                // Remove all tasks match the cleared application package and user
5120                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5121                    final TaskRecord tr = mRecentTasks.get(i);
5122                    final String taskPackageName =
5123                            tr.getBaseIntent().getComponent().getPackageName();
5124                    if (tr.userId != userId) continue;
5125                    if (!taskPackageName.equals(packageName)) continue;
5126                    removeTaskByIdLocked(tr.taskId, false);
5127                }
5128            }
5129
5130            try {
5131                // Clear application user data
5132                pm.clearApplicationUserData(packageName, observer, userId);
5133
5134                synchronized(this) {
5135                    // Remove all permissions granted from/to this package
5136                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5137                }
5138
5139                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5140                        Uri.fromParts("package", packageName, null));
5141                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5142                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5143                        null, null, 0, null, null, null, null, false, false, userId);
5144            } catch (RemoteException e) {
5145            }
5146        } finally {
5147            Binder.restoreCallingIdentity(callingId);
5148        }
5149        return true;
5150    }
5151
5152    @Override
5153    public void killBackgroundProcesses(final String packageName, int userId) {
5154        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5155                != PackageManager.PERMISSION_GRANTED &&
5156                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5157                        != PackageManager.PERMISSION_GRANTED) {
5158            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5159                    + Binder.getCallingPid()
5160                    + ", uid=" + Binder.getCallingUid()
5161                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5162            Slog.w(TAG, msg);
5163            throw new SecurityException(msg);
5164        }
5165
5166        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5167                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5168        long callingId = Binder.clearCallingIdentity();
5169        try {
5170            IPackageManager pm = AppGlobals.getPackageManager();
5171            synchronized(this) {
5172                int appId = -1;
5173                try {
5174                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5175                } catch (RemoteException e) {
5176                }
5177                if (appId == -1) {
5178                    Slog.w(TAG, "Invalid packageName: " + packageName);
5179                    return;
5180                }
5181                killPackageProcessesLocked(packageName, appId, userId,
5182                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5183            }
5184        } finally {
5185            Binder.restoreCallingIdentity(callingId);
5186        }
5187    }
5188
5189    @Override
5190    public void killAllBackgroundProcesses() {
5191        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5192                != PackageManager.PERMISSION_GRANTED) {
5193            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5194                    + Binder.getCallingPid()
5195                    + ", uid=" + Binder.getCallingUid()
5196                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5197            Slog.w(TAG, msg);
5198            throw new SecurityException(msg);
5199        }
5200
5201        long callingId = Binder.clearCallingIdentity();
5202        try {
5203            synchronized(this) {
5204                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5205                final int NP = mProcessNames.getMap().size();
5206                for (int ip=0; ip<NP; ip++) {
5207                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5208                    final int NA = apps.size();
5209                    for (int ia=0; ia<NA; ia++) {
5210                        ProcessRecord app = apps.valueAt(ia);
5211                        if (app.persistent) {
5212                            // we don't kill persistent processes
5213                            continue;
5214                        }
5215                        if (app.removed) {
5216                            procs.add(app);
5217                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5218                            app.removed = true;
5219                            procs.add(app);
5220                        }
5221                    }
5222                }
5223
5224                int N = procs.size();
5225                for (int i=0; i<N; i++) {
5226                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5227                }
5228                mAllowLowerMemLevel = true;
5229                updateOomAdjLocked();
5230                doLowMemReportIfNeededLocked(null);
5231            }
5232        } finally {
5233            Binder.restoreCallingIdentity(callingId);
5234        }
5235    }
5236
5237    @Override
5238    public void forceStopPackage(final String packageName, int userId) {
5239        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5240                != PackageManager.PERMISSION_GRANTED) {
5241            String msg = "Permission Denial: forceStopPackage() from pid="
5242                    + Binder.getCallingPid()
5243                    + ", uid=" + Binder.getCallingUid()
5244                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5245            Slog.w(TAG, msg);
5246            throw new SecurityException(msg);
5247        }
5248        final int callingPid = Binder.getCallingPid();
5249        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5250                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5251        long callingId = Binder.clearCallingIdentity();
5252        try {
5253            IPackageManager pm = AppGlobals.getPackageManager();
5254            synchronized(this) {
5255                int[] users = userId == UserHandle.USER_ALL
5256                        ? getUsersLocked() : new int[] { userId };
5257                for (int user : users) {
5258                    int pkgUid = -1;
5259                    try {
5260                        pkgUid = pm.getPackageUid(packageName, user);
5261                    } catch (RemoteException e) {
5262                    }
5263                    if (pkgUid == -1) {
5264                        Slog.w(TAG, "Invalid packageName: " + packageName);
5265                        continue;
5266                    }
5267                    try {
5268                        pm.setPackageStoppedState(packageName, true, user);
5269                    } catch (RemoteException e) {
5270                    } catch (IllegalArgumentException e) {
5271                        Slog.w(TAG, "Failed trying to unstop package "
5272                                + packageName + ": " + e);
5273                    }
5274                    if (isUserRunningLocked(user, false)) {
5275                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5276                    }
5277                }
5278            }
5279        } finally {
5280            Binder.restoreCallingIdentity(callingId);
5281        }
5282    }
5283
5284    @Override
5285    public void addPackageDependency(String packageName) {
5286        synchronized (this) {
5287            int callingPid = Binder.getCallingPid();
5288            if (callingPid == Process.myPid()) {
5289                //  Yeah, um, no.
5290                return;
5291            }
5292            ProcessRecord proc;
5293            synchronized (mPidsSelfLocked) {
5294                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5295            }
5296            if (proc != null) {
5297                if (proc.pkgDeps == null) {
5298                    proc.pkgDeps = new ArraySet<String>(1);
5299                }
5300                proc.pkgDeps.add(packageName);
5301            }
5302        }
5303    }
5304
5305    /*
5306     * The pkg name and app id have to be specified.
5307     */
5308    @Override
5309    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5310        if (pkg == null) {
5311            return;
5312        }
5313        // Make sure the uid is valid.
5314        if (appid < 0) {
5315            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5316            return;
5317        }
5318        int callerUid = Binder.getCallingUid();
5319        // Only the system server can kill an application
5320        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5321            // Post an aysnc message to kill the application
5322            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5323            msg.arg1 = appid;
5324            msg.arg2 = 0;
5325            Bundle bundle = new Bundle();
5326            bundle.putString("pkg", pkg);
5327            bundle.putString("reason", reason);
5328            msg.obj = bundle;
5329            mHandler.sendMessage(msg);
5330        } else {
5331            throw new SecurityException(callerUid + " cannot kill pkg: " +
5332                    pkg);
5333        }
5334    }
5335
5336    @Override
5337    public void closeSystemDialogs(String reason) {
5338        enforceNotIsolatedCaller("closeSystemDialogs");
5339
5340        final int pid = Binder.getCallingPid();
5341        final int uid = Binder.getCallingUid();
5342        final long origId = Binder.clearCallingIdentity();
5343        try {
5344            synchronized (this) {
5345                // Only allow this from foreground processes, so that background
5346                // applications can't abuse it to prevent system UI from being shown.
5347                if (uid >= Process.FIRST_APPLICATION_UID) {
5348                    ProcessRecord proc;
5349                    synchronized (mPidsSelfLocked) {
5350                        proc = mPidsSelfLocked.get(pid);
5351                    }
5352                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5353                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5354                                + " from background process " + proc);
5355                        return;
5356                    }
5357                }
5358                closeSystemDialogsLocked(reason);
5359            }
5360        } finally {
5361            Binder.restoreCallingIdentity(origId);
5362        }
5363    }
5364
5365    void closeSystemDialogsLocked(String reason) {
5366        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5367        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5368                | Intent.FLAG_RECEIVER_FOREGROUND);
5369        if (reason != null) {
5370            intent.putExtra("reason", reason);
5371        }
5372        mWindowManager.closeSystemDialogs(reason);
5373
5374        mStackSupervisor.closeSystemDialogsLocked();
5375
5376        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5377                AppOpsManager.OP_NONE, null, false, false,
5378                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5379    }
5380
5381    @Override
5382    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5383        enforceNotIsolatedCaller("getProcessMemoryInfo");
5384        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5385        for (int i=pids.length-1; i>=0; i--) {
5386            ProcessRecord proc;
5387            int oomAdj;
5388            synchronized (this) {
5389                synchronized (mPidsSelfLocked) {
5390                    proc = mPidsSelfLocked.get(pids[i]);
5391                    oomAdj = proc != null ? proc.setAdj : 0;
5392                }
5393            }
5394            infos[i] = new Debug.MemoryInfo();
5395            Debug.getMemoryInfo(pids[i], infos[i]);
5396            if (proc != null) {
5397                synchronized (this) {
5398                    if (proc.thread != null && proc.setAdj == oomAdj) {
5399                        // Record this for posterity if the process has been stable.
5400                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5401                                infos[i].getTotalUss(), false, proc.pkgList);
5402                    }
5403                }
5404            }
5405        }
5406        return infos;
5407    }
5408
5409    @Override
5410    public long[] getProcessPss(int[] pids) {
5411        enforceNotIsolatedCaller("getProcessPss");
5412        long[] pss = new long[pids.length];
5413        for (int i=pids.length-1; i>=0; i--) {
5414            ProcessRecord proc;
5415            int oomAdj;
5416            synchronized (this) {
5417                synchronized (mPidsSelfLocked) {
5418                    proc = mPidsSelfLocked.get(pids[i]);
5419                    oomAdj = proc != null ? proc.setAdj : 0;
5420                }
5421            }
5422            long[] tmpUss = new long[1];
5423            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5424            if (proc != null) {
5425                synchronized (this) {
5426                    if (proc.thread != null && proc.setAdj == oomAdj) {
5427                        // Record this for posterity if the process has been stable.
5428                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5429                    }
5430                }
5431            }
5432        }
5433        return pss;
5434    }
5435
5436    @Override
5437    public void killApplicationProcess(String processName, int uid) {
5438        if (processName == null) {
5439            return;
5440        }
5441
5442        int callerUid = Binder.getCallingUid();
5443        // Only the system server can kill an application
5444        if (callerUid == Process.SYSTEM_UID) {
5445            synchronized (this) {
5446                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5447                if (app != null && app.thread != null) {
5448                    try {
5449                        app.thread.scheduleSuicide();
5450                    } catch (RemoteException e) {
5451                        // If the other end already died, then our work here is done.
5452                    }
5453                } else {
5454                    Slog.w(TAG, "Process/uid not found attempting kill of "
5455                            + processName + " / " + uid);
5456                }
5457            }
5458        } else {
5459            throw new SecurityException(callerUid + " cannot kill app process: " +
5460                    processName);
5461        }
5462    }
5463
5464    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5465        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5466                false, true, false, false, UserHandle.getUserId(uid), reason);
5467        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5468                Uri.fromParts("package", packageName, null));
5469        if (!mProcessesReady) {
5470            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5471                    | Intent.FLAG_RECEIVER_FOREGROUND);
5472        }
5473        intent.putExtra(Intent.EXTRA_UID, uid);
5474        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5475        broadcastIntentLocked(null, null, intent,
5476                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5477                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5478    }
5479
5480    private void forceStopUserLocked(int userId, String reason) {
5481        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5482        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5483        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5484                | Intent.FLAG_RECEIVER_FOREGROUND);
5485        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5486        broadcastIntentLocked(null, null, intent,
5487                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5488                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5489    }
5490
5491    private final boolean killPackageProcessesLocked(String packageName, int appId,
5492            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5493            boolean doit, boolean evenPersistent, String reason) {
5494        ArrayList<ProcessRecord> procs = new ArrayList<>();
5495
5496        // Remove all processes this package may have touched: all with the
5497        // same UID (except for the system or root user), and all whose name
5498        // matches the package name.
5499        final int NP = mProcessNames.getMap().size();
5500        for (int ip=0; ip<NP; ip++) {
5501            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5502            final int NA = apps.size();
5503            for (int ia=0; ia<NA; ia++) {
5504                ProcessRecord app = apps.valueAt(ia);
5505                if (app.persistent && !evenPersistent) {
5506                    // we don't kill persistent processes
5507                    continue;
5508                }
5509                if (app.removed) {
5510                    if (doit) {
5511                        procs.add(app);
5512                    }
5513                    continue;
5514                }
5515
5516                // Skip process if it doesn't meet our oom adj requirement.
5517                if (app.setAdj < minOomAdj) {
5518                    continue;
5519                }
5520
5521                // If no package is specified, we call all processes under the
5522                // give user id.
5523                if (packageName == null) {
5524                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5525                        continue;
5526                    }
5527                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5528                        continue;
5529                    }
5530                // Package has been specified, we want to hit all processes
5531                // that match it.  We need to qualify this by the processes
5532                // that are running under the specified app and user ID.
5533                } else {
5534                    final boolean isDep = app.pkgDeps != null
5535                            && app.pkgDeps.contains(packageName);
5536                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5537                        continue;
5538                    }
5539                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5540                        continue;
5541                    }
5542                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5543                        continue;
5544                    }
5545                }
5546
5547                // Process has passed all conditions, kill it!
5548                if (!doit) {
5549                    return true;
5550                }
5551                app.removed = true;
5552                procs.add(app);
5553            }
5554        }
5555
5556        int N = procs.size();
5557        for (int i=0; i<N; i++) {
5558            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5559        }
5560        updateOomAdjLocked();
5561        return N > 0;
5562    }
5563
5564    private void cleanupDisabledPackageComponentsLocked(
5565            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5566
5567        Set<String> disabledClasses = null;
5568        boolean packageDisabled = false;
5569        IPackageManager pm = AppGlobals.getPackageManager();
5570
5571        if (changedClasses == null) {
5572            // Nothing changed...
5573            return;
5574        }
5575
5576        // Determine enable/disable state of the package and its components.
5577        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5578        for (int i = changedClasses.length - 1; i >= 0; i--) {
5579            final String changedClass = changedClasses[i];
5580
5581            if (changedClass.equals(packageName)) {
5582                try {
5583                    // Entire package setting changed
5584                    enabled = pm.getApplicationEnabledSetting(packageName,
5585                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5586                } catch (Exception e) {
5587                    // No such package/component; probably racing with uninstall.  In any
5588                    // event it means we have nothing further to do here.
5589                    return;
5590                }
5591                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5592                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5593                if (packageDisabled) {
5594                    // Entire package is disabled.
5595                    // No need to continue to check component states.
5596                    disabledClasses = null;
5597                    break;
5598                }
5599            } else {
5600                try {
5601                    enabled = pm.getComponentEnabledSetting(
5602                            new ComponentName(packageName, changedClass),
5603                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5604                } catch (Exception e) {
5605                    // As above, probably racing with uninstall.
5606                    return;
5607                }
5608                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5609                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5610                    if (disabledClasses == null) {
5611                        disabledClasses = new ArraySet<>(changedClasses.length);
5612                    }
5613                    disabledClasses.add(changedClass);
5614                }
5615            }
5616        }
5617
5618        if (!packageDisabled && disabledClasses == null) {
5619            // Nothing to do here...
5620            return;
5621        }
5622
5623        // Clean-up disabled activities.
5624        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5625                packageName, disabledClasses, true, false, userId) && mBooted) {
5626            mStackSupervisor.resumeTopActivitiesLocked();
5627            mStackSupervisor.scheduleIdleLocked();
5628        }
5629
5630        // Clean-up disabled tasks
5631        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5632
5633        // Clean-up disabled services.
5634        mServices.bringDownDisabledPackageServicesLocked(
5635                packageName, disabledClasses, userId, false, killProcess, true);
5636
5637        // Clean-up disabled providers.
5638        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5639        mProviderMap.collectPackageProvidersLocked(
5640                packageName, disabledClasses, true, false, userId, providers);
5641        for (int i = providers.size() - 1; i >= 0; i--) {
5642            removeDyingProviderLocked(null, providers.get(i), true);
5643        }
5644
5645        // Clean-up disabled broadcast receivers.
5646        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5647            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5648                    packageName, disabledClasses, userId, true);
5649        }
5650
5651    }
5652
5653    private final boolean forceStopPackageLocked(String packageName, int appId,
5654            boolean callerWillRestart, boolean purgeCache, boolean doit,
5655            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5656        int i;
5657
5658        if (userId == UserHandle.USER_ALL && packageName == null) {
5659            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5660        }
5661
5662        if (appId < 0 && packageName != null) {
5663            try {
5664                appId = UserHandle.getAppId(
5665                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5666            } catch (RemoteException e) {
5667            }
5668        }
5669
5670        if (doit) {
5671            if (packageName != null) {
5672                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5673                        + " user=" + userId + ": " + reason);
5674            } else {
5675                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5676            }
5677
5678            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5679            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5680                SparseArray<Long> ba = pmap.valueAt(ip);
5681                for (i = ba.size() - 1; i >= 0; i--) {
5682                    boolean remove = false;
5683                    final int entUid = ba.keyAt(i);
5684                    if (packageName != null) {
5685                        if (userId == UserHandle.USER_ALL) {
5686                            if (UserHandle.getAppId(entUid) == appId) {
5687                                remove = true;
5688                            }
5689                        } else {
5690                            if (entUid == UserHandle.getUid(userId, appId)) {
5691                                remove = true;
5692                            }
5693                        }
5694                    } else if (UserHandle.getUserId(entUid) == userId) {
5695                        remove = true;
5696                    }
5697                    if (remove) {
5698                        ba.removeAt(i);
5699                    }
5700                }
5701                if (ba.size() == 0) {
5702                    pmap.removeAt(ip);
5703                }
5704            }
5705        }
5706
5707        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5708                -100, callerWillRestart, true, doit, evenPersistent,
5709                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5710
5711        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5712                packageName, null, doit, evenPersistent, userId)) {
5713            if (!doit) {
5714                return true;
5715            }
5716            didSomething = true;
5717        }
5718
5719        if (mServices.bringDownDisabledPackageServicesLocked(
5720                packageName, null, userId, evenPersistent, true, doit)) {
5721            if (!doit) {
5722                return true;
5723            }
5724            didSomething = true;
5725        }
5726
5727        if (packageName == null) {
5728            // Remove all sticky broadcasts from this user.
5729            mStickyBroadcasts.remove(userId);
5730        }
5731
5732        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5733        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5734                userId, providers)) {
5735            if (!doit) {
5736                return true;
5737            }
5738            didSomething = true;
5739        }
5740        for (i = providers.size() - 1; i >= 0; i--) {
5741            removeDyingProviderLocked(null, providers.get(i), true);
5742        }
5743
5744        // Remove transient permissions granted from/to this package/user
5745        removeUriPermissionsForPackageLocked(packageName, userId, false);
5746
5747        if (doit) {
5748            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5749                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5750                        packageName, null, userId, doit);
5751            }
5752        }
5753
5754        if (packageName == null || uninstalling) {
5755            // Remove pending intents.  For now we only do this when force
5756            // stopping users, because we have some problems when doing this
5757            // for packages -- app widgets are not currently cleaned up for
5758            // such packages, so they can be left with bad pending intents.
5759            if (mIntentSenderRecords.size() > 0) {
5760                Iterator<WeakReference<PendingIntentRecord>> it
5761                        = mIntentSenderRecords.values().iterator();
5762                while (it.hasNext()) {
5763                    WeakReference<PendingIntentRecord> wpir = it.next();
5764                    if (wpir == null) {
5765                        it.remove();
5766                        continue;
5767                    }
5768                    PendingIntentRecord pir = wpir.get();
5769                    if (pir == null) {
5770                        it.remove();
5771                        continue;
5772                    }
5773                    if (packageName == null) {
5774                        // Stopping user, remove all objects for the user.
5775                        if (pir.key.userId != userId) {
5776                            // Not the same user, skip it.
5777                            continue;
5778                        }
5779                    } else {
5780                        if (UserHandle.getAppId(pir.uid) != appId) {
5781                            // Different app id, skip it.
5782                            continue;
5783                        }
5784                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5785                            // Different user, skip it.
5786                            continue;
5787                        }
5788                        if (!pir.key.packageName.equals(packageName)) {
5789                            // Different package, skip it.
5790                            continue;
5791                        }
5792                    }
5793                    if (!doit) {
5794                        return true;
5795                    }
5796                    didSomething = true;
5797                    it.remove();
5798                    pir.canceled = true;
5799                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5800                        pir.key.activity.pendingResults.remove(pir.ref);
5801                    }
5802                }
5803            }
5804        }
5805
5806        if (doit) {
5807            if (purgeCache && packageName != null) {
5808                AttributeCache ac = AttributeCache.instance();
5809                if (ac != null) {
5810                    ac.removePackage(packageName);
5811                }
5812            }
5813            if (mBooted) {
5814                mStackSupervisor.resumeTopActivitiesLocked();
5815                mStackSupervisor.scheduleIdleLocked();
5816            }
5817        }
5818
5819        return didSomething;
5820    }
5821
5822    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5823        ProcessRecord old = mProcessNames.remove(name, uid);
5824        if (old != null) {
5825            old.uidRecord.numProcs--;
5826            if (old.uidRecord.numProcs == 0) {
5827                // No more processes using this uid, tell clients it is gone.
5828                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5829                        "No more processes in " + old.uidRecord);
5830                enqueueUidChangeLocked(old.uidRecord, true);
5831                mActiveUids.remove(uid);
5832            }
5833            old.uidRecord = null;
5834        }
5835        mIsolatedProcesses.remove(uid);
5836        return old;
5837    }
5838
5839    private final void addProcessNameLocked(ProcessRecord proc) {
5840        // We shouldn't already have a process under this name, but just in case we
5841        // need to clean up whatever may be there now.
5842        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5843        if (old == proc && proc.persistent) {
5844            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
5845            Slog.w(TAG, "Re-adding persistent process " + proc);
5846        } else if (old != null) {
5847            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5848        }
5849        UidRecord uidRec = mActiveUids.get(proc.uid);
5850        if (uidRec == null) {
5851            uidRec = new UidRecord(proc.uid);
5852            // This is the first appearance of the uid, report it now!
5853            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5854                    "Creating new process uid: " + uidRec);
5855            mActiveUids.put(proc.uid, uidRec);
5856            enqueueUidChangeLocked(uidRec, false);
5857        }
5858        proc.uidRecord = uidRec;
5859        uidRec.numProcs++;
5860        mProcessNames.put(proc.processName, proc.uid, proc);
5861        if (proc.isolated) {
5862            mIsolatedProcesses.put(proc.uid, proc);
5863        }
5864    }
5865
5866    private final boolean removeProcessLocked(ProcessRecord app,
5867            boolean callerWillRestart, boolean allowRestart, String reason) {
5868        final String name = app.processName;
5869        final int uid = app.uid;
5870        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5871            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5872
5873        removeProcessNameLocked(name, uid);
5874        if (mHeavyWeightProcess == app) {
5875            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5876                    mHeavyWeightProcess.userId, 0));
5877            mHeavyWeightProcess = null;
5878        }
5879        boolean needRestart = false;
5880        if (app.pid > 0 && app.pid != MY_PID) {
5881            int pid = app.pid;
5882            synchronized (mPidsSelfLocked) {
5883                mPidsSelfLocked.remove(pid);
5884                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5885            }
5886            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5887            if (app.isolated) {
5888                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5889            }
5890            boolean willRestart = false;
5891            if (app.persistent && !app.isolated) {
5892                if (!callerWillRestart) {
5893                    willRestart = true;
5894                } else {
5895                    needRestart = true;
5896                }
5897            }
5898            app.kill(reason, true);
5899            handleAppDiedLocked(app, willRestart, allowRestart);
5900            if (willRestart) {
5901                removeLruProcessLocked(app);
5902                addAppLocked(app.info, false, null /* ABI override */);
5903            }
5904        } else {
5905            mRemovedProcesses.add(app);
5906        }
5907
5908        return needRestart;
5909    }
5910
5911    private final void processStartTimedOutLocked(ProcessRecord app) {
5912        final int pid = app.pid;
5913        boolean gone = false;
5914        synchronized (mPidsSelfLocked) {
5915            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5916            if (knownApp != null && knownApp.thread == null) {
5917                mPidsSelfLocked.remove(pid);
5918                gone = true;
5919            }
5920        }
5921
5922        if (gone) {
5923            Slog.w(TAG, "Process " + app + " failed to attach");
5924            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5925                    pid, app.uid, app.processName);
5926            removeProcessNameLocked(app.processName, app.uid);
5927            if (mHeavyWeightProcess == app) {
5928                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5929                        mHeavyWeightProcess.userId, 0));
5930                mHeavyWeightProcess = null;
5931            }
5932            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5933            if (app.isolated) {
5934                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5935            }
5936            // Take care of any launching providers waiting for this process.
5937            checkAppInLaunchingProvidersLocked(app, true);
5938            // Take care of any services that are waiting for the process.
5939            mServices.processStartTimedOutLocked(app);
5940            app.kill("start timeout", true);
5941            removeLruProcessLocked(app);
5942            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5943                Slog.w(TAG, "Unattached app died before backup, skipping");
5944                try {
5945                    IBackupManager bm = IBackupManager.Stub.asInterface(
5946                            ServiceManager.getService(Context.BACKUP_SERVICE));
5947                    bm.agentDisconnected(app.info.packageName);
5948                } catch (RemoteException e) {
5949                    // Can't happen; the backup manager is local
5950                }
5951            }
5952            if (isPendingBroadcastProcessLocked(pid)) {
5953                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5954                skipPendingBroadcastLocked(pid);
5955            }
5956        } else {
5957            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5958        }
5959    }
5960
5961    private final boolean attachApplicationLocked(IApplicationThread thread,
5962            int pid) {
5963
5964        // Find the application record that is being attached...  either via
5965        // the pid if we are running in multiple processes, or just pull the
5966        // next app record if we are emulating process with anonymous threads.
5967        ProcessRecord app;
5968        if (pid != MY_PID && pid >= 0) {
5969            synchronized (mPidsSelfLocked) {
5970                app = mPidsSelfLocked.get(pid);
5971            }
5972        } else {
5973            app = null;
5974        }
5975
5976        if (app == null) {
5977            Slog.w(TAG, "No pending application record for pid " + pid
5978                    + " (IApplicationThread " + thread + "); dropping process");
5979            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5980            if (pid > 0 && pid != MY_PID) {
5981                Process.killProcessQuiet(pid);
5982                //TODO: killProcessGroup(app.info.uid, pid);
5983            } else {
5984                try {
5985                    thread.scheduleExit();
5986                } catch (Exception e) {
5987                    // Ignore exceptions.
5988                }
5989            }
5990            return false;
5991        }
5992
5993        // If this application record is still attached to a previous
5994        // process, clean it up now.
5995        if (app.thread != null) {
5996            handleAppDiedLocked(app, true, true);
5997        }
5998
5999        // Tell the process all about itself.
6000
6001        if (DEBUG_ALL) Slog.v(
6002                TAG, "Binding process pid " + pid + " to record " + app);
6003
6004        final String processName = app.processName;
6005        try {
6006            AppDeathRecipient adr = new AppDeathRecipient(
6007                    app, pid, thread);
6008            thread.asBinder().linkToDeath(adr, 0);
6009            app.deathRecipient = adr;
6010        } catch (RemoteException e) {
6011            app.resetPackageList(mProcessStats);
6012            startProcessLocked(app, "link fail", processName);
6013            return false;
6014        }
6015
6016        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6017
6018        app.makeActive(thread, mProcessStats);
6019        app.curAdj = app.setAdj = -100;
6020        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6021        app.forcingToForeground = null;
6022        updateProcessForegroundLocked(app, false, false);
6023        app.hasShownUi = false;
6024        app.debugging = false;
6025        app.cached = false;
6026        app.killedByAm = false;
6027
6028        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6029
6030        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6031        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6032
6033        if (!normalMode) {
6034            Slog.i(TAG, "Launching preboot mode app: " + app);
6035        }
6036
6037        if (DEBUG_ALL) Slog.v(
6038            TAG, "New app record " + app
6039            + " thread=" + thread.asBinder() + " pid=" + pid);
6040        try {
6041            int testMode = IApplicationThread.DEBUG_OFF;
6042            if (mDebugApp != null && mDebugApp.equals(processName)) {
6043                testMode = mWaitForDebugger
6044                    ? IApplicationThread.DEBUG_WAIT
6045                    : IApplicationThread.DEBUG_ON;
6046                app.debugging = true;
6047                if (mDebugTransient) {
6048                    mDebugApp = mOrigDebugApp;
6049                    mWaitForDebugger = mOrigWaitForDebugger;
6050                }
6051            }
6052            String profileFile = app.instrumentationProfileFile;
6053            ParcelFileDescriptor profileFd = null;
6054            int samplingInterval = 0;
6055            boolean profileAutoStop = false;
6056            if (mProfileApp != null && mProfileApp.equals(processName)) {
6057                mProfileProc = app;
6058                profileFile = mProfileFile;
6059                profileFd = mProfileFd;
6060                samplingInterval = mSamplingInterval;
6061                profileAutoStop = mAutoStopProfiler;
6062            }
6063            boolean enableOpenGlTrace = false;
6064            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6065                enableOpenGlTrace = true;
6066                mOpenGlTraceApp = null;
6067            }
6068
6069            // If the app is being launched for restore or full backup, set it up specially
6070            boolean isRestrictedBackupMode = false;
6071            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6072                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6073                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6074                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6075            }
6076
6077            ensurePackageDexOpt(app.instrumentationInfo != null
6078                    ? app.instrumentationInfo.packageName
6079                    : app.info.packageName);
6080            if (app.instrumentationClass != null) {
6081                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6082            }
6083            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6084                    + processName + " with config " + mConfiguration);
6085            ApplicationInfo appInfo = app.instrumentationInfo != null
6086                    ? app.instrumentationInfo : app.info;
6087            app.compat = compatibilityInfoForPackageLocked(appInfo);
6088            if (profileFd != null) {
6089                profileFd = profileFd.dup();
6090            }
6091            ProfilerInfo profilerInfo = profileFile == null ? null
6092                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6093            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6094                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6095                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6096                    isRestrictedBackupMode || !normalMode, app.persistent,
6097                    new Configuration(mConfiguration), app.compat,
6098                    getCommonServicesLocked(app.isolated),
6099                    mCoreSettingsObserver.getCoreSettingsLocked());
6100            updateLruProcessLocked(app, false, null);
6101            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6102        } catch (Exception e) {
6103            // todo: Yikes!  What should we do?  For now we will try to
6104            // start another process, but that could easily get us in
6105            // an infinite loop of restarting processes...
6106            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6107
6108            app.resetPackageList(mProcessStats);
6109            app.unlinkDeathRecipient();
6110            startProcessLocked(app, "bind fail", processName);
6111            return false;
6112        }
6113
6114        // Remove this record from the list of starting applications.
6115        mPersistentStartingProcesses.remove(app);
6116        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6117                "Attach application locked removing on hold: " + app);
6118        mProcessesOnHold.remove(app);
6119
6120        boolean badApp = false;
6121        boolean didSomething = false;
6122
6123        // See if the top visible activity is waiting to run in this process...
6124        if (normalMode) {
6125            try {
6126                if (mStackSupervisor.attachApplicationLocked(app)) {
6127                    didSomething = true;
6128                }
6129            } catch (Exception e) {
6130                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6131                badApp = true;
6132            }
6133        }
6134
6135        // Find any services that should be running in this process...
6136        if (!badApp) {
6137            try {
6138                didSomething |= mServices.attachApplicationLocked(app, processName);
6139            } catch (Exception e) {
6140                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6141                badApp = true;
6142            }
6143        }
6144
6145        // Check if a next-broadcast receiver is in this process...
6146        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6147            try {
6148                didSomething |= sendPendingBroadcastsLocked(app);
6149            } catch (Exception e) {
6150                // If the app died trying to launch the receiver we declare it 'bad'
6151                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6152                badApp = true;
6153            }
6154        }
6155
6156        // Check whether the next backup agent is in this process...
6157        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6158            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6159                    "New app is backup target, launching agent for " + app);
6160            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6161            try {
6162                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6163                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6164                        mBackupTarget.backupMode);
6165            } catch (Exception e) {
6166                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6167                badApp = true;
6168            }
6169        }
6170
6171        if (badApp) {
6172            app.kill("error during init", true);
6173            handleAppDiedLocked(app, false, true);
6174            return false;
6175        }
6176
6177        if (!didSomething) {
6178            updateOomAdjLocked();
6179        }
6180
6181        return true;
6182    }
6183
6184    @Override
6185    public final void attachApplication(IApplicationThread thread) {
6186        synchronized (this) {
6187            int callingPid = Binder.getCallingPid();
6188            final long origId = Binder.clearCallingIdentity();
6189            attachApplicationLocked(thread, callingPid);
6190            Binder.restoreCallingIdentity(origId);
6191        }
6192    }
6193
6194    @Override
6195    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6196        final long origId = Binder.clearCallingIdentity();
6197        synchronized (this) {
6198            ActivityStack stack = ActivityRecord.getStackLocked(token);
6199            if (stack != null) {
6200                ActivityRecord r =
6201                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6202                if (stopProfiling) {
6203                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6204                        try {
6205                            mProfileFd.close();
6206                        } catch (IOException e) {
6207                        }
6208                        clearProfilerLocked();
6209                    }
6210                }
6211            }
6212        }
6213        Binder.restoreCallingIdentity(origId);
6214    }
6215
6216    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6217        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6218                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6219    }
6220
6221    void enableScreenAfterBoot() {
6222        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6223                SystemClock.uptimeMillis());
6224        mWindowManager.enableScreenAfterBoot();
6225
6226        synchronized (this) {
6227            updateEventDispatchingLocked();
6228        }
6229    }
6230
6231    @Override
6232    public void showBootMessage(final CharSequence msg, final boolean always) {
6233        if (Binder.getCallingUid() != Process.myUid()) {
6234            // These days only the core system can call this, so apps can't get in
6235            // the way of what we show about running them.
6236        }
6237        mWindowManager.showBootMessage(msg, always);
6238    }
6239
6240    @Override
6241    public void keyguardWaitingForActivityDrawn() {
6242        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6243        final long token = Binder.clearCallingIdentity();
6244        try {
6245            synchronized (this) {
6246                if (DEBUG_LOCKSCREEN) logLockScreen("");
6247                mWindowManager.keyguardWaitingForActivityDrawn();
6248                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6249                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6250                    updateSleepIfNeededLocked();
6251                }
6252            }
6253        } finally {
6254            Binder.restoreCallingIdentity(token);
6255        }
6256    }
6257
6258    @Override
6259    public void keyguardGoingAway(boolean disableWindowAnimations,
6260            boolean keyguardGoingToNotificationShade) {
6261        enforceNotIsolatedCaller("keyguardGoingAway");
6262        final long token = Binder.clearCallingIdentity();
6263        try {
6264            synchronized (this) {
6265                if (DEBUG_LOCKSCREEN) logLockScreen("");
6266                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6267                        keyguardGoingToNotificationShade);
6268                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6269                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6270                    updateSleepIfNeededLocked();
6271                }
6272            }
6273        } finally {
6274            Binder.restoreCallingIdentity(token);
6275        }
6276    }
6277
6278    final void finishBooting() {
6279        synchronized (this) {
6280            if (!mBootAnimationComplete) {
6281                mCallFinishBooting = true;
6282                return;
6283            }
6284            mCallFinishBooting = false;
6285        }
6286
6287        ArraySet<String> completedIsas = new ArraySet<String>();
6288        for (String abi : Build.SUPPORTED_ABIS) {
6289            Process.establishZygoteConnectionForAbi(abi);
6290            final String instructionSet = VMRuntime.getInstructionSet(abi);
6291            if (!completedIsas.contains(instructionSet)) {
6292                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6293                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6294                }
6295                completedIsas.add(instructionSet);
6296            }
6297        }
6298
6299        IntentFilter pkgFilter = new IntentFilter();
6300        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6301        pkgFilter.addDataScheme("package");
6302        mContext.registerReceiver(new BroadcastReceiver() {
6303            @Override
6304            public void onReceive(Context context, Intent intent) {
6305                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6306                if (pkgs != null) {
6307                    for (String pkg : pkgs) {
6308                        synchronized (ActivityManagerService.this) {
6309                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6310                                    0, "query restart")) {
6311                                setResultCode(Activity.RESULT_OK);
6312                                return;
6313                            }
6314                        }
6315                    }
6316                }
6317            }
6318        }, pkgFilter);
6319
6320        IntentFilter dumpheapFilter = new IntentFilter();
6321        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6322        mContext.registerReceiver(new BroadcastReceiver() {
6323            @Override
6324            public void onReceive(Context context, Intent intent) {
6325                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6326                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6327                } else {
6328                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6329                }
6330            }
6331        }, dumpheapFilter);
6332
6333        // Let system services know.
6334        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6335
6336        synchronized (this) {
6337            // Ensure that any processes we had put on hold are now started
6338            // up.
6339            final int NP = mProcessesOnHold.size();
6340            if (NP > 0) {
6341                ArrayList<ProcessRecord> procs =
6342                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6343                for (int ip=0; ip<NP; ip++) {
6344                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6345                            + procs.get(ip));
6346                    startProcessLocked(procs.get(ip), "on-hold", null);
6347                }
6348            }
6349
6350            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6351                // Start looking for apps that are abusing wake locks.
6352                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6353                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6354                // Tell anyone interested that we are done booting!
6355                SystemProperties.set("sys.boot_completed", "1");
6356
6357                // And trigger dev.bootcomplete if we are not showing encryption progress
6358                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6359                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6360                    SystemProperties.set("dev.bootcomplete", "1");
6361                }
6362                for (int i=0; i<mStartedUsers.size(); i++) {
6363                    UserState uss = mStartedUsers.valueAt(i);
6364                    if (uss.mState == UserState.STATE_BOOTING) {
6365                        uss.mState = UserState.STATE_RUNNING;
6366                        final int userId = mStartedUsers.keyAt(i);
6367                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6368                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6369                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6370                        broadcastIntentLocked(null, null, intent, null,
6371                                new IIntentReceiver.Stub() {
6372                                    @Override
6373                                    public void performReceive(Intent intent, int resultCode,
6374                                            String data, Bundle extras, boolean ordered,
6375                                            boolean sticky, int sendingUser) {
6376                                        synchronized (ActivityManagerService.this) {
6377                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6378                                                    true, false);
6379                                        }
6380                                    }
6381                                },
6382                                0, null, null,
6383                                new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
6384                                AppOpsManager.OP_NONE, null, true, false,
6385                                MY_PID, Process.SYSTEM_UID, userId);
6386                    }
6387                }
6388                scheduleStartProfilesLocked();
6389            }
6390        }
6391    }
6392
6393    @Override
6394    public void bootAnimationComplete() {
6395        final boolean callFinishBooting;
6396        synchronized (this) {
6397            callFinishBooting = mCallFinishBooting;
6398            mBootAnimationComplete = true;
6399        }
6400        if (callFinishBooting) {
6401            finishBooting();
6402        }
6403    }
6404
6405    final void ensureBootCompleted() {
6406        boolean booting;
6407        boolean enableScreen;
6408        synchronized (this) {
6409            booting = mBooting;
6410            mBooting = false;
6411            enableScreen = !mBooted;
6412            mBooted = true;
6413        }
6414
6415        if (booting) {
6416            finishBooting();
6417        }
6418
6419        if (enableScreen) {
6420            enableScreenAfterBoot();
6421        }
6422    }
6423
6424    @Override
6425    public final void activityResumed(IBinder token) {
6426        final long origId = Binder.clearCallingIdentity();
6427        synchronized(this) {
6428            ActivityStack stack = ActivityRecord.getStackLocked(token);
6429            if (stack != null) {
6430                ActivityRecord.activityResumedLocked(token);
6431            }
6432        }
6433        Binder.restoreCallingIdentity(origId);
6434    }
6435
6436    @Override
6437    public final void activityPaused(IBinder token) {
6438        final long origId = Binder.clearCallingIdentity();
6439        synchronized(this) {
6440            ActivityStack stack = ActivityRecord.getStackLocked(token);
6441            if (stack != null) {
6442                stack.activityPausedLocked(token, false);
6443            }
6444        }
6445        Binder.restoreCallingIdentity(origId);
6446    }
6447
6448    @Override
6449    public final void activityStopped(IBinder token, Bundle icicle,
6450            PersistableBundle persistentState, CharSequence description) {
6451        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6452
6453        // Refuse possible leaked file descriptors
6454        if (icicle != null && icicle.hasFileDescriptors()) {
6455            throw new IllegalArgumentException("File descriptors passed in Bundle");
6456        }
6457
6458        final long origId = Binder.clearCallingIdentity();
6459
6460        synchronized (this) {
6461            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6462            if (r != null) {
6463                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6464            }
6465        }
6466
6467        trimApplications();
6468
6469        Binder.restoreCallingIdentity(origId);
6470    }
6471
6472    @Override
6473    public final void activityDestroyed(IBinder token) {
6474        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6475        synchronized (this) {
6476            ActivityStack stack = ActivityRecord.getStackLocked(token);
6477            if (stack != null) {
6478                stack.activityDestroyedLocked(token, "activityDestroyed");
6479            }
6480        }
6481    }
6482
6483    @Override
6484    public final void backgroundResourcesReleased(IBinder token) {
6485        final long origId = Binder.clearCallingIdentity();
6486        try {
6487            synchronized (this) {
6488                ActivityStack stack = ActivityRecord.getStackLocked(token);
6489                if (stack != null) {
6490                    stack.backgroundResourcesReleased();
6491                }
6492            }
6493        } finally {
6494            Binder.restoreCallingIdentity(origId);
6495        }
6496    }
6497
6498    @Override
6499    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6500        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6501    }
6502
6503    @Override
6504    public final void notifyEnterAnimationComplete(IBinder token) {
6505        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6506    }
6507
6508    @Override
6509    public String getCallingPackage(IBinder token) {
6510        synchronized (this) {
6511            ActivityRecord r = getCallingRecordLocked(token);
6512            return r != null ? r.info.packageName : null;
6513        }
6514    }
6515
6516    @Override
6517    public ComponentName getCallingActivity(IBinder token) {
6518        synchronized (this) {
6519            ActivityRecord r = getCallingRecordLocked(token);
6520            return r != null ? r.intent.getComponent() : null;
6521        }
6522    }
6523
6524    private ActivityRecord getCallingRecordLocked(IBinder token) {
6525        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6526        if (r == null) {
6527            return null;
6528        }
6529        return r.resultTo;
6530    }
6531
6532    @Override
6533    public ComponentName getActivityClassForToken(IBinder token) {
6534        synchronized(this) {
6535            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6536            if (r == null) {
6537                return null;
6538            }
6539            return r.intent.getComponent();
6540        }
6541    }
6542
6543    @Override
6544    public String getPackageForToken(IBinder token) {
6545        synchronized(this) {
6546            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6547            if (r == null) {
6548                return null;
6549            }
6550            return r.packageName;
6551        }
6552    }
6553
6554    @Override
6555    public boolean isRootVoiceInteraction(IBinder token) {
6556        synchronized(this) {
6557            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6558            if (r == null) {
6559                return false;
6560            }
6561            return r.rootVoiceInteraction;
6562        }
6563    }
6564
6565    @Override
6566    public IIntentSender getIntentSender(int type,
6567            String packageName, IBinder token, String resultWho,
6568            int requestCode, Intent[] intents, String[] resolvedTypes,
6569            int flags, Bundle options, int userId) {
6570        enforceNotIsolatedCaller("getIntentSender");
6571        // Refuse possible leaked file descriptors
6572        if (intents != null) {
6573            if (intents.length < 1) {
6574                throw new IllegalArgumentException("Intents array length must be >= 1");
6575            }
6576            for (int i=0; i<intents.length; i++) {
6577                Intent intent = intents[i];
6578                if (intent != null) {
6579                    if (intent.hasFileDescriptors()) {
6580                        throw new IllegalArgumentException("File descriptors passed in Intent");
6581                    }
6582                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6583                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6584                        throw new IllegalArgumentException(
6585                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6586                    }
6587                    intents[i] = new Intent(intent);
6588                }
6589            }
6590            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6591                throw new IllegalArgumentException(
6592                        "Intent array length does not match resolvedTypes length");
6593            }
6594        }
6595        if (options != null) {
6596            if (options.hasFileDescriptors()) {
6597                throw new IllegalArgumentException("File descriptors passed in options");
6598            }
6599        }
6600
6601        synchronized(this) {
6602            int callingUid = Binder.getCallingUid();
6603            int origUserId = userId;
6604            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6605                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6606                    ALLOW_NON_FULL, "getIntentSender", null);
6607            if (origUserId == UserHandle.USER_CURRENT) {
6608                // We don't want to evaluate this until the pending intent is
6609                // actually executed.  However, we do want to always do the
6610                // security checking for it above.
6611                userId = UserHandle.USER_CURRENT;
6612            }
6613            try {
6614                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6615                    int uid = AppGlobals.getPackageManager()
6616                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6617                    if (!UserHandle.isSameApp(callingUid, uid)) {
6618                        String msg = "Permission Denial: getIntentSender() from pid="
6619                            + Binder.getCallingPid()
6620                            + ", uid=" + Binder.getCallingUid()
6621                            + ", (need uid=" + uid + ")"
6622                            + " is not allowed to send as package " + packageName;
6623                        Slog.w(TAG, msg);
6624                        throw new SecurityException(msg);
6625                    }
6626                }
6627
6628                return getIntentSenderLocked(type, packageName, callingUid, userId,
6629                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6630
6631            } catch (RemoteException e) {
6632                throw new SecurityException(e);
6633            }
6634        }
6635    }
6636
6637    IIntentSender getIntentSenderLocked(int type, String packageName,
6638            int callingUid, int userId, IBinder token, String resultWho,
6639            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6640            Bundle options) {
6641        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6642        ActivityRecord activity = null;
6643        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6644            activity = ActivityRecord.isInStackLocked(token);
6645            if (activity == null) {
6646                return null;
6647            }
6648            if (activity.finishing) {
6649                return null;
6650            }
6651        }
6652
6653        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6654        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6655        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6656        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6657                |PendingIntent.FLAG_UPDATE_CURRENT);
6658
6659        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6660                type, packageName, activity, resultWho,
6661                requestCode, intents, resolvedTypes, flags, options, userId);
6662        WeakReference<PendingIntentRecord> ref;
6663        ref = mIntentSenderRecords.get(key);
6664        PendingIntentRecord rec = ref != null ? ref.get() : null;
6665        if (rec != null) {
6666            if (!cancelCurrent) {
6667                if (updateCurrent) {
6668                    if (rec.key.requestIntent != null) {
6669                        rec.key.requestIntent.replaceExtras(intents != null ?
6670                                intents[intents.length - 1] : null);
6671                    }
6672                    if (intents != null) {
6673                        intents[intents.length-1] = rec.key.requestIntent;
6674                        rec.key.allIntents = intents;
6675                        rec.key.allResolvedTypes = resolvedTypes;
6676                    } else {
6677                        rec.key.allIntents = null;
6678                        rec.key.allResolvedTypes = null;
6679                    }
6680                }
6681                return rec;
6682            }
6683            rec.canceled = true;
6684            mIntentSenderRecords.remove(key);
6685        }
6686        if (noCreate) {
6687            return rec;
6688        }
6689        rec = new PendingIntentRecord(this, key, callingUid);
6690        mIntentSenderRecords.put(key, rec.ref);
6691        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6692            if (activity.pendingResults == null) {
6693                activity.pendingResults
6694                        = new HashSet<WeakReference<PendingIntentRecord>>();
6695            }
6696            activity.pendingResults.add(rec.ref);
6697        }
6698        return rec;
6699    }
6700
6701    @Override
6702    public void cancelIntentSender(IIntentSender sender) {
6703        if (!(sender instanceof PendingIntentRecord)) {
6704            return;
6705        }
6706        synchronized(this) {
6707            PendingIntentRecord rec = (PendingIntentRecord)sender;
6708            try {
6709                int uid = AppGlobals.getPackageManager()
6710                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6711                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6712                    String msg = "Permission Denial: cancelIntentSender() from pid="
6713                        + Binder.getCallingPid()
6714                        + ", uid=" + Binder.getCallingUid()
6715                        + " is not allowed to cancel packges "
6716                        + rec.key.packageName;
6717                    Slog.w(TAG, msg);
6718                    throw new SecurityException(msg);
6719                }
6720            } catch (RemoteException e) {
6721                throw new SecurityException(e);
6722            }
6723            cancelIntentSenderLocked(rec, true);
6724        }
6725    }
6726
6727    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6728        rec.canceled = true;
6729        mIntentSenderRecords.remove(rec.key);
6730        if (cleanActivity && rec.key.activity != null) {
6731            rec.key.activity.pendingResults.remove(rec.ref);
6732        }
6733    }
6734
6735    @Override
6736    public String getPackageForIntentSender(IIntentSender pendingResult) {
6737        if (!(pendingResult instanceof PendingIntentRecord)) {
6738            return null;
6739        }
6740        try {
6741            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6742            return res.key.packageName;
6743        } catch (ClassCastException e) {
6744        }
6745        return null;
6746    }
6747
6748    @Override
6749    public int getUidForIntentSender(IIntentSender sender) {
6750        if (sender instanceof PendingIntentRecord) {
6751            try {
6752                PendingIntentRecord res = (PendingIntentRecord)sender;
6753                return res.uid;
6754            } catch (ClassCastException e) {
6755            }
6756        }
6757        return -1;
6758    }
6759
6760    @Override
6761    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6762        if (!(pendingResult instanceof PendingIntentRecord)) {
6763            return false;
6764        }
6765        try {
6766            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6767            if (res.key.allIntents == null) {
6768                return false;
6769            }
6770            for (int i=0; i<res.key.allIntents.length; i++) {
6771                Intent intent = res.key.allIntents[i];
6772                if (intent.getPackage() != null && intent.getComponent() != null) {
6773                    return false;
6774                }
6775            }
6776            return true;
6777        } catch (ClassCastException e) {
6778        }
6779        return false;
6780    }
6781
6782    @Override
6783    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6784        if (!(pendingResult instanceof PendingIntentRecord)) {
6785            return false;
6786        }
6787        try {
6788            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6789            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6790                return true;
6791            }
6792            return false;
6793        } catch (ClassCastException e) {
6794        }
6795        return false;
6796    }
6797
6798    @Override
6799    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6800        if (!(pendingResult instanceof PendingIntentRecord)) {
6801            return null;
6802        }
6803        try {
6804            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6805            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6806        } catch (ClassCastException e) {
6807        }
6808        return null;
6809    }
6810
6811    @Override
6812    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6813        if (!(pendingResult instanceof PendingIntentRecord)) {
6814            return null;
6815        }
6816        try {
6817            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6818            synchronized (this) {
6819                return getTagForIntentSenderLocked(res, prefix);
6820            }
6821        } catch (ClassCastException e) {
6822        }
6823        return null;
6824    }
6825
6826    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6827        final Intent intent = res.key.requestIntent;
6828        if (intent != null) {
6829            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6830                    || res.lastTagPrefix.equals(prefix))) {
6831                return res.lastTag;
6832            }
6833            res.lastTagPrefix = prefix;
6834            final StringBuilder sb = new StringBuilder(128);
6835            if (prefix != null) {
6836                sb.append(prefix);
6837            }
6838            if (intent.getAction() != null) {
6839                sb.append(intent.getAction());
6840            } else if (intent.getComponent() != null) {
6841                intent.getComponent().appendShortString(sb);
6842            } else {
6843                sb.append("?");
6844            }
6845            return res.lastTag = sb.toString();
6846        }
6847        return null;
6848    }
6849
6850    @Override
6851    public void setProcessLimit(int max) {
6852        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6853                "setProcessLimit()");
6854        synchronized (this) {
6855            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6856            mProcessLimitOverride = max;
6857        }
6858        trimApplications();
6859    }
6860
6861    @Override
6862    public int getProcessLimit() {
6863        synchronized (this) {
6864            return mProcessLimitOverride;
6865        }
6866    }
6867
6868    void foregroundTokenDied(ForegroundToken token) {
6869        synchronized (ActivityManagerService.this) {
6870            synchronized (mPidsSelfLocked) {
6871                ForegroundToken cur
6872                    = mForegroundProcesses.get(token.pid);
6873                if (cur != token) {
6874                    return;
6875                }
6876                mForegroundProcesses.remove(token.pid);
6877                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6878                if (pr == null) {
6879                    return;
6880                }
6881                pr.forcingToForeground = null;
6882                updateProcessForegroundLocked(pr, false, false);
6883            }
6884            updateOomAdjLocked();
6885        }
6886    }
6887
6888    @Override
6889    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6890        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6891                "setProcessForeground()");
6892        synchronized(this) {
6893            boolean changed = false;
6894
6895            synchronized (mPidsSelfLocked) {
6896                ProcessRecord pr = mPidsSelfLocked.get(pid);
6897                if (pr == null && isForeground) {
6898                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6899                    return;
6900                }
6901                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6902                if (oldToken != null) {
6903                    oldToken.token.unlinkToDeath(oldToken, 0);
6904                    mForegroundProcesses.remove(pid);
6905                    if (pr != null) {
6906                        pr.forcingToForeground = null;
6907                    }
6908                    changed = true;
6909                }
6910                if (isForeground && token != null) {
6911                    ForegroundToken newToken = new ForegroundToken() {
6912                        @Override
6913                        public void binderDied() {
6914                            foregroundTokenDied(this);
6915                        }
6916                    };
6917                    newToken.pid = pid;
6918                    newToken.token = token;
6919                    try {
6920                        token.linkToDeath(newToken, 0);
6921                        mForegroundProcesses.put(pid, newToken);
6922                        pr.forcingToForeground = token;
6923                        changed = true;
6924                    } catch (RemoteException e) {
6925                        // If the process died while doing this, we will later
6926                        // do the cleanup with the process death link.
6927                    }
6928                }
6929            }
6930
6931            if (changed) {
6932                updateOomAdjLocked();
6933            }
6934        }
6935    }
6936
6937    // =========================================================
6938    // PROCESS INFO
6939    // =========================================================
6940
6941    static class ProcessInfoService extends IProcessInfoService.Stub {
6942        final ActivityManagerService mActivityManagerService;
6943        ProcessInfoService(ActivityManagerService activityManagerService) {
6944            mActivityManagerService = activityManagerService;
6945        }
6946
6947        @Override
6948        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6949            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6950        }
6951    }
6952
6953    /**
6954     * For each PID in the given input array, write the current process state
6955     * for that process into the output array, or -1 to indicate that no
6956     * process with the given PID exists.
6957     */
6958    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6959        if (pids == null) {
6960            throw new NullPointerException("pids");
6961        } else if (states == null) {
6962            throw new NullPointerException("states");
6963        } else if (pids.length != states.length) {
6964            throw new IllegalArgumentException("input and output arrays have different lengths!");
6965        }
6966
6967        synchronized (mPidsSelfLocked) {
6968            for (int i = 0; i < pids.length; i++) {
6969                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6970                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6971                        pr.curProcState;
6972            }
6973        }
6974    }
6975
6976    // =========================================================
6977    // PERMISSIONS
6978    // =========================================================
6979
6980    static class PermissionController extends IPermissionController.Stub {
6981        ActivityManagerService mActivityManagerService;
6982        PermissionController(ActivityManagerService activityManagerService) {
6983            mActivityManagerService = activityManagerService;
6984        }
6985
6986        @Override
6987        public boolean checkPermission(String permission, int pid, int uid) {
6988            return mActivityManagerService.checkPermission(permission, pid,
6989                    uid) == PackageManager.PERMISSION_GRANTED;
6990        }
6991
6992        @Override
6993        public String[] getPackagesForUid(int uid) {
6994            return mActivityManagerService.mContext.getPackageManager()
6995                    .getPackagesForUid(uid);
6996        }
6997
6998        @Override
6999        public boolean isRuntimePermission(String permission) {
7000            try {
7001                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7002                        .getPermissionInfo(permission, 0);
7003                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7004            } catch (NameNotFoundException nnfe) {
7005                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7006            }
7007            return false;
7008        }
7009    }
7010
7011    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7012        @Override
7013        public int checkComponentPermission(String permission, int pid, int uid,
7014                int owningUid, boolean exported) {
7015            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7016                    owningUid, exported);
7017        }
7018
7019        @Override
7020        public Object getAMSLock() {
7021            return ActivityManagerService.this;
7022        }
7023    }
7024
7025    /**
7026     * This can be called with or without the global lock held.
7027     */
7028    int checkComponentPermission(String permission, int pid, int uid,
7029            int owningUid, boolean exported) {
7030        if (pid == MY_PID) {
7031            return PackageManager.PERMISSION_GRANTED;
7032        }
7033        return ActivityManager.checkComponentPermission(permission, uid,
7034                owningUid, exported);
7035    }
7036
7037    /**
7038     * As the only public entry point for permissions checking, this method
7039     * can enforce the semantic that requesting a check on a null global
7040     * permission is automatically denied.  (Internally a null permission
7041     * string is used when calling {@link #checkComponentPermission} in cases
7042     * when only uid-based security is needed.)
7043     *
7044     * This can be called with or without the global lock held.
7045     */
7046    @Override
7047    public int checkPermission(String permission, int pid, int uid) {
7048        if (permission == null) {
7049            return PackageManager.PERMISSION_DENIED;
7050        }
7051        return checkComponentPermission(permission, pid, uid, -1, true);
7052    }
7053
7054    @Override
7055    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7056        if (permission == null) {
7057            return PackageManager.PERMISSION_DENIED;
7058        }
7059
7060        // We might be performing an operation on behalf of an indirect binder
7061        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7062        // client identity accordingly before proceeding.
7063        Identity tlsIdentity = sCallerIdentity.get();
7064        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7065            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7066                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7067            uid = tlsIdentity.uid;
7068            pid = tlsIdentity.pid;
7069        }
7070
7071        return checkComponentPermission(permission, pid, uid, -1, true);
7072    }
7073
7074    /**
7075     * Binder IPC calls go through the public entry point.
7076     * This can be called with or without the global lock held.
7077     */
7078    int checkCallingPermission(String permission) {
7079        return checkPermission(permission,
7080                Binder.getCallingPid(),
7081                UserHandle.getAppId(Binder.getCallingUid()));
7082    }
7083
7084    /**
7085     * This can be called with or without the global lock held.
7086     */
7087    void enforceCallingPermission(String permission, String func) {
7088        if (checkCallingPermission(permission)
7089                == PackageManager.PERMISSION_GRANTED) {
7090            return;
7091        }
7092
7093        String msg = "Permission Denial: " + func + " from pid="
7094                + Binder.getCallingPid()
7095                + ", uid=" + Binder.getCallingUid()
7096                + " requires " + permission;
7097        Slog.w(TAG, msg);
7098        throw new SecurityException(msg);
7099    }
7100
7101    /**
7102     * Determine if UID is holding permissions required to access {@link Uri} in
7103     * the given {@link ProviderInfo}. Final permission checking is always done
7104     * in {@link ContentProvider}.
7105     */
7106    private final boolean checkHoldingPermissionsLocked(
7107            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7108        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7109                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7110        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7111            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7112                    != PERMISSION_GRANTED) {
7113                return false;
7114            }
7115        }
7116        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7117    }
7118
7119    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7120            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7121        if (pi.applicationInfo.uid == uid) {
7122            return true;
7123        } else if (!pi.exported) {
7124            return false;
7125        }
7126
7127        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7128        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7129        try {
7130            // check if target holds top-level <provider> permissions
7131            if (!readMet && pi.readPermission != null && considerUidPermissions
7132                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7133                readMet = true;
7134            }
7135            if (!writeMet && pi.writePermission != null && considerUidPermissions
7136                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7137                writeMet = true;
7138            }
7139
7140            // track if unprotected read/write is allowed; any denied
7141            // <path-permission> below removes this ability
7142            boolean allowDefaultRead = pi.readPermission == null;
7143            boolean allowDefaultWrite = pi.writePermission == null;
7144
7145            // check if target holds any <path-permission> that match uri
7146            final PathPermission[] pps = pi.pathPermissions;
7147            if (pps != null) {
7148                final String path = grantUri.uri.getPath();
7149                int i = pps.length;
7150                while (i > 0 && (!readMet || !writeMet)) {
7151                    i--;
7152                    PathPermission pp = pps[i];
7153                    if (pp.match(path)) {
7154                        if (!readMet) {
7155                            final String pprperm = pp.getReadPermission();
7156                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7157                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7158                                    + ": match=" + pp.match(path)
7159                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7160                            if (pprperm != null) {
7161                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7162                                        == PERMISSION_GRANTED) {
7163                                    readMet = true;
7164                                } else {
7165                                    allowDefaultRead = false;
7166                                }
7167                            }
7168                        }
7169                        if (!writeMet) {
7170                            final String ppwperm = pp.getWritePermission();
7171                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7172                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7173                                    + ": match=" + pp.match(path)
7174                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7175                            if (ppwperm != null) {
7176                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7177                                        == PERMISSION_GRANTED) {
7178                                    writeMet = true;
7179                                } else {
7180                                    allowDefaultWrite = false;
7181                                }
7182                            }
7183                        }
7184                    }
7185                }
7186            }
7187
7188            // grant unprotected <provider> read/write, if not blocked by
7189            // <path-permission> above
7190            if (allowDefaultRead) readMet = true;
7191            if (allowDefaultWrite) writeMet = true;
7192
7193        } catch (RemoteException e) {
7194            return false;
7195        }
7196
7197        return readMet && writeMet;
7198    }
7199
7200    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7201        ProviderInfo pi = null;
7202        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7203        if (cpr != null) {
7204            pi = cpr.info;
7205        } else {
7206            try {
7207                pi = AppGlobals.getPackageManager().resolveContentProvider(
7208                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7209            } catch (RemoteException ex) {
7210            }
7211        }
7212        return pi;
7213    }
7214
7215    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7216        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7217        if (targetUris != null) {
7218            return targetUris.get(grantUri);
7219        }
7220        return null;
7221    }
7222
7223    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7224            String targetPkg, int targetUid, GrantUri grantUri) {
7225        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7226        if (targetUris == null) {
7227            targetUris = Maps.newArrayMap();
7228            mGrantedUriPermissions.put(targetUid, targetUris);
7229        }
7230
7231        UriPermission perm = targetUris.get(grantUri);
7232        if (perm == null) {
7233            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7234            targetUris.put(grantUri, perm);
7235        }
7236
7237        return perm;
7238    }
7239
7240    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7241            final int modeFlags) {
7242        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7243        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7244                : UriPermission.STRENGTH_OWNED;
7245
7246        // Root gets to do everything.
7247        if (uid == 0) {
7248            return true;
7249        }
7250
7251        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7252        if (perms == null) return false;
7253
7254        // First look for exact match
7255        final UriPermission exactPerm = perms.get(grantUri);
7256        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7257            return true;
7258        }
7259
7260        // No exact match, look for prefixes
7261        final int N = perms.size();
7262        for (int i = 0; i < N; i++) {
7263            final UriPermission perm = perms.valueAt(i);
7264            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7265                    && perm.getStrength(modeFlags) >= minStrength) {
7266                return true;
7267            }
7268        }
7269
7270        return false;
7271    }
7272
7273    /**
7274     * @param uri This uri must NOT contain an embedded userId.
7275     * @param userId The userId in which the uri is to be resolved.
7276     */
7277    @Override
7278    public int checkUriPermission(Uri uri, int pid, int uid,
7279            final int modeFlags, int userId, IBinder callerToken) {
7280        enforceNotIsolatedCaller("checkUriPermission");
7281
7282        // Another redirected-binder-call permissions check as in
7283        // {@link checkPermissionWithToken}.
7284        Identity tlsIdentity = sCallerIdentity.get();
7285        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7286            uid = tlsIdentity.uid;
7287            pid = tlsIdentity.pid;
7288        }
7289
7290        // Our own process gets to do everything.
7291        if (pid == MY_PID) {
7292            return PackageManager.PERMISSION_GRANTED;
7293        }
7294        synchronized (this) {
7295            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7296                    ? PackageManager.PERMISSION_GRANTED
7297                    : PackageManager.PERMISSION_DENIED;
7298        }
7299    }
7300
7301    /**
7302     * Check if the targetPkg can be granted permission to access uri by
7303     * the callingUid using the given modeFlags.  Throws a security exception
7304     * if callingUid is not allowed to do this.  Returns the uid of the target
7305     * if the URI permission grant should be performed; returns -1 if it is not
7306     * needed (for example targetPkg already has permission to access the URI).
7307     * If you already know the uid of the target, you can supply it in
7308     * lastTargetUid else set that to -1.
7309     */
7310    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7311            final int modeFlags, int lastTargetUid) {
7312        if (!Intent.isAccessUriMode(modeFlags)) {
7313            return -1;
7314        }
7315
7316        if (targetPkg != null) {
7317            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7318                    "Checking grant " + targetPkg + " permission to " + grantUri);
7319        }
7320
7321        final IPackageManager pm = AppGlobals.getPackageManager();
7322
7323        // If this is not a content: uri, we can't do anything with it.
7324        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7325            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7326                    "Can't grant URI permission for non-content URI: " + grantUri);
7327            return -1;
7328        }
7329
7330        final String authority = grantUri.uri.getAuthority();
7331        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7332        if (pi == null) {
7333            Slog.w(TAG, "No content provider found for permission check: " +
7334                    grantUri.uri.toSafeString());
7335            return -1;
7336        }
7337
7338        int targetUid = lastTargetUid;
7339        if (targetUid < 0 && targetPkg != null) {
7340            try {
7341                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7342                if (targetUid < 0) {
7343                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7344                            "Can't grant URI permission no uid for: " + targetPkg);
7345                    return -1;
7346                }
7347            } catch (RemoteException ex) {
7348                return -1;
7349            }
7350        }
7351
7352        if (targetUid >= 0) {
7353            // First...  does the target actually need this permission?
7354            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7355                // No need to grant the target this permission.
7356                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7357                        "Target " + targetPkg + " already has full permission to " + grantUri);
7358                return -1;
7359            }
7360        } else {
7361            // First...  there is no target package, so can anyone access it?
7362            boolean allowed = pi.exported;
7363            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7364                if (pi.readPermission != null) {
7365                    allowed = false;
7366                }
7367            }
7368            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7369                if (pi.writePermission != null) {
7370                    allowed = false;
7371                }
7372            }
7373            if (allowed) {
7374                return -1;
7375            }
7376        }
7377
7378        /* There is a special cross user grant if:
7379         * - The target is on another user.
7380         * - Apps on the current user can access the uri without any uid permissions.
7381         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7382         * grant uri permissions.
7383         */
7384        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7385                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7386                modeFlags, false /*without considering the uid permissions*/);
7387
7388        // Second...  is the provider allowing granting of URI permissions?
7389        if (!specialCrossUserGrant) {
7390            if (!pi.grantUriPermissions) {
7391                throw new SecurityException("Provider " + pi.packageName
7392                        + "/" + pi.name
7393                        + " does not allow granting of Uri permissions (uri "
7394                        + grantUri + ")");
7395            }
7396            if (pi.uriPermissionPatterns != null) {
7397                final int N = pi.uriPermissionPatterns.length;
7398                boolean allowed = false;
7399                for (int i=0; i<N; i++) {
7400                    if (pi.uriPermissionPatterns[i] != null
7401                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7402                        allowed = true;
7403                        break;
7404                    }
7405                }
7406                if (!allowed) {
7407                    throw new SecurityException("Provider " + pi.packageName
7408                            + "/" + pi.name
7409                            + " does not allow granting of permission to path of Uri "
7410                            + grantUri);
7411                }
7412            }
7413        }
7414
7415        // Third...  does the caller itself have permission to access
7416        // this uri?
7417        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7418            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7419                // Require they hold a strong enough Uri permission
7420                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7421                    throw new SecurityException("Uid " + callingUid
7422                            + " does not have permission to uri " + grantUri);
7423                }
7424            }
7425        }
7426        return targetUid;
7427    }
7428
7429    /**
7430     * @param uri This uri must NOT contain an embedded userId.
7431     * @param userId The userId in which the uri is to be resolved.
7432     */
7433    @Override
7434    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7435            final int modeFlags, int userId) {
7436        enforceNotIsolatedCaller("checkGrantUriPermission");
7437        synchronized(this) {
7438            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7439                    new GrantUri(userId, uri, false), modeFlags, -1);
7440        }
7441    }
7442
7443    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7444            final int modeFlags, UriPermissionOwner owner) {
7445        if (!Intent.isAccessUriMode(modeFlags)) {
7446            return;
7447        }
7448
7449        // So here we are: the caller has the assumed permission
7450        // to the uri, and the target doesn't.  Let's now give this to
7451        // the target.
7452
7453        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7454                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7455
7456        final String authority = grantUri.uri.getAuthority();
7457        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7458        if (pi == null) {
7459            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7460            return;
7461        }
7462
7463        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7464            grantUri.prefix = true;
7465        }
7466        final UriPermission perm = findOrCreateUriPermissionLocked(
7467                pi.packageName, targetPkg, targetUid, grantUri);
7468        perm.grantModes(modeFlags, owner);
7469    }
7470
7471    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7472            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7473        if (targetPkg == null) {
7474            throw new NullPointerException("targetPkg");
7475        }
7476        int targetUid;
7477        final IPackageManager pm = AppGlobals.getPackageManager();
7478        try {
7479            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7480        } catch (RemoteException ex) {
7481            return;
7482        }
7483
7484        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7485                targetUid);
7486        if (targetUid < 0) {
7487            return;
7488        }
7489
7490        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7491                owner);
7492    }
7493
7494    static class NeededUriGrants extends ArrayList<GrantUri> {
7495        final String targetPkg;
7496        final int targetUid;
7497        final int flags;
7498
7499        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7500            this.targetPkg = targetPkg;
7501            this.targetUid = targetUid;
7502            this.flags = flags;
7503        }
7504    }
7505
7506    /**
7507     * Like checkGrantUriPermissionLocked, but takes an Intent.
7508     */
7509    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7510            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7511        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7512                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7513                + " clip=" + (intent != null ? intent.getClipData() : null)
7514                + " from " + intent + "; flags=0x"
7515                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7516
7517        if (targetPkg == null) {
7518            throw new NullPointerException("targetPkg");
7519        }
7520
7521        if (intent == null) {
7522            return null;
7523        }
7524        Uri data = intent.getData();
7525        ClipData clip = intent.getClipData();
7526        if (data == null && clip == null) {
7527            return null;
7528        }
7529        // Default userId for uris in the intent (if they don't specify it themselves)
7530        int contentUserHint = intent.getContentUserHint();
7531        if (contentUserHint == UserHandle.USER_CURRENT) {
7532            contentUserHint = UserHandle.getUserId(callingUid);
7533        }
7534        final IPackageManager pm = AppGlobals.getPackageManager();
7535        int targetUid;
7536        if (needed != null) {
7537            targetUid = needed.targetUid;
7538        } else {
7539            try {
7540                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7541            } catch (RemoteException ex) {
7542                return null;
7543            }
7544            if (targetUid < 0) {
7545                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7546                        "Can't grant URI permission no uid for: " + targetPkg
7547                        + " on user " + targetUserId);
7548                return null;
7549            }
7550        }
7551        if (data != null) {
7552            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7553            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7554                    targetUid);
7555            if (targetUid > 0) {
7556                if (needed == null) {
7557                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7558                }
7559                needed.add(grantUri);
7560            }
7561        }
7562        if (clip != null) {
7563            for (int i=0; i<clip.getItemCount(); i++) {
7564                Uri uri = clip.getItemAt(i).getUri();
7565                if (uri != null) {
7566                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7567                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7568                            targetUid);
7569                    if (targetUid > 0) {
7570                        if (needed == null) {
7571                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7572                        }
7573                        needed.add(grantUri);
7574                    }
7575                } else {
7576                    Intent clipIntent = clip.getItemAt(i).getIntent();
7577                    if (clipIntent != null) {
7578                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7579                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7580                        if (newNeeded != null) {
7581                            needed = newNeeded;
7582                        }
7583                    }
7584                }
7585            }
7586        }
7587
7588        return needed;
7589    }
7590
7591    /**
7592     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7593     */
7594    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7595            UriPermissionOwner owner) {
7596        if (needed != null) {
7597            for (int i=0; i<needed.size(); i++) {
7598                GrantUri grantUri = needed.get(i);
7599                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7600                        grantUri, needed.flags, owner);
7601            }
7602        }
7603    }
7604
7605    void grantUriPermissionFromIntentLocked(int callingUid,
7606            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7607        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7608                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7609        if (needed == null) {
7610            return;
7611        }
7612
7613        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7614    }
7615
7616    /**
7617     * @param uri This uri must NOT contain an embedded userId.
7618     * @param userId The userId in which the uri is to be resolved.
7619     */
7620    @Override
7621    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7622            final int modeFlags, int userId) {
7623        enforceNotIsolatedCaller("grantUriPermission");
7624        GrantUri grantUri = new GrantUri(userId, uri, false);
7625        synchronized(this) {
7626            final ProcessRecord r = getRecordForAppLocked(caller);
7627            if (r == null) {
7628                throw new SecurityException("Unable to find app for caller "
7629                        + caller
7630                        + " when granting permission to uri " + grantUri);
7631            }
7632            if (targetPkg == null) {
7633                throw new IllegalArgumentException("null target");
7634            }
7635            if (grantUri == null) {
7636                throw new IllegalArgumentException("null uri");
7637            }
7638
7639            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7640                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7641                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7642                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7643
7644            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7645                    UserHandle.getUserId(r.uid));
7646        }
7647    }
7648
7649    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7650        if (perm.modeFlags == 0) {
7651            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7652                    perm.targetUid);
7653            if (perms != null) {
7654                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7655                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7656
7657                perms.remove(perm.uri);
7658                if (perms.isEmpty()) {
7659                    mGrantedUriPermissions.remove(perm.targetUid);
7660                }
7661            }
7662        }
7663    }
7664
7665    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7666        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7667                "Revoking all granted permissions to " + grantUri);
7668
7669        final IPackageManager pm = AppGlobals.getPackageManager();
7670        final String authority = grantUri.uri.getAuthority();
7671        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7672        if (pi == null) {
7673            Slog.w(TAG, "No content provider found for permission revoke: "
7674                    + grantUri.toSafeString());
7675            return;
7676        }
7677
7678        // Does the caller have this permission on the URI?
7679        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7680            // If they don't have direct access to the URI, then revoke any
7681            // ownerless URI permissions that have been granted to them.
7682            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7683            if (perms != null) {
7684                boolean persistChanged = false;
7685                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7686                    final UriPermission perm = it.next();
7687                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7688                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7689                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7690                                "Revoking non-owned " + perm.targetUid
7691                                + " permission to " + perm.uri);
7692                        persistChanged |= perm.revokeModes(
7693                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7694                        if (perm.modeFlags == 0) {
7695                            it.remove();
7696                        }
7697                    }
7698                }
7699                if (perms.isEmpty()) {
7700                    mGrantedUriPermissions.remove(callingUid);
7701                }
7702                if (persistChanged) {
7703                    schedulePersistUriGrants();
7704                }
7705            }
7706            return;
7707        }
7708
7709        boolean persistChanged = false;
7710
7711        // Go through all of the permissions and remove any that match.
7712        int N = mGrantedUriPermissions.size();
7713        for (int i = 0; i < N; i++) {
7714            final int targetUid = mGrantedUriPermissions.keyAt(i);
7715            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7716
7717            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7718                final UriPermission perm = it.next();
7719                if (perm.uri.sourceUserId == grantUri.sourceUserId
7720                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7721                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7722                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7723                    persistChanged |= perm.revokeModes(
7724                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7725                    if (perm.modeFlags == 0) {
7726                        it.remove();
7727                    }
7728                }
7729            }
7730
7731            if (perms.isEmpty()) {
7732                mGrantedUriPermissions.remove(targetUid);
7733                N--;
7734                i--;
7735            }
7736        }
7737
7738        if (persistChanged) {
7739            schedulePersistUriGrants();
7740        }
7741    }
7742
7743    /**
7744     * @param uri This uri must NOT contain an embedded userId.
7745     * @param userId The userId in which the uri is to be resolved.
7746     */
7747    @Override
7748    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7749            int userId) {
7750        enforceNotIsolatedCaller("revokeUriPermission");
7751        synchronized(this) {
7752            final ProcessRecord r = getRecordForAppLocked(caller);
7753            if (r == null) {
7754                throw new SecurityException("Unable to find app for caller "
7755                        + caller
7756                        + " when revoking permission to uri " + uri);
7757            }
7758            if (uri == null) {
7759                Slog.w(TAG, "revokeUriPermission: null uri");
7760                return;
7761            }
7762
7763            if (!Intent.isAccessUriMode(modeFlags)) {
7764                return;
7765            }
7766
7767            final String authority = uri.getAuthority();
7768            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7769            if (pi == null) {
7770                Slog.w(TAG, "No content provider found for permission revoke: "
7771                        + uri.toSafeString());
7772                return;
7773            }
7774
7775            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7776        }
7777    }
7778
7779    /**
7780     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7781     * given package.
7782     *
7783     * @param packageName Package name to match, or {@code null} to apply to all
7784     *            packages.
7785     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7786     *            to all users.
7787     * @param persistable If persistable grants should be removed.
7788     */
7789    private void removeUriPermissionsForPackageLocked(
7790            String packageName, int userHandle, boolean persistable) {
7791        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7792            throw new IllegalArgumentException("Must narrow by either package or user");
7793        }
7794
7795        boolean persistChanged = false;
7796
7797        int N = mGrantedUriPermissions.size();
7798        for (int i = 0; i < N; i++) {
7799            final int targetUid = mGrantedUriPermissions.keyAt(i);
7800            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7801
7802            // Only inspect grants matching user
7803            if (userHandle == UserHandle.USER_ALL
7804                    || userHandle == UserHandle.getUserId(targetUid)) {
7805                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7806                    final UriPermission perm = it.next();
7807
7808                    // Only inspect grants matching package
7809                    if (packageName == null || perm.sourcePkg.equals(packageName)
7810                            || perm.targetPkg.equals(packageName)) {
7811                        persistChanged |= perm.revokeModes(persistable
7812                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7813
7814                        // Only remove when no modes remain; any persisted grants
7815                        // will keep this alive.
7816                        if (perm.modeFlags == 0) {
7817                            it.remove();
7818                        }
7819                    }
7820                }
7821
7822                if (perms.isEmpty()) {
7823                    mGrantedUriPermissions.remove(targetUid);
7824                    N--;
7825                    i--;
7826                }
7827            }
7828        }
7829
7830        if (persistChanged) {
7831            schedulePersistUriGrants();
7832        }
7833    }
7834
7835    @Override
7836    public IBinder newUriPermissionOwner(String name) {
7837        enforceNotIsolatedCaller("newUriPermissionOwner");
7838        synchronized(this) {
7839            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7840            return owner.getExternalTokenLocked();
7841        }
7842    }
7843
7844    /**
7845     * @param uri This uri must NOT contain an embedded userId.
7846     * @param sourceUserId The userId in which the uri is to be resolved.
7847     * @param targetUserId The userId of the app that receives the grant.
7848     */
7849    @Override
7850    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7851            final int modeFlags, int sourceUserId, int targetUserId) {
7852        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7853                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7854        synchronized(this) {
7855            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7856            if (owner == null) {
7857                throw new IllegalArgumentException("Unknown owner: " + token);
7858            }
7859            if (fromUid != Binder.getCallingUid()) {
7860                if (Binder.getCallingUid() != Process.myUid()) {
7861                    // Only system code can grant URI permissions on behalf
7862                    // of other users.
7863                    throw new SecurityException("nice try");
7864                }
7865            }
7866            if (targetPkg == null) {
7867                throw new IllegalArgumentException("null target");
7868            }
7869            if (uri == null) {
7870                throw new IllegalArgumentException("null uri");
7871            }
7872
7873            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7874                    modeFlags, owner, targetUserId);
7875        }
7876    }
7877
7878    /**
7879     * @param uri This uri must NOT contain an embedded userId.
7880     * @param userId The userId in which the uri is to be resolved.
7881     */
7882    @Override
7883    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7884        synchronized(this) {
7885            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7886            if (owner == null) {
7887                throw new IllegalArgumentException("Unknown owner: " + token);
7888            }
7889
7890            if (uri == null) {
7891                owner.removeUriPermissionsLocked(mode);
7892            } else {
7893                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7894            }
7895        }
7896    }
7897
7898    private void schedulePersistUriGrants() {
7899        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7900            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7901                    10 * DateUtils.SECOND_IN_MILLIS);
7902        }
7903    }
7904
7905    private void writeGrantedUriPermissions() {
7906        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7907
7908        // Snapshot permissions so we can persist without lock
7909        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7910        synchronized (this) {
7911            final int size = mGrantedUriPermissions.size();
7912            for (int i = 0; i < size; i++) {
7913                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7914                for (UriPermission perm : perms.values()) {
7915                    if (perm.persistedModeFlags != 0) {
7916                        persist.add(perm.snapshot());
7917                    }
7918                }
7919            }
7920        }
7921
7922        FileOutputStream fos = null;
7923        try {
7924            fos = mGrantFile.startWrite();
7925
7926            XmlSerializer out = new FastXmlSerializer();
7927            out.setOutput(fos, StandardCharsets.UTF_8.name());
7928            out.startDocument(null, true);
7929            out.startTag(null, TAG_URI_GRANTS);
7930            for (UriPermission.Snapshot perm : persist) {
7931                out.startTag(null, TAG_URI_GRANT);
7932                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7933                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7934                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7935                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7936                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7937                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7938                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7939                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7940                out.endTag(null, TAG_URI_GRANT);
7941            }
7942            out.endTag(null, TAG_URI_GRANTS);
7943            out.endDocument();
7944
7945            mGrantFile.finishWrite(fos);
7946        } catch (IOException e) {
7947            if (fos != null) {
7948                mGrantFile.failWrite(fos);
7949            }
7950        }
7951    }
7952
7953    private void readGrantedUriPermissionsLocked() {
7954        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7955
7956        final long now = System.currentTimeMillis();
7957
7958        FileInputStream fis = null;
7959        try {
7960            fis = mGrantFile.openRead();
7961            final XmlPullParser in = Xml.newPullParser();
7962            in.setInput(fis, StandardCharsets.UTF_8.name());
7963
7964            int type;
7965            while ((type = in.next()) != END_DOCUMENT) {
7966                final String tag = in.getName();
7967                if (type == START_TAG) {
7968                    if (TAG_URI_GRANT.equals(tag)) {
7969                        final int sourceUserId;
7970                        final int targetUserId;
7971                        final int userHandle = readIntAttribute(in,
7972                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7973                        if (userHandle != UserHandle.USER_NULL) {
7974                            // For backwards compatibility.
7975                            sourceUserId = userHandle;
7976                            targetUserId = userHandle;
7977                        } else {
7978                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7979                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7980                        }
7981                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7982                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7983                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7984                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7985                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7986                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7987
7988                        // Sanity check that provider still belongs to source package
7989                        final ProviderInfo pi = getProviderInfoLocked(
7990                                uri.getAuthority(), sourceUserId);
7991                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7992                            int targetUid = -1;
7993                            try {
7994                                targetUid = AppGlobals.getPackageManager()
7995                                        .getPackageUid(targetPkg, targetUserId);
7996                            } catch (RemoteException e) {
7997                            }
7998                            if (targetUid != -1) {
7999                                final UriPermission perm = findOrCreateUriPermissionLocked(
8000                                        sourcePkg, targetPkg, targetUid,
8001                                        new GrantUri(sourceUserId, uri, prefix));
8002                                perm.initPersistedModes(modeFlags, createdTime);
8003                            }
8004                        } else {
8005                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8006                                    + " but instead found " + pi);
8007                        }
8008                    }
8009                }
8010            }
8011        } catch (FileNotFoundException e) {
8012            // Missing grants is okay
8013        } catch (IOException e) {
8014            Slog.wtf(TAG, "Failed reading Uri grants", e);
8015        } catch (XmlPullParserException e) {
8016            Slog.wtf(TAG, "Failed reading Uri grants", e);
8017        } finally {
8018            IoUtils.closeQuietly(fis);
8019        }
8020    }
8021
8022    /**
8023     * @param uri This uri must NOT contain an embedded userId.
8024     * @param userId The userId in which the uri is to be resolved.
8025     */
8026    @Override
8027    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8028        enforceNotIsolatedCaller("takePersistableUriPermission");
8029
8030        Preconditions.checkFlagsArgument(modeFlags,
8031                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8032
8033        synchronized (this) {
8034            final int callingUid = Binder.getCallingUid();
8035            boolean persistChanged = false;
8036            GrantUri grantUri = new GrantUri(userId, uri, false);
8037
8038            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8039                    new GrantUri(userId, uri, false));
8040            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8041                    new GrantUri(userId, uri, true));
8042
8043            final boolean exactValid = (exactPerm != null)
8044                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8045            final boolean prefixValid = (prefixPerm != null)
8046                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8047
8048            if (!(exactValid || prefixValid)) {
8049                throw new SecurityException("No persistable permission grants found for UID "
8050                        + callingUid + " and Uri " + grantUri.toSafeString());
8051            }
8052
8053            if (exactValid) {
8054                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8055            }
8056            if (prefixValid) {
8057                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8058            }
8059
8060            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8061
8062            if (persistChanged) {
8063                schedulePersistUriGrants();
8064            }
8065        }
8066    }
8067
8068    /**
8069     * @param uri This uri must NOT contain an embedded userId.
8070     * @param userId The userId in which the uri is to be resolved.
8071     */
8072    @Override
8073    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8074        enforceNotIsolatedCaller("releasePersistableUriPermission");
8075
8076        Preconditions.checkFlagsArgument(modeFlags,
8077                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8078
8079        synchronized (this) {
8080            final int callingUid = Binder.getCallingUid();
8081            boolean persistChanged = false;
8082
8083            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8084                    new GrantUri(userId, uri, false));
8085            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8086                    new GrantUri(userId, uri, true));
8087            if (exactPerm == null && prefixPerm == null) {
8088                throw new SecurityException("No permission grants found for UID " + callingUid
8089                        + " and Uri " + uri.toSafeString());
8090            }
8091
8092            if (exactPerm != null) {
8093                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8094                removeUriPermissionIfNeededLocked(exactPerm);
8095            }
8096            if (prefixPerm != null) {
8097                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8098                removeUriPermissionIfNeededLocked(prefixPerm);
8099            }
8100
8101            if (persistChanged) {
8102                schedulePersistUriGrants();
8103            }
8104        }
8105    }
8106
8107    /**
8108     * Prune any older {@link UriPermission} for the given UID until outstanding
8109     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8110     *
8111     * @return if any mutations occured that require persisting.
8112     */
8113    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8114        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8115        if (perms == null) return false;
8116        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8117
8118        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8119        for (UriPermission perm : perms.values()) {
8120            if (perm.persistedModeFlags != 0) {
8121                persisted.add(perm);
8122            }
8123        }
8124
8125        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8126        if (trimCount <= 0) return false;
8127
8128        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8129        for (int i = 0; i < trimCount; i++) {
8130            final UriPermission perm = persisted.get(i);
8131
8132            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8133                    "Trimming grant created at " + perm.persistedCreateTime);
8134
8135            perm.releasePersistableModes(~0);
8136            removeUriPermissionIfNeededLocked(perm);
8137        }
8138
8139        return true;
8140    }
8141
8142    @Override
8143    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8144            String packageName, boolean incoming) {
8145        enforceNotIsolatedCaller("getPersistedUriPermissions");
8146        Preconditions.checkNotNull(packageName, "packageName");
8147
8148        final int callingUid = Binder.getCallingUid();
8149        final IPackageManager pm = AppGlobals.getPackageManager();
8150        try {
8151            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8152            if (packageUid != callingUid) {
8153                throw new SecurityException(
8154                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8155            }
8156        } catch (RemoteException e) {
8157            throw new SecurityException("Failed to verify package name ownership");
8158        }
8159
8160        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8161        synchronized (this) {
8162            if (incoming) {
8163                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8164                        callingUid);
8165                if (perms == null) {
8166                    Slog.w(TAG, "No permission grants found for " + packageName);
8167                } else {
8168                    for (UriPermission perm : perms.values()) {
8169                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8170                            result.add(perm.buildPersistedPublicApiObject());
8171                        }
8172                    }
8173                }
8174            } else {
8175                final int size = mGrantedUriPermissions.size();
8176                for (int i = 0; i < size; i++) {
8177                    final ArrayMap<GrantUri, UriPermission> perms =
8178                            mGrantedUriPermissions.valueAt(i);
8179                    for (UriPermission perm : perms.values()) {
8180                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8181                            result.add(perm.buildPersistedPublicApiObject());
8182                        }
8183                    }
8184                }
8185            }
8186        }
8187        return new ParceledListSlice<android.content.UriPermission>(result);
8188    }
8189
8190    @Override
8191    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8192        synchronized (this) {
8193            ProcessRecord app =
8194                who != null ? getRecordForAppLocked(who) : null;
8195            if (app == null) return;
8196
8197            Message msg = Message.obtain();
8198            msg.what = WAIT_FOR_DEBUGGER_MSG;
8199            msg.obj = app;
8200            msg.arg1 = waiting ? 1 : 0;
8201            mUiHandler.sendMessage(msg);
8202        }
8203    }
8204
8205    @Override
8206    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8207        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8208        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8209        outInfo.availMem = Process.getFreeMemory();
8210        outInfo.totalMem = Process.getTotalMemory();
8211        outInfo.threshold = homeAppMem;
8212        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8213        outInfo.hiddenAppThreshold = cachedAppMem;
8214        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8215                ProcessList.SERVICE_ADJ);
8216        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8217                ProcessList.VISIBLE_APP_ADJ);
8218        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8219                ProcessList.FOREGROUND_APP_ADJ);
8220    }
8221
8222    // =========================================================
8223    // TASK MANAGEMENT
8224    // =========================================================
8225
8226    @Override
8227    public List<IAppTask> getAppTasks(String callingPackage) {
8228        int callingUid = Binder.getCallingUid();
8229        long ident = Binder.clearCallingIdentity();
8230
8231        synchronized(this) {
8232            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8233            try {
8234                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8235
8236                final int N = mRecentTasks.size();
8237                for (int i = 0; i < N; i++) {
8238                    TaskRecord tr = mRecentTasks.get(i);
8239                    // Skip tasks that do not match the caller.  We don't need to verify
8240                    // callingPackage, because we are also limiting to callingUid and know
8241                    // that will limit to the correct security sandbox.
8242                    if (tr.effectiveUid != callingUid) {
8243                        continue;
8244                    }
8245                    Intent intent = tr.getBaseIntent();
8246                    if (intent == null ||
8247                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8248                        continue;
8249                    }
8250                    ActivityManager.RecentTaskInfo taskInfo =
8251                            createRecentTaskInfoFromTaskRecord(tr);
8252                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8253                    list.add(taskImpl);
8254                }
8255            } finally {
8256                Binder.restoreCallingIdentity(ident);
8257            }
8258            return list;
8259        }
8260    }
8261
8262    @Override
8263    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8264        final int callingUid = Binder.getCallingUid();
8265        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8266
8267        synchronized(this) {
8268            if (DEBUG_ALL) Slog.v(
8269                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8270
8271            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8272                    callingUid);
8273
8274            // TODO: Improve with MRU list from all ActivityStacks.
8275            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8276        }
8277
8278        return list;
8279    }
8280
8281    /**
8282     * Creates a new RecentTaskInfo from a TaskRecord.
8283     */
8284    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8285        // Update the task description to reflect any changes in the task stack
8286        tr.updateTaskDescription();
8287
8288        // Compose the recent task info
8289        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8290        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8291        rti.persistentId = tr.taskId;
8292        rti.baseIntent = new Intent(tr.getBaseIntent());
8293        rti.origActivity = tr.origActivity;
8294        rti.description = tr.lastDescription;
8295        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8296        rti.userId = tr.userId;
8297        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8298        rti.firstActiveTime = tr.firstActiveTime;
8299        rti.lastActiveTime = tr.lastActiveTime;
8300        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8301        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8302        rti.numActivities = 0;
8303
8304        ActivityRecord base = null;
8305        ActivityRecord top = null;
8306        ActivityRecord tmp;
8307
8308        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8309            tmp = tr.mActivities.get(i);
8310            if (tmp.finishing) {
8311                continue;
8312            }
8313            base = tmp;
8314            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8315                top = base;
8316            }
8317            rti.numActivities++;
8318        }
8319
8320        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8321        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8322
8323        return rti;
8324    }
8325
8326    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8327        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8328                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8329        if (!allowed) {
8330            if (checkPermission(android.Manifest.permission.GET_TASKS,
8331                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8332                // Temporary compatibility: some existing apps on the system image may
8333                // still be requesting the old permission and not switched to the new
8334                // one; if so, we'll still allow them full access.  This means we need
8335                // to see if they are holding the old permission and are a system app.
8336                try {
8337                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8338                        allowed = true;
8339                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8340                                + " is using old GET_TASKS but privileged; allowing");
8341                    }
8342                } catch (RemoteException e) {
8343                }
8344            }
8345        }
8346        if (!allowed) {
8347            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8348                    + " does not hold REAL_GET_TASKS; limiting output");
8349        }
8350        return allowed;
8351    }
8352
8353    @Override
8354    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8355        final int callingUid = Binder.getCallingUid();
8356        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8357                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8358
8359        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8360        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8361        synchronized (this) {
8362            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8363                    callingUid);
8364            final boolean detailed = checkCallingPermission(
8365                    android.Manifest.permission.GET_DETAILED_TASKS)
8366                    == PackageManager.PERMISSION_GRANTED;
8367
8368            final int recentsCount = mRecentTasks.size();
8369            ArrayList<ActivityManager.RecentTaskInfo> res =
8370                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8371
8372            final Set<Integer> includedUsers;
8373            if (includeProfiles) {
8374                includedUsers = getProfileIdsLocked(userId);
8375            } else {
8376                includedUsers = new HashSet<>();
8377            }
8378            includedUsers.add(Integer.valueOf(userId));
8379
8380            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8381                TaskRecord tr = mRecentTasks.get(i);
8382                // Only add calling user or related users recent tasks
8383                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8384                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8385                    continue;
8386                }
8387
8388                // Return the entry if desired by the caller.  We always return
8389                // the first entry, because callers always expect this to be the
8390                // foreground app.  We may filter others if the caller has
8391                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8392                // we should exclude the entry.
8393
8394                if (i == 0
8395                        || withExcluded
8396                        || (tr.intent == null)
8397                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8398                                == 0)) {
8399                    if (!allowed) {
8400                        // If the caller doesn't have the GET_TASKS permission, then only
8401                        // allow them to see a small subset of tasks -- their own and home.
8402                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8403                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8404                            continue;
8405                        }
8406                    }
8407                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8408                        if (tr.stack != null && tr.stack.isHomeStack()) {
8409                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8410                                    "Skipping, home stack task: " + tr);
8411                            continue;
8412                        }
8413                    }
8414                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8415                        // Don't include auto remove tasks that are finished or finishing.
8416                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8417                                "Skipping, auto-remove without activity: " + tr);
8418                        continue;
8419                    }
8420                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8421                            && !tr.isAvailable) {
8422                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8423                                "Skipping, unavail real act: " + tr);
8424                        continue;
8425                    }
8426
8427                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8428                    if (!detailed) {
8429                        rti.baseIntent.replaceExtras((Bundle)null);
8430                    }
8431
8432                    res.add(rti);
8433                    maxNum--;
8434                }
8435            }
8436            return res;
8437        }
8438    }
8439
8440    @Override
8441    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8442        synchronized (this) {
8443            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8444                    "getTaskThumbnail()");
8445            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8446            if (tr != null) {
8447                return tr.getTaskThumbnailLocked();
8448            }
8449        }
8450        return null;
8451    }
8452
8453    @Override
8454    public int addAppTask(IBinder activityToken, Intent intent,
8455            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8456        final int callingUid = Binder.getCallingUid();
8457        final long callingIdent = Binder.clearCallingIdentity();
8458
8459        try {
8460            synchronized (this) {
8461                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8462                if (r == null) {
8463                    throw new IllegalArgumentException("Activity does not exist; token="
8464                            + activityToken);
8465                }
8466                ComponentName comp = intent.getComponent();
8467                if (comp == null) {
8468                    throw new IllegalArgumentException("Intent " + intent
8469                            + " must specify explicit component");
8470                }
8471                if (thumbnail.getWidth() != mThumbnailWidth
8472                        || thumbnail.getHeight() != mThumbnailHeight) {
8473                    throw new IllegalArgumentException("Bad thumbnail size: got "
8474                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8475                            + mThumbnailWidth + "x" + mThumbnailHeight);
8476                }
8477                if (intent.getSelector() != null) {
8478                    intent.setSelector(null);
8479                }
8480                if (intent.getSourceBounds() != null) {
8481                    intent.setSourceBounds(null);
8482                }
8483                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8484                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8485                        // The caller has added this as an auto-remove task...  that makes no
8486                        // sense, so turn off auto-remove.
8487                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8488                    }
8489                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8490                    // Must be a new task.
8491                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8492                }
8493                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8494                    mLastAddedTaskActivity = null;
8495                }
8496                ActivityInfo ainfo = mLastAddedTaskActivity;
8497                if (ainfo == null) {
8498                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8499                            comp, 0, UserHandle.getUserId(callingUid));
8500                    if (ainfo.applicationInfo.uid != callingUid) {
8501                        throw new SecurityException(
8502                                "Can't add task for another application: target uid="
8503                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8504                    }
8505                }
8506
8507                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8508                        intent, description);
8509
8510                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8511                if (trimIdx >= 0) {
8512                    // If this would have caused a trim, then we'll abort because that
8513                    // means it would be added at the end of the list but then just removed.
8514                    return INVALID_TASK_ID;
8515                }
8516
8517                final int N = mRecentTasks.size();
8518                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8519                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8520                    tr.removedFromRecents();
8521                }
8522
8523                task.inRecents = true;
8524                mRecentTasks.add(task);
8525                r.task.stack.addTask(task, false, false);
8526
8527                task.setLastThumbnail(thumbnail);
8528                task.freeLastThumbnail();
8529
8530                return task.taskId;
8531            }
8532        } finally {
8533            Binder.restoreCallingIdentity(callingIdent);
8534        }
8535    }
8536
8537    @Override
8538    public Point getAppTaskThumbnailSize() {
8539        synchronized (this) {
8540            return new Point(mThumbnailWidth,  mThumbnailHeight);
8541        }
8542    }
8543
8544    @Override
8545    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8546        synchronized (this) {
8547            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8548            if (r != null) {
8549                r.setTaskDescription(td);
8550                r.task.updateTaskDescription();
8551            }
8552        }
8553    }
8554
8555    @Override
8556    public void setTaskResizeable(int taskId, boolean resizeable) {
8557        synchronized (this) {
8558            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8559            if (task == null) {
8560                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8561                return;
8562            }
8563            if (task.mResizeable != resizeable) {
8564                task.mResizeable = resizeable;
8565                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8566                mStackSupervisor.resumeTopActivitiesLocked();
8567            }
8568        }
8569    }
8570
8571    @Override
8572    public void resizeTask(int taskId, Rect bounds) {
8573        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8574                "resizeTask()");
8575        long ident = Binder.clearCallingIdentity();
8576        try {
8577            synchronized (this) {
8578                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8579                if (task == null) {
8580                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8581                    return;
8582                }
8583                mStackSupervisor.resizeTaskLocked(task, bounds);
8584            }
8585        } finally {
8586            Binder.restoreCallingIdentity(ident);
8587        }
8588    }
8589
8590    @Override
8591    public Bitmap getTaskDescriptionIcon(String filename) {
8592        if (!FileUtils.isValidExtFilename(filename)
8593                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8594            throw new IllegalArgumentException("Bad filename: " + filename);
8595        }
8596        return mTaskPersister.getTaskDescriptionIcon(filename);
8597    }
8598
8599    @Override
8600    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8601            throws RemoteException {
8602        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8603                opts.getCustomInPlaceResId() == 0) {
8604            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8605                    "with valid animation");
8606        }
8607        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8608        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8609                opts.getCustomInPlaceResId());
8610        mWindowManager.executeAppTransition();
8611    }
8612
8613    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8614        mRecentTasks.remove(tr);
8615        tr.removedFromRecents();
8616        ComponentName component = tr.getBaseIntent().getComponent();
8617        if (component == null) {
8618            Slog.w(TAG, "No component for base intent of task: " + tr);
8619            return;
8620        }
8621
8622        // Find any running services associated with this app and stop if needed.
8623        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8624
8625        if (!killProcess) {
8626            return;
8627        }
8628
8629        // Determine if the process(es) for this task should be killed.
8630        final String pkg = component.getPackageName();
8631        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8632        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8633        for (int i = 0; i < pmap.size(); i++) {
8634
8635            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8636            for (int j = 0; j < uids.size(); j++) {
8637                ProcessRecord proc = uids.valueAt(j);
8638                if (proc.userId != tr.userId) {
8639                    // Don't kill process for a different user.
8640                    continue;
8641                }
8642                if (proc == mHomeProcess) {
8643                    // Don't kill the home process along with tasks from the same package.
8644                    continue;
8645                }
8646                if (!proc.pkgList.containsKey(pkg)) {
8647                    // Don't kill process that is not associated with this task.
8648                    continue;
8649                }
8650
8651                for (int k = 0; k < proc.activities.size(); k++) {
8652                    TaskRecord otherTask = proc.activities.get(k).task;
8653                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8654                        // Don't kill process(es) that has an activity in a different task that is
8655                        // also in recents.
8656                        return;
8657                    }
8658                }
8659
8660                if (proc.foregroundServices) {
8661                    // Don't kill process(es) with foreground service.
8662                    return;
8663                }
8664
8665                // Add process to kill list.
8666                procsToKill.add(proc);
8667            }
8668        }
8669
8670        // Kill the running processes.
8671        for (int i = 0; i < procsToKill.size(); i++) {
8672            ProcessRecord pr = procsToKill.get(i);
8673            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8674                    && pr.curReceiver == null) {
8675                pr.kill("remove task", true);
8676            } else {
8677                // We delay killing processes that are not in the background or running a receiver.
8678                pr.waitingToKill = "remove task";
8679            }
8680        }
8681    }
8682
8683    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8684        // Remove all tasks with activities in the specified package from the list of recent tasks
8685        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8686            TaskRecord tr = mRecentTasks.get(i);
8687            if (tr.userId != userId) continue;
8688
8689            ComponentName cn = tr.intent.getComponent();
8690            if (cn != null && cn.getPackageName().equals(packageName)) {
8691                // If the package name matches, remove the task.
8692                removeTaskByIdLocked(tr.taskId, true);
8693            }
8694        }
8695    }
8696
8697    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8698            int userId) {
8699
8700        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8701            TaskRecord tr = mRecentTasks.get(i);
8702            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8703                continue;
8704            }
8705
8706            ComponentName cn = tr.intent.getComponent();
8707            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8708                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8709            if (sameComponent) {
8710                removeTaskByIdLocked(tr.taskId, false);
8711            }
8712        }
8713    }
8714
8715    /**
8716     * Removes the task with the specified task id.
8717     *
8718     * @param taskId Identifier of the task to be removed.
8719     * @param killProcess Kill any process associated with the task if possible.
8720     * @return Returns true if the given task was found and removed.
8721     */
8722    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8723        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8724        if (tr != null) {
8725            tr.removeTaskActivitiesLocked();
8726            cleanUpRemovedTaskLocked(tr, killProcess);
8727            if (tr.isPersistable) {
8728                notifyTaskPersisterLocked(null, true);
8729            }
8730            return true;
8731        }
8732        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8733        return false;
8734    }
8735
8736    @Override
8737    public boolean removeTask(int taskId) {
8738        synchronized (this) {
8739            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8740                    "removeTask()");
8741            long ident = Binder.clearCallingIdentity();
8742            try {
8743                return removeTaskByIdLocked(taskId, true);
8744            } finally {
8745                Binder.restoreCallingIdentity(ident);
8746            }
8747        }
8748    }
8749
8750    /**
8751     * TODO: Add mController hook
8752     */
8753    @Override
8754    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8755        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8756
8757        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8758        synchronized(this) {
8759            moveTaskToFrontLocked(taskId, flags, options);
8760        }
8761    }
8762
8763    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8764        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8765                Binder.getCallingUid(), -1, -1, "Task to front")) {
8766            ActivityOptions.abort(options);
8767            return;
8768        }
8769        final long origId = Binder.clearCallingIdentity();
8770        try {
8771            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8772            if (task == null) {
8773                Slog.d(TAG, "Could not find task for id: "+ taskId);
8774                return;
8775            }
8776            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8777                mStackSupervisor.showLockTaskToast();
8778                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8779                return;
8780            }
8781            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8782            if (prev != null && prev.isRecentsActivity()) {
8783                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8784            }
8785            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8786        } finally {
8787            Binder.restoreCallingIdentity(origId);
8788        }
8789        ActivityOptions.abort(options);
8790    }
8791
8792    /**
8793     * Moves an activity, and all of the other activities within the same task, to the bottom
8794     * of the history stack.  The activity's order within the task is unchanged.
8795     *
8796     * @param token A reference to the activity we wish to move
8797     * @param nonRoot If false then this only works if the activity is the root
8798     *                of a task; if true it will work for any activity in a task.
8799     * @return Returns true if the move completed, false if not.
8800     */
8801    @Override
8802    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8803        enforceNotIsolatedCaller("moveActivityTaskToBack");
8804        synchronized(this) {
8805            final long origId = Binder.clearCallingIdentity();
8806            try {
8807                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8808                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8809                if (task != null) {
8810                    if (mStackSupervisor.isLockedTask(task)) {
8811                        mStackSupervisor.showLockTaskToast();
8812                        return false;
8813                    }
8814                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8815                }
8816            } finally {
8817                Binder.restoreCallingIdentity(origId);
8818            }
8819        }
8820        return false;
8821    }
8822
8823    @Override
8824    public void moveTaskBackwards(int task) {
8825        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8826                "moveTaskBackwards()");
8827
8828        synchronized(this) {
8829            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8830                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8831                return;
8832            }
8833            final long origId = Binder.clearCallingIdentity();
8834            moveTaskBackwardsLocked(task);
8835            Binder.restoreCallingIdentity(origId);
8836        }
8837    }
8838
8839    private final void moveTaskBackwardsLocked(int task) {
8840        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8841    }
8842
8843    @Override
8844    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8845            IActivityContainerCallback callback) throws RemoteException {
8846        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8847                "createActivityContainer()");
8848        synchronized (this) {
8849            if (parentActivityToken == null) {
8850                throw new IllegalArgumentException("parent token must not be null");
8851            }
8852            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8853            if (r == null) {
8854                return null;
8855            }
8856            if (callback == null) {
8857                throw new IllegalArgumentException("callback must not be null");
8858            }
8859            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8860        }
8861    }
8862
8863    @Override
8864    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8865        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8866                "deleteActivityContainer()");
8867        synchronized (this) {
8868            mStackSupervisor.deleteActivityContainer(container);
8869        }
8870    }
8871
8872    @Override
8873    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8874        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8875                "createStackOnDisplay()");
8876        synchronized (this) {
8877            final int stackId = mStackSupervisor.getNextStackId();
8878            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8879            if (stack == null) {
8880                return null;
8881            }
8882            return stack.mActivityContainer;
8883        }
8884    }
8885
8886    @Override
8887    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8888        synchronized (this) {
8889            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8890            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8891                return stack.mActivityContainer.getDisplayId();
8892            }
8893            return Display.DEFAULT_DISPLAY;
8894        }
8895    }
8896
8897    @Override
8898    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8899        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8900                "moveTaskToStack()");
8901        if (stackId == HOME_STACK_ID) {
8902            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8903                    new RuntimeException("here").fillInStackTrace());
8904        }
8905        synchronized (this) {
8906            long ident = Binder.clearCallingIdentity();
8907            try {
8908                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8909                        + " to stackId=" + stackId + " toTop=" + toTop);
8910                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8911            } finally {
8912                Binder.restoreCallingIdentity(ident);
8913            }
8914        }
8915    }
8916
8917    @Override
8918    public void resizeStack(int stackId, Rect bounds) {
8919        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8920                "resizeStack()");
8921        long ident = Binder.clearCallingIdentity();
8922        try {
8923            synchronized (this) {
8924                mStackSupervisor.resizeStackLocked(stackId, bounds);
8925            }
8926        } finally {
8927            Binder.restoreCallingIdentity(ident);
8928        }
8929    }
8930
8931    @Override
8932    public List<StackInfo> getAllStackInfos() {
8933        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8934                "getAllStackInfos()");
8935        long ident = Binder.clearCallingIdentity();
8936        try {
8937            synchronized (this) {
8938                return mStackSupervisor.getAllStackInfosLocked();
8939            }
8940        } finally {
8941            Binder.restoreCallingIdentity(ident);
8942        }
8943    }
8944
8945    @Override
8946    public StackInfo getStackInfo(int stackId) {
8947        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8948                "getStackInfo()");
8949        long ident = Binder.clearCallingIdentity();
8950        try {
8951            synchronized (this) {
8952                return mStackSupervisor.getStackInfoLocked(stackId);
8953            }
8954        } finally {
8955            Binder.restoreCallingIdentity(ident);
8956        }
8957    }
8958
8959    @Override
8960    public boolean isInHomeStack(int taskId) {
8961        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8962                "getStackInfo()");
8963        long ident = Binder.clearCallingIdentity();
8964        try {
8965            synchronized (this) {
8966                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8967                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8968            }
8969        } finally {
8970            Binder.restoreCallingIdentity(ident);
8971        }
8972    }
8973
8974    @Override
8975    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8976        synchronized(this) {
8977            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8978        }
8979    }
8980
8981    @Override
8982    public void updateDeviceOwner(String packageName) {
8983        final int callingUid = Binder.getCallingUid();
8984        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8985            throw new SecurityException("updateDeviceOwner called from non-system process");
8986        }
8987        synchronized (this) {
8988            mDeviceOwnerName = packageName;
8989        }
8990    }
8991
8992    @Override
8993    public void updateLockTaskPackages(int userId, String[] packages) {
8994        final int callingUid = Binder.getCallingUid();
8995        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8996            throw new SecurityException("updateLockTaskPackage called from non-system process");
8997        }
8998        synchronized (this) {
8999            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9000                    Arrays.toString(packages));
9001            mLockTaskPackages.put(userId, packages);
9002            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9003        }
9004    }
9005
9006
9007    void startLockTaskModeLocked(TaskRecord task) {
9008        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9009        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9010            return;
9011        }
9012
9013        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9014        // is initiated by system after the pinning request was shown and locked mode is initiated
9015        // by an authorized app directly
9016        final int callingUid = Binder.getCallingUid();
9017        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9018        long ident = Binder.clearCallingIdentity();
9019        try {
9020            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9021            if (!isSystemInitiated) {
9022                task.mLockTaskUid = callingUid;
9023                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9024                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9025                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9026                    StatusBarManagerInternal statusBarManager =
9027                            LocalServices.getService(StatusBarManagerInternal.class);
9028                    if (statusBarManager != null) {
9029                        statusBarManager.showScreenPinningRequest();
9030                    }
9031                    return;
9032                }
9033
9034                if (stack == null || task != stack.topTask()) {
9035                    throw new IllegalArgumentException("Invalid task, not in foreground");
9036                }
9037            }
9038            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9039                    "Locking fully");
9040            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9041                    ActivityManager.LOCK_TASK_MODE_PINNED :
9042                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9043                    "startLockTask", true);
9044        } finally {
9045            Binder.restoreCallingIdentity(ident);
9046        }
9047    }
9048
9049    @Override
9050    public void startLockTaskMode(int taskId) {
9051        synchronized (this) {
9052            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9053            if (task != null) {
9054                startLockTaskModeLocked(task);
9055            }
9056        }
9057    }
9058
9059    @Override
9060    public void startLockTaskMode(IBinder token) {
9061        synchronized (this) {
9062            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9063            if (r == null) {
9064                return;
9065            }
9066            final TaskRecord task = r.task;
9067            if (task != null) {
9068                startLockTaskModeLocked(task);
9069            }
9070        }
9071    }
9072
9073    @Override
9074    public void startLockTaskModeOnCurrent() throws RemoteException {
9075        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9076                "startLockTaskModeOnCurrent");
9077        long ident = Binder.clearCallingIdentity();
9078        try {
9079            synchronized (this) {
9080                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9081                if (r != null) {
9082                    startLockTaskModeLocked(r.task);
9083                }
9084            }
9085        } finally {
9086            Binder.restoreCallingIdentity(ident);
9087        }
9088    }
9089
9090    @Override
9091    public void stopLockTaskMode() {
9092        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9093        if (lockTask == null) {
9094            // Our work here is done.
9095            return;
9096        }
9097
9098        final int callingUid = Binder.getCallingUid();
9099        final int lockTaskUid = lockTask.mLockTaskUid;
9100        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9101        // It is possible lockTaskMode was started by the system process because
9102        // android:lockTaskMode is set to a locking value in the application manifest instead of
9103        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9104        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9105        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9106                callingUid != lockTaskUid
9107                && (lockTaskUid != 0
9108                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9109            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9110                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9111        }
9112
9113        long ident = Binder.clearCallingIdentity();
9114        try {
9115            Log.d(TAG, "stopLockTaskMode");
9116            // Stop lock task
9117            synchronized (this) {
9118                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9119                        "stopLockTask", true);
9120            }
9121        } finally {
9122            Binder.restoreCallingIdentity(ident);
9123        }
9124    }
9125
9126    @Override
9127    public void stopLockTaskModeOnCurrent() throws RemoteException {
9128        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9129                "stopLockTaskModeOnCurrent");
9130        long ident = Binder.clearCallingIdentity();
9131        try {
9132            stopLockTaskMode();
9133        } finally {
9134            Binder.restoreCallingIdentity(ident);
9135        }
9136    }
9137
9138    @Override
9139    public boolean isInLockTaskMode() {
9140        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9141    }
9142
9143    @Override
9144    public int getLockTaskModeState() {
9145        synchronized (this) {
9146            return mStackSupervisor.getLockTaskModeState();
9147        }
9148    }
9149
9150    @Override
9151    public void showLockTaskEscapeMessage(IBinder token) {
9152        synchronized (this) {
9153            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9154            if (r == null) {
9155                return;
9156            }
9157            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9158        }
9159    }
9160
9161    // =========================================================
9162    // CONTENT PROVIDERS
9163    // =========================================================
9164
9165    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9166        List<ProviderInfo> providers = null;
9167        try {
9168            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9169                queryContentProviders(app.processName, app.uid,
9170                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9171            providers = slice != null ? slice.getList() : null;
9172        } catch (RemoteException ex) {
9173        }
9174        if (DEBUG_MU) Slog.v(TAG_MU,
9175                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9176        int userId = app.userId;
9177        if (providers != null) {
9178            int N = providers.size();
9179            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9180            for (int i=0; i<N; i++) {
9181                ProviderInfo cpi =
9182                    (ProviderInfo)providers.get(i);
9183                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9184                        cpi.name, cpi.flags);
9185                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9186                    // This is a singleton provider, but a user besides the
9187                    // default user is asking to initialize a process it runs
9188                    // in...  well, no, it doesn't actually run in this process,
9189                    // it runs in the process of the default user.  Get rid of it.
9190                    providers.remove(i);
9191                    N--;
9192                    i--;
9193                    continue;
9194                }
9195
9196                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9197                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9198                if (cpr == null) {
9199                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9200                    mProviderMap.putProviderByClass(comp, cpr);
9201                }
9202                if (DEBUG_MU) Slog.v(TAG_MU,
9203                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9204                app.pubProviders.put(cpi.name, cpr);
9205                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9206                    // Don't add this if it is a platform component that is marked
9207                    // to run in multiple processes, because this is actually
9208                    // part of the framework so doesn't make sense to track as a
9209                    // separate apk in the process.
9210                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9211                            mProcessStats);
9212                }
9213                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9214            }
9215        }
9216        return providers;
9217    }
9218
9219    /**
9220     * Check if {@link ProcessRecord} has a possible chance at accessing the
9221     * given {@link ProviderInfo}. Final permission checking is always done
9222     * in {@link ContentProvider}.
9223     */
9224    private final String checkContentProviderPermissionLocked(
9225            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9226        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9227        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9228        boolean checkedGrants = false;
9229        if (checkUser) {
9230            // Looking for cross-user grants before enforcing the typical cross-users permissions
9231            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9232            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9233                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9234                    return null;
9235                }
9236                checkedGrants = true;
9237            }
9238            userId = handleIncomingUser(callingPid, callingUid, userId,
9239                    false, ALLOW_NON_FULL,
9240                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9241            if (userId != tmpTargetUserId) {
9242                // When we actually went to determine the final targer user ID, this ended
9243                // up different than our initial check for the authority.  This is because
9244                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9245                // SELF.  So we need to re-check the grants again.
9246                checkedGrants = false;
9247            }
9248        }
9249        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9250                cpi.applicationInfo.uid, cpi.exported)
9251                == PackageManager.PERMISSION_GRANTED) {
9252            return null;
9253        }
9254        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9255                cpi.applicationInfo.uid, cpi.exported)
9256                == PackageManager.PERMISSION_GRANTED) {
9257            return null;
9258        }
9259
9260        PathPermission[] pps = cpi.pathPermissions;
9261        if (pps != null) {
9262            int i = pps.length;
9263            while (i > 0) {
9264                i--;
9265                PathPermission pp = pps[i];
9266                String pprperm = pp.getReadPermission();
9267                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9268                        cpi.applicationInfo.uid, cpi.exported)
9269                        == PackageManager.PERMISSION_GRANTED) {
9270                    return null;
9271                }
9272                String ppwperm = pp.getWritePermission();
9273                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9274                        cpi.applicationInfo.uid, cpi.exported)
9275                        == PackageManager.PERMISSION_GRANTED) {
9276                    return null;
9277                }
9278            }
9279        }
9280        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9281            return null;
9282        }
9283
9284        String msg;
9285        if (!cpi.exported) {
9286            msg = "Permission Denial: opening provider " + cpi.name
9287                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9288                    + ", uid=" + callingUid + ") that is not exported from uid "
9289                    + cpi.applicationInfo.uid;
9290        } else {
9291            msg = "Permission Denial: opening provider " + cpi.name
9292                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9293                    + ", uid=" + callingUid + ") requires "
9294                    + cpi.readPermission + " or " + cpi.writePermission;
9295        }
9296        Slog.w(TAG, msg);
9297        return msg;
9298    }
9299
9300    /**
9301     * Returns if the ContentProvider has granted a uri to callingUid
9302     */
9303    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9304        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9305        if (perms != null) {
9306            for (int i=perms.size()-1; i>=0; i--) {
9307                GrantUri grantUri = perms.keyAt(i);
9308                if (grantUri.sourceUserId == userId || !checkUser) {
9309                    if (matchesProvider(grantUri.uri, cpi)) {
9310                        return true;
9311                    }
9312                }
9313            }
9314        }
9315        return false;
9316    }
9317
9318    /**
9319     * Returns true if the uri authority is one of the authorities specified in the provider.
9320     */
9321    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9322        String uriAuth = uri.getAuthority();
9323        String cpiAuth = cpi.authority;
9324        if (cpiAuth.indexOf(';') == -1) {
9325            return cpiAuth.equals(uriAuth);
9326        }
9327        String[] cpiAuths = cpiAuth.split(";");
9328        int length = cpiAuths.length;
9329        for (int i = 0; i < length; i++) {
9330            if (cpiAuths[i].equals(uriAuth)) return true;
9331        }
9332        return false;
9333    }
9334
9335    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9336            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9337        if (r != null) {
9338            for (int i=0; i<r.conProviders.size(); i++) {
9339                ContentProviderConnection conn = r.conProviders.get(i);
9340                if (conn.provider == cpr) {
9341                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9342                            "Adding provider requested by "
9343                            + r.processName + " from process "
9344                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9345                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9346                    if (stable) {
9347                        conn.stableCount++;
9348                        conn.numStableIncs++;
9349                    } else {
9350                        conn.unstableCount++;
9351                        conn.numUnstableIncs++;
9352                    }
9353                    return conn;
9354                }
9355            }
9356            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9357            if (stable) {
9358                conn.stableCount = 1;
9359                conn.numStableIncs = 1;
9360            } else {
9361                conn.unstableCount = 1;
9362                conn.numUnstableIncs = 1;
9363            }
9364            cpr.connections.add(conn);
9365            r.conProviders.add(conn);
9366            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9367            return conn;
9368        }
9369        cpr.addExternalProcessHandleLocked(externalProcessToken);
9370        return null;
9371    }
9372
9373    boolean decProviderCountLocked(ContentProviderConnection conn,
9374            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9375        if (conn != null) {
9376            cpr = conn.provider;
9377            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9378                    "Removing provider requested by "
9379                    + conn.client.processName + " from process "
9380                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9381                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9382            if (stable) {
9383                conn.stableCount--;
9384            } else {
9385                conn.unstableCount--;
9386            }
9387            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9388                cpr.connections.remove(conn);
9389                conn.client.conProviders.remove(conn);
9390                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9391                return true;
9392            }
9393            return false;
9394        }
9395        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9396        return false;
9397    }
9398
9399    private void checkTime(long startTime, String where) {
9400        long now = SystemClock.elapsedRealtime();
9401        if ((now-startTime) > 1000) {
9402            // If we are taking more than a second, log about it.
9403            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9404        }
9405    }
9406
9407    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9408            String name, IBinder token, boolean stable, int userId) {
9409        ContentProviderRecord cpr;
9410        ContentProviderConnection conn = null;
9411        ProviderInfo cpi = null;
9412
9413        synchronized(this) {
9414            long startTime = SystemClock.elapsedRealtime();
9415
9416            ProcessRecord r = null;
9417            if (caller != null) {
9418                r = getRecordForAppLocked(caller);
9419                if (r == null) {
9420                    throw new SecurityException(
9421                            "Unable to find app for caller " + caller
9422                          + " (pid=" + Binder.getCallingPid()
9423                          + ") when getting content provider " + name);
9424                }
9425            }
9426
9427            boolean checkCrossUser = true;
9428
9429            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9430
9431            // First check if this content provider has been published...
9432            cpr = mProviderMap.getProviderByName(name, userId);
9433            // If that didn't work, check if it exists for user 0 and then
9434            // verify that it's a singleton provider before using it.
9435            if (cpr == null && userId != UserHandle.USER_OWNER) {
9436                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9437                if (cpr != null) {
9438                    cpi = cpr.info;
9439                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9440                            cpi.name, cpi.flags)
9441                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9442                        userId = UserHandle.USER_OWNER;
9443                        checkCrossUser = false;
9444                    } else {
9445                        cpr = null;
9446                        cpi = null;
9447                    }
9448                }
9449            }
9450
9451            boolean providerRunning = cpr != null;
9452            if (providerRunning) {
9453                cpi = cpr.info;
9454                String msg;
9455                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9456                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9457                        != null) {
9458                    throw new SecurityException(msg);
9459                }
9460                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9461
9462                if (r != null && cpr.canRunHere(r)) {
9463                    // This provider has been published or is in the process
9464                    // of being published...  but it is also allowed to run
9465                    // in the caller's process, so don't make a connection
9466                    // and just let the caller instantiate its own instance.
9467                    ContentProviderHolder holder = cpr.newHolder(null);
9468                    // don't give caller the provider object, it needs
9469                    // to make its own.
9470                    holder.provider = null;
9471                    return holder;
9472                }
9473
9474                final long origId = Binder.clearCallingIdentity();
9475
9476                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9477
9478                // In this case the provider instance already exists, so we can
9479                // return it right away.
9480                conn = incProviderCountLocked(r, cpr, token, stable);
9481                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9482                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9483                        // If this is a perceptible app accessing the provider,
9484                        // make sure to count it as being accessed and thus
9485                        // back up on the LRU list.  This is good because
9486                        // content providers are often expensive to start.
9487                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9488                        updateLruProcessLocked(cpr.proc, false, null);
9489                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9490                    }
9491                }
9492
9493                if (cpr.proc != null) {
9494                    if (false) {
9495                        if (cpr.name.flattenToShortString().equals(
9496                                "com.android.providers.calendar/.CalendarProvider2")) {
9497                            Slog.v(TAG, "****************** KILLING "
9498                                + cpr.name.flattenToShortString());
9499                            Process.killProcess(cpr.proc.pid);
9500                        }
9501                    }
9502                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9503                    boolean success = updateOomAdjLocked(cpr.proc);
9504                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9505                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9506                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9507                    // NOTE: there is still a race here where a signal could be
9508                    // pending on the process even though we managed to update its
9509                    // adj level.  Not sure what to do about this, but at least
9510                    // the race is now smaller.
9511                    if (!success) {
9512                        // Uh oh...  it looks like the provider's process
9513                        // has been killed on us.  We need to wait for a new
9514                        // process to be started, and make sure its death
9515                        // doesn't kill our process.
9516                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9517                                + " is crashing; detaching " + r);
9518                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9519                        checkTime(startTime, "getContentProviderImpl: before appDied");
9520                        appDiedLocked(cpr.proc);
9521                        checkTime(startTime, "getContentProviderImpl: after appDied");
9522                        if (!lastRef) {
9523                            // This wasn't the last ref our process had on
9524                            // the provider...  we have now been killed, bail.
9525                            return null;
9526                        }
9527                        providerRunning = false;
9528                        conn = null;
9529                    }
9530                }
9531
9532                Binder.restoreCallingIdentity(origId);
9533            }
9534
9535            boolean singleton;
9536            if (!providerRunning) {
9537                try {
9538                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9539                    cpi = AppGlobals.getPackageManager().
9540                        resolveContentProvider(name,
9541                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9542                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9543                } catch (RemoteException ex) {
9544                }
9545                if (cpi == null) {
9546                    return null;
9547                }
9548                // If the provider is a singleton AND
9549                // (it's a call within the same user || the provider is a
9550                // privileged app)
9551                // Then allow connecting to the singleton provider
9552                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9553                        cpi.name, cpi.flags)
9554                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9555                if (singleton) {
9556                    userId = UserHandle.USER_OWNER;
9557                }
9558                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9559                checkTime(startTime, "getContentProviderImpl: got app info for user");
9560
9561                String msg;
9562                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9563                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9564                        != null) {
9565                    throw new SecurityException(msg);
9566                }
9567                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9568
9569                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9570                        && !cpi.processName.equals("system")) {
9571                    // If this content provider does not run in the system
9572                    // process, and the system is not yet ready to run other
9573                    // processes, then fail fast instead of hanging.
9574                    throw new IllegalArgumentException(
9575                            "Attempt to launch content provider before system ready");
9576                }
9577
9578                // Make sure that the user who owns this provider is running.  If not,
9579                // we don't want to allow it to run.
9580                if (!isUserRunningLocked(userId, false)) {
9581                    Slog.w(TAG, "Unable to launch app "
9582                            + cpi.applicationInfo.packageName + "/"
9583                            + cpi.applicationInfo.uid + " for provider "
9584                            + name + ": user " + userId + " is stopped");
9585                    return null;
9586                }
9587
9588                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9589                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9590                cpr = mProviderMap.getProviderByClass(comp, userId);
9591                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9592                final boolean firstClass = cpr == null;
9593                if (firstClass) {
9594                    final long ident = Binder.clearCallingIdentity();
9595                    try {
9596                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9597                        ApplicationInfo ai =
9598                            AppGlobals.getPackageManager().
9599                                getApplicationInfo(
9600                                        cpi.applicationInfo.packageName,
9601                                        STOCK_PM_FLAGS, userId);
9602                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9603                        if (ai == null) {
9604                            Slog.w(TAG, "No package info for content provider "
9605                                    + cpi.name);
9606                            return null;
9607                        }
9608                        ai = getAppInfoForUser(ai, userId);
9609                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9610                    } catch (RemoteException ex) {
9611                        // pm is in same process, this will never happen.
9612                    } finally {
9613                        Binder.restoreCallingIdentity(ident);
9614                    }
9615                }
9616
9617                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9618
9619                if (r != null && cpr.canRunHere(r)) {
9620                    // If this is a multiprocess provider, then just return its
9621                    // info and allow the caller to instantiate it.  Only do
9622                    // this if the provider is the same user as the caller's
9623                    // process, or can run as root (so can be in any process).
9624                    return cpr.newHolder(null);
9625                }
9626
9627                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9628                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9629                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9630
9631                // This is single process, and our app is now connecting to it.
9632                // See if we are already in the process of launching this
9633                // provider.
9634                final int N = mLaunchingProviders.size();
9635                int i;
9636                for (i = 0; i < N; i++) {
9637                    if (mLaunchingProviders.get(i) == cpr) {
9638                        break;
9639                    }
9640                }
9641
9642                // If the provider is not already being launched, then get it
9643                // started.
9644                if (i >= N) {
9645                    final long origId = Binder.clearCallingIdentity();
9646
9647                    try {
9648                        // Content provider is now in use, its package can't be stopped.
9649                        try {
9650                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9651                            AppGlobals.getPackageManager().setPackageStoppedState(
9652                                    cpr.appInfo.packageName, false, userId);
9653                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9654                        } catch (RemoteException e) {
9655                        } catch (IllegalArgumentException e) {
9656                            Slog.w(TAG, "Failed trying to unstop package "
9657                                    + cpr.appInfo.packageName + ": " + e);
9658                        }
9659
9660                        // Use existing process if already started
9661                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9662                        ProcessRecord proc = getProcessRecordLocked(
9663                                cpi.processName, cpr.appInfo.uid, false);
9664                        if (proc != null && proc.thread != null) {
9665                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9666                                    "Installing in existing process " + proc);
9667                            if (!proc.pubProviders.containsKey(cpi.name)) {
9668                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9669                                proc.pubProviders.put(cpi.name, cpr);
9670                                try {
9671                                    proc.thread.scheduleInstallProvider(cpi);
9672                                } catch (RemoteException e) {
9673                                }
9674                            }
9675                        } else {
9676                            checkTime(startTime, "getContentProviderImpl: before start process");
9677                            proc = startProcessLocked(cpi.processName,
9678                                    cpr.appInfo, false, 0, "content provider",
9679                                    new ComponentName(cpi.applicationInfo.packageName,
9680                                            cpi.name), false, false, false);
9681                            checkTime(startTime, "getContentProviderImpl: after start process");
9682                            if (proc == null) {
9683                                Slog.w(TAG, "Unable to launch app "
9684                                        + cpi.applicationInfo.packageName + "/"
9685                                        + cpi.applicationInfo.uid + " for provider "
9686                                        + name + ": process is bad");
9687                                return null;
9688                            }
9689                        }
9690                        cpr.launchingApp = proc;
9691                        mLaunchingProviders.add(cpr);
9692                    } finally {
9693                        Binder.restoreCallingIdentity(origId);
9694                    }
9695                }
9696
9697                checkTime(startTime, "getContentProviderImpl: updating data structures");
9698
9699                // Make sure the provider is published (the same provider class
9700                // may be published under multiple names).
9701                if (firstClass) {
9702                    mProviderMap.putProviderByClass(comp, cpr);
9703                }
9704
9705                mProviderMap.putProviderByName(name, cpr);
9706                conn = incProviderCountLocked(r, cpr, token, stable);
9707                if (conn != null) {
9708                    conn.waiting = true;
9709                }
9710            }
9711            checkTime(startTime, "getContentProviderImpl: done!");
9712        }
9713
9714        // Wait for the provider to be published...
9715        synchronized (cpr) {
9716            while (cpr.provider == null) {
9717                if (cpr.launchingApp == null) {
9718                    Slog.w(TAG, "Unable to launch app "
9719                            + cpi.applicationInfo.packageName + "/"
9720                            + cpi.applicationInfo.uid + " for provider "
9721                            + name + ": launching app became null");
9722                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9723                            UserHandle.getUserId(cpi.applicationInfo.uid),
9724                            cpi.applicationInfo.packageName,
9725                            cpi.applicationInfo.uid, name);
9726                    return null;
9727                }
9728                try {
9729                    if (DEBUG_MU) Slog.v(TAG_MU,
9730                            "Waiting to start provider " + cpr
9731                            + " launchingApp=" + cpr.launchingApp);
9732                    if (conn != null) {
9733                        conn.waiting = true;
9734                    }
9735                    cpr.wait();
9736                } catch (InterruptedException ex) {
9737                } finally {
9738                    if (conn != null) {
9739                        conn.waiting = false;
9740                    }
9741                }
9742            }
9743        }
9744        return cpr != null ? cpr.newHolder(conn) : null;
9745    }
9746
9747    @Override
9748    public final ContentProviderHolder getContentProvider(
9749            IApplicationThread caller, String name, int userId, boolean stable) {
9750        enforceNotIsolatedCaller("getContentProvider");
9751        if (caller == null) {
9752            String msg = "null IApplicationThread when getting content provider "
9753                    + name;
9754            Slog.w(TAG, msg);
9755            throw new SecurityException(msg);
9756        }
9757        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9758        // with cross-user grant.
9759        return getContentProviderImpl(caller, name, null, stable, userId);
9760    }
9761
9762    public ContentProviderHolder getContentProviderExternal(
9763            String name, int userId, IBinder token) {
9764        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9765            "Do not have permission in call getContentProviderExternal()");
9766        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9767                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9768        return getContentProviderExternalUnchecked(name, token, userId);
9769    }
9770
9771    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9772            IBinder token, int userId) {
9773        return getContentProviderImpl(null, name, token, true, userId);
9774    }
9775
9776    /**
9777     * Drop a content provider from a ProcessRecord's bookkeeping
9778     */
9779    public void removeContentProvider(IBinder connection, boolean stable) {
9780        enforceNotIsolatedCaller("removeContentProvider");
9781        long ident = Binder.clearCallingIdentity();
9782        try {
9783            synchronized (this) {
9784                ContentProviderConnection conn;
9785                try {
9786                    conn = (ContentProviderConnection)connection;
9787                } catch (ClassCastException e) {
9788                    String msg ="removeContentProvider: " + connection
9789                            + " not a ContentProviderConnection";
9790                    Slog.w(TAG, msg);
9791                    throw new IllegalArgumentException(msg);
9792                }
9793                if (conn == null) {
9794                    throw new NullPointerException("connection is null");
9795                }
9796                if (decProviderCountLocked(conn, null, null, stable)) {
9797                    updateOomAdjLocked();
9798                }
9799            }
9800        } finally {
9801            Binder.restoreCallingIdentity(ident);
9802        }
9803    }
9804
9805    public void removeContentProviderExternal(String name, IBinder token) {
9806        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9807            "Do not have permission in call removeContentProviderExternal()");
9808        int userId = UserHandle.getCallingUserId();
9809        long ident = Binder.clearCallingIdentity();
9810        try {
9811            removeContentProviderExternalUnchecked(name, token, userId);
9812        } finally {
9813            Binder.restoreCallingIdentity(ident);
9814        }
9815    }
9816
9817    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9818        synchronized (this) {
9819            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9820            if(cpr == null) {
9821                //remove from mProvidersByClass
9822                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9823                return;
9824            }
9825
9826            //update content provider record entry info
9827            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9828            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9829            if (localCpr.hasExternalProcessHandles()) {
9830                if (localCpr.removeExternalProcessHandleLocked(token)) {
9831                    updateOomAdjLocked();
9832                } else {
9833                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9834                            + " with no external reference for token: "
9835                            + token + ".");
9836                }
9837            } else {
9838                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9839                        + " with no external references.");
9840            }
9841        }
9842    }
9843
9844    public final void publishContentProviders(IApplicationThread caller,
9845            List<ContentProviderHolder> providers) {
9846        if (providers == null) {
9847            return;
9848        }
9849
9850        enforceNotIsolatedCaller("publishContentProviders");
9851        synchronized (this) {
9852            final ProcessRecord r = getRecordForAppLocked(caller);
9853            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9854            if (r == null) {
9855                throw new SecurityException(
9856                        "Unable to find app for caller " + caller
9857                      + " (pid=" + Binder.getCallingPid()
9858                      + ") when publishing content providers");
9859            }
9860
9861            final long origId = Binder.clearCallingIdentity();
9862
9863            final int N = providers.size();
9864            for (int i=0; i<N; i++) {
9865                ContentProviderHolder src = providers.get(i);
9866                if (src == null || src.info == null || src.provider == null) {
9867                    continue;
9868                }
9869                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9870                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9871                if (dst != null) {
9872                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9873                    mProviderMap.putProviderByClass(comp, dst);
9874                    String names[] = dst.info.authority.split(";");
9875                    for (int j = 0; j < names.length; j++) {
9876                        mProviderMap.putProviderByName(names[j], dst);
9877                    }
9878
9879                    int NL = mLaunchingProviders.size();
9880                    int j;
9881                    for (j=0; j<NL; j++) {
9882                        if (mLaunchingProviders.get(j) == dst) {
9883                            mLaunchingProviders.remove(j);
9884                            j--;
9885                            NL--;
9886                        }
9887                    }
9888                    synchronized (dst) {
9889                        dst.provider = src.provider;
9890                        dst.proc = r;
9891                        dst.notifyAll();
9892                    }
9893                    updateOomAdjLocked(r);
9894                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
9895                            src.info.authority);
9896                }
9897            }
9898
9899            Binder.restoreCallingIdentity(origId);
9900        }
9901    }
9902
9903    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9904        ContentProviderConnection conn;
9905        try {
9906            conn = (ContentProviderConnection)connection;
9907        } catch (ClassCastException e) {
9908            String msg ="refContentProvider: " + connection
9909                    + " not a ContentProviderConnection";
9910            Slog.w(TAG, msg);
9911            throw new IllegalArgumentException(msg);
9912        }
9913        if (conn == null) {
9914            throw new NullPointerException("connection is null");
9915        }
9916
9917        synchronized (this) {
9918            if (stable > 0) {
9919                conn.numStableIncs += stable;
9920            }
9921            stable = conn.stableCount + stable;
9922            if (stable < 0) {
9923                throw new IllegalStateException("stableCount < 0: " + stable);
9924            }
9925
9926            if (unstable > 0) {
9927                conn.numUnstableIncs += unstable;
9928            }
9929            unstable = conn.unstableCount + unstable;
9930            if (unstable < 0) {
9931                throw new IllegalStateException("unstableCount < 0: " + unstable);
9932            }
9933
9934            if ((stable+unstable) <= 0) {
9935                throw new IllegalStateException("ref counts can't go to zero here: stable="
9936                        + stable + " unstable=" + unstable);
9937            }
9938            conn.stableCount = stable;
9939            conn.unstableCount = unstable;
9940            return !conn.dead;
9941        }
9942    }
9943
9944    public void unstableProviderDied(IBinder connection) {
9945        ContentProviderConnection conn;
9946        try {
9947            conn = (ContentProviderConnection)connection;
9948        } catch (ClassCastException e) {
9949            String msg ="refContentProvider: " + connection
9950                    + " not a ContentProviderConnection";
9951            Slog.w(TAG, msg);
9952            throw new IllegalArgumentException(msg);
9953        }
9954        if (conn == null) {
9955            throw new NullPointerException("connection is null");
9956        }
9957
9958        // Safely retrieve the content provider associated with the connection.
9959        IContentProvider provider;
9960        synchronized (this) {
9961            provider = conn.provider.provider;
9962        }
9963
9964        if (provider == null) {
9965            // Um, yeah, we're way ahead of you.
9966            return;
9967        }
9968
9969        // Make sure the caller is being honest with us.
9970        if (provider.asBinder().pingBinder()) {
9971            // Er, no, still looks good to us.
9972            synchronized (this) {
9973                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9974                        + " says " + conn + " died, but we don't agree");
9975                return;
9976            }
9977        }
9978
9979        // Well look at that!  It's dead!
9980        synchronized (this) {
9981            if (conn.provider.provider != provider) {
9982                // But something changed...  good enough.
9983                return;
9984            }
9985
9986            ProcessRecord proc = conn.provider.proc;
9987            if (proc == null || proc.thread == null) {
9988                // Seems like the process is already cleaned up.
9989                return;
9990            }
9991
9992            // As far as we're concerned, this is just like receiving a
9993            // death notification...  just a bit prematurely.
9994            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9995                    + ") early provider death");
9996            final long ident = Binder.clearCallingIdentity();
9997            try {
9998                appDiedLocked(proc);
9999            } finally {
10000                Binder.restoreCallingIdentity(ident);
10001            }
10002        }
10003    }
10004
10005    @Override
10006    public void appNotRespondingViaProvider(IBinder connection) {
10007        enforceCallingPermission(
10008                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10009
10010        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10011        if (conn == null) {
10012            Slog.w(TAG, "ContentProviderConnection is null");
10013            return;
10014        }
10015
10016        final ProcessRecord host = conn.provider.proc;
10017        if (host == null) {
10018            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10019            return;
10020        }
10021
10022        final long token = Binder.clearCallingIdentity();
10023        try {
10024            appNotResponding(host, null, null, false, "ContentProvider not responding");
10025        } finally {
10026            Binder.restoreCallingIdentity(token);
10027        }
10028    }
10029
10030    public final void installSystemProviders() {
10031        List<ProviderInfo> providers;
10032        synchronized (this) {
10033            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10034            providers = generateApplicationProvidersLocked(app);
10035            if (providers != null) {
10036                for (int i=providers.size()-1; i>=0; i--) {
10037                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10038                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10039                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10040                                + ": not system .apk");
10041                        providers.remove(i);
10042                    }
10043                }
10044            }
10045        }
10046        if (providers != null) {
10047            mSystemThread.installSystemProviders(providers);
10048        }
10049
10050        mCoreSettingsObserver = new CoreSettingsObserver(this);
10051
10052        //mUsageStatsService.monitorPackages();
10053    }
10054
10055    /**
10056     * Allows apps to retrieve the MIME type of a URI.
10057     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10058     * users, then it does not need permission to access the ContentProvider.
10059     * Either, it needs cross-user uri grants.
10060     *
10061     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10062     *
10063     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10064     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10065     */
10066    public String getProviderMimeType(Uri uri, int userId) {
10067        enforceNotIsolatedCaller("getProviderMimeType");
10068        final String name = uri.getAuthority();
10069        int callingUid = Binder.getCallingUid();
10070        int callingPid = Binder.getCallingPid();
10071        long ident = 0;
10072        boolean clearedIdentity = false;
10073        userId = unsafeConvertIncomingUser(userId);
10074        if (canClearIdentity(callingPid, callingUid, userId)) {
10075            clearedIdentity = true;
10076            ident = Binder.clearCallingIdentity();
10077        }
10078        ContentProviderHolder holder = null;
10079        try {
10080            holder = getContentProviderExternalUnchecked(name, null, userId);
10081            if (holder != null) {
10082                return holder.provider.getType(uri);
10083            }
10084        } catch (RemoteException e) {
10085            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10086            return null;
10087        } finally {
10088            // We need to clear the identity to call removeContentProviderExternalUnchecked
10089            if (!clearedIdentity) {
10090                ident = Binder.clearCallingIdentity();
10091            }
10092            try {
10093                if (holder != null) {
10094                    removeContentProviderExternalUnchecked(name, null, userId);
10095                }
10096            } finally {
10097                Binder.restoreCallingIdentity(ident);
10098            }
10099        }
10100
10101        return null;
10102    }
10103
10104    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10105        if (UserHandle.getUserId(callingUid) == userId) {
10106            return true;
10107        }
10108        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10109                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10110                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10111                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10112                return true;
10113        }
10114        return false;
10115    }
10116
10117    // =========================================================
10118    // GLOBAL MANAGEMENT
10119    // =========================================================
10120
10121    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10122            boolean isolated, int isolatedUid) {
10123        String proc = customProcess != null ? customProcess : info.processName;
10124        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10125        final int userId = UserHandle.getUserId(info.uid);
10126        int uid = info.uid;
10127        if (isolated) {
10128            if (isolatedUid == 0) {
10129                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10130                while (true) {
10131                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10132                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10133                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10134                    }
10135                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10136                    mNextIsolatedProcessUid++;
10137                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10138                        // No process for this uid, use it.
10139                        break;
10140                    }
10141                    stepsLeft--;
10142                    if (stepsLeft <= 0) {
10143                        return null;
10144                    }
10145                }
10146            } else {
10147                // Special case for startIsolatedProcess (internal only), where
10148                // the uid of the isolated process is specified by the caller.
10149                uid = isolatedUid;
10150            }
10151        }
10152        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10153        if (!mBooted && !mBooting
10154                && userId == UserHandle.USER_OWNER
10155                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10156            r.persistent = true;
10157        }
10158        addProcessNameLocked(r);
10159        return r;
10160    }
10161
10162    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10163            String abiOverride) {
10164        ProcessRecord app;
10165        if (!isolated) {
10166            app = getProcessRecordLocked(info.processName, info.uid, true);
10167        } else {
10168            app = null;
10169        }
10170
10171        if (app == null) {
10172            app = newProcessRecordLocked(info, null, isolated, 0);
10173            updateLruProcessLocked(app, false, null);
10174            updateOomAdjLocked();
10175        }
10176
10177        // This package really, really can not be stopped.
10178        try {
10179            AppGlobals.getPackageManager().setPackageStoppedState(
10180                    info.packageName, false, UserHandle.getUserId(app.uid));
10181        } catch (RemoteException e) {
10182        } catch (IllegalArgumentException e) {
10183            Slog.w(TAG, "Failed trying to unstop package "
10184                    + info.packageName + ": " + e);
10185        }
10186
10187        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10188            app.persistent = true;
10189            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10190        }
10191        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10192            mPersistentStartingProcesses.add(app);
10193            startProcessLocked(app, "added application", app.processName, abiOverride,
10194                    null /* entryPoint */, null /* entryPointArgs */);
10195        }
10196
10197        return app;
10198    }
10199
10200    public void unhandledBack() {
10201        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10202                "unhandledBack()");
10203
10204        synchronized(this) {
10205            final long origId = Binder.clearCallingIdentity();
10206            try {
10207                getFocusedStack().unhandledBackLocked();
10208            } finally {
10209                Binder.restoreCallingIdentity(origId);
10210            }
10211        }
10212    }
10213
10214    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10215        enforceNotIsolatedCaller("openContentUri");
10216        final int userId = UserHandle.getCallingUserId();
10217        String name = uri.getAuthority();
10218        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10219        ParcelFileDescriptor pfd = null;
10220        if (cph != null) {
10221            // We record the binder invoker's uid in thread-local storage before
10222            // going to the content provider to open the file.  Later, in the code
10223            // that handles all permissions checks, we look for this uid and use
10224            // that rather than the Activity Manager's own uid.  The effect is that
10225            // we do the check against the caller's permissions even though it looks
10226            // to the content provider like the Activity Manager itself is making
10227            // the request.
10228            Binder token = new Binder();
10229            sCallerIdentity.set(new Identity(
10230                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10231            try {
10232                pfd = cph.provider.openFile(null, uri, "r", null, token);
10233            } catch (FileNotFoundException e) {
10234                // do nothing; pfd will be returned null
10235            } finally {
10236                // Ensure that whatever happens, we clean up the identity state
10237                sCallerIdentity.remove();
10238                // Ensure we're done with the provider.
10239                removeContentProviderExternalUnchecked(name, null, userId);
10240            }
10241        } else {
10242            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10243        }
10244        return pfd;
10245    }
10246
10247    // Actually is sleeping or shutting down or whatever else in the future
10248    // is an inactive state.
10249    public boolean isSleepingOrShuttingDown() {
10250        return isSleeping() || mShuttingDown;
10251    }
10252
10253    public boolean isSleeping() {
10254        return mSleeping;
10255    }
10256
10257    void onWakefulnessChanged(int wakefulness) {
10258        synchronized(this) {
10259            mWakefulness = wakefulness;
10260            updateSleepIfNeededLocked();
10261        }
10262    }
10263
10264    void finishRunningVoiceLocked() {
10265        if (mRunningVoice != null) {
10266            mRunningVoice = null;
10267            mVoiceWakeLock.release();
10268            updateSleepIfNeededLocked();
10269        }
10270    }
10271
10272    void startTimeTrackingFocusedActivityLocked() {
10273        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10274            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10275        }
10276    }
10277
10278    void updateSleepIfNeededLocked() {
10279        if (mSleeping && !shouldSleepLocked()) {
10280            mSleeping = false;
10281            startTimeTrackingFocusedActivityLocked();
10282            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10283            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10284            updateOomAdjLocked();
10285        } else if (!mSleeping && shouldSleepLocked()) {
10286            mSleeping = true;
10287            if (mCurAppTimeTracker != null) {
10288                mCurAppTimeTracker.stop();
10289            }
10290            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10291            mStackSupervisor.goingToSleepLocked();
10292            updateOomAdjLocked();
10293
10294            // Initialize the wake times of all processes.
10295            checkExcessivePowerUsageLocked(false);
10296            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10297            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10298            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10299        }
10300    }
10301
10302    private boolean shouldSleepLocked() {
10303        // Resume applications while running a voice interactor.
10304        if (mRunningVoice != null) {
10305            return false;
10306        }
10307
10308        // TODO: Transform the lock screen state into a sleep token instead.
10309        switch (mWakefulness) {
10310            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10311            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10312            case PowerManagerInternal.WAKEFULNESS_DOZING:
10313                // Pause applications whenever the lock screen is shown or any sleep
10314                // tokens have been acquired.
10315                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10316            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10317            default:
10318                // If we're asleep then pause applications unconditionally.
10319                return true;
10320        }
10321    }
10322
10323    /** Pokes the task persister. */
10324    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10325        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10326            // Never persist the home stack.
10327            return;
10328        }
10329        mTaskPersister.wakeup(task, flush);
10330    }
10331
10332    /** Notifies all listeners when the task stack has changed. */
10333    void notifyTaskStackChangedLocked() {
10334        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10335        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10336        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10337    }
10338
10339    @Override
10340    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10341        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10342    }
10343
10344    @Override
10345    public boolean shutdown(int timeout) {
10346        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10347                != PackageManager.PERMISSION_GRANTED) {
10348            throw new SecurityException("Requires permission "
10349                    + android.Manifest.permission.SHUTDOWN);
10350        }
10351
10352        boolean timedout = false;
10353
10354        synchronized(this) {
10355            mShuttingDown = true;
10356            updateEventDispatchingLocked();
10357            timedout = mStackSupervisor.shutdownLocked(timeout);
10358        }
10359
10360        mAppOpsService.shutdown();
10361        if (mUsageStatsService != null) {
10362            mUsageStatsService.prepareShutdown();
10363        }
10364        mBatteryStatsService.shutdown();
10365        synchronized (this) {
10366            mProcessStats.shutdownLocked();
10367            notifyTaskPersisterLocked(null, true);
10368        }
10369
10370        return timedout;
10371    }
10372
10373    public final void activitySlept(IBinder token) {
10374        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10375
10376        final long origId = Binder.clearCallingIdentity();
10377
10378        synchronized (this) {
10379            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10380            if (r != null) {
10381                mStackSupervisor.activitySleptLocked(r);
10382            }
10383        }
10384
10385        Binder.restoreCallingIdentity(origId);
10386    }
10387
10388    private String lockScreenShownToString() {
10389        switch (mLockScreenShown) {
10390            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10391            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10392            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10393            default: return "Unknown=" + mLockScreenShown;
10394        }
10395    }
10396
10397    void logLockScreen(String msg) {
10398        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10399                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10400                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10401                + " mSleeping=" + mSleeping);
10402    }
10403
10404    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10405        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10406        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10407            boolean wasRunningVoice = mRunningVoice != null;
10408            mRunningVoice = session;
10409            if (!wasRunningVoice) {
10410                mVoiceWakeLock.acquire();
10411                updateSleepIfNeededLocked();
10412            }
10413        }
10414    }
10415
10416    private void updateEventDispatchingLocked() {
10417        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10418    }
10419
10420    public void setLockScreenShown(boolean shown) {
10421        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10422                != PackageManager.PERMISSION_GRANTED) {
10423            throw new SecurityException("Requires permission "
10424                    + android.Manifest.permission.DEVICE_POWER);
10425        }
10426
10427        synchronized(this) {
10428            long ident = Binder.clearCallingIdentity();
10429            try {
10430                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10431                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10432                updateSleepIfNeededLocked();
10433            } finally {
10434                Binder.restoreCallingIdentity(ident);
10435            }
10436        }
10437    }
10438
10439    @Override
10440    public void stopAppSwitches() {
10441        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10442                != PackageManager.PERMISSION_GRANTED) {
10443            throw new SecurityException("Requires permission "
10444                    + android.Manifest.permission.STOP_APP_SWITCHES);
10445        }
10446
10447        synchronized(this) {
10448            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10449                    + APP_SWITCH_DELAY_TIME;
10450            mDidAppSwitch = false;
10451            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10452            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10453            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10454        }
10455    }
10456
10457    public void resumeAppSwitches() {
10458        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10459                != PackageManager.PERMISSION_GRANTED) {
10460            throw new SecurityException("Requires permission "
10461                    + android.Manifest.permission.STOP_APP_SWITCHES);
10462        }
10463
10464        synchronized(this) {
10465            // Note that we don't execute any pending app switches... we will
10466            // let those wait until either the timeout, or the next start
10467            // activity request.
10468            mAppSwitchesAllowedTime = 0;
10469        }
10470    }
10471
10472    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10473            int callingPid, int callingUid, String name) {
10474        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10475            return true;
10476        }
10477
10478        int perm = checkComponentPermission(
10479                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10480                sourceUid, -1, true);
10481        if (perm == PackageManager.PERMISSION_GRANTED) {
10482            return true;
10483        }
10484
10485        // If the actual IPC caller is different from the logical source, then
10486        // also see if they are allowed to control app switches.
10487        if (callingUid != -1 && callingUid != sourceUid) {
10488            perm = checkComponentPermission(
10489                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10490                    callingUid, -1, true);
10491            if (perm == PackageManager.PERMISSION_GRANTED) {
10492                return true;
10493            }
10494        }
10495
10496        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10497        return false;
10498    }
10499
10500    public void setDebugApp(String packageName, boolean waitForDebugger,
10501            boolean persistent) {
10502        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10503                "setDebugApp()");
10504
10505        long ident = Binder.clearCallingIdentity();
10506        try {
10507            // Note that this is not really thread safe if there are multiple
10508            // callers into it at the same time, but that's not a situation we
10509            // care about.
10510            if (persistent) {
10511                final ContentResolver resolver = mContext.getContentResolver();
10512                Settings.Global.putString(
10513                    resolver, Settings.Global.DEBUG_APP,
10514                    packageName);
10515                Settings.Global.putInt(
10516                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10517                    waitForDebugger ? 1 : 0);
10518            }
10519
10520            synchronized (this) {
10521                if (!persistent) {
10522                    mOrigDebugApp = mDebugApp;
10523                    mOrigWaitForDebugger = mWaitForDebugger;
10524                }
10525                mDebugApp = packageName;
10526                mWaitForDebugger = waitForDebugger;
10527                mDebugTransient = !persistent;
10528                if (packageName != null) {
10529                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10530                            false, UserHandle.USER_ALL, "set debug app");
10531                }
10532            }
10533        } finally {
10534            Binder.restoreCallingIdentity(ident);
10535        }
10536    }
10537
10538    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10539        synchronized (this) {
10540            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10541            if (!isDebuggable) {
10542                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10543                    throw new SecurityException("Process not debuggable: " + app.packageName);
10544                }
10545            }
10546
10547            mOpenGlTraceApp = processName;
10548        }
10549    }
10550
10551    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10552        synchronized (this) {
10553            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10554            if (!isDebuggable) {
10555                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10556                    throw new SecurityException("Process not debuggable: " + app.packageName);
10557                }
10558            }
10559            mProfileApp = processName;
10560            mProfileFile = profilerInfo.profileFile;
10561            if (mProfileFd != null) {
10562                try {
10563                    mProfileFd.close();
10564                } catch (IOException e) {
10565                }
10566                mProfileFd = null;
10567            }
10568            mProfileFd = profilerInfo.profileFd;
10569            mSamplingInterval = profilerInfo.samplingInterval;
10570            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10571            mProfileType = 0;
10572        }
10573    }
10574
10575    @Override
10576    public void setAlwaysFinish(boolean enabled) {
10577        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10578                "setAlwaysFinish()");
10579
10580        Settings.Global.putInt(
10581                mContext.getContentResolver(),
10582                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10583
10584        synchronized (this) {
10585            mAlwaysFinishActivities = enabled;
10586        }
10587    }
10588
10589    @Override
10590    public void setActivityController(IActivityController controller) {
10591        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10592                "setActivityController()");
10593        synchronized (this) {
10594            mController = controller;
10595            Watchdog.getInstance().setActivityController(controller);
10596        }
10597    }
10598
10599    @Override
10600    public void setUserIsMonkey(boolean userIsMonkey) {
10601        synchronized (this) {
10602            synchronized (mPidsSelfLocked) {
10603                final int callingPid = Binder.getCallingPid();
10604                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10605                if (precessRecord == null) {
10606                    throw new SecurityException("Unknown process: " + callingPid);
10607                }
10608                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10609                    throw new SecurityException("Only an instrumentation process "
10610                            + "with a UiAutomation can call setUserIsMonkey");
10611                }
10612            }
10613            mUserIsMonkey = userIsMonkey;
10614        }
10615    }
10616
10617    @Override
10618    public boolean isUserAMonkey() {
10619        synchronized (this) {
10620            // If there is a controller also implies the user is a monkey.
10621            return (mUserIsMonkey || mController != null);
10622        }
10623    }
10624
10625    public void requestBugReport() {
10626        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10627        SystemProperties.set("ctl.start", "bugreport");
10628    }
10629
10630    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10631        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10632    }
10633
10634    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10635        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10636            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10637        }
10638        return KEY_DISPATCHING_TIMEOUT;
10639    }
10640
10641    @Override
10642    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10643        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10644                != PackageManager.PERMISSION_GRANTED) {
10645            throw new SecurityException("Requires permission "
10646                    + android.Manifest.permission.FILTER_EVENTS);
10647        }
10648        ProcessRecord proc;
10649        long timeout;
10650        synchronized (this) {
10651            synchronized (mPidsSelfLocked) {
10652                proc = mPidsSelfLocked.get(pid);
10653            }
10654            timeout = getInputDispatchingTimeoutLocked(proc);
10655        }
10656
10657        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10658            return -1;
10659        }
10660
10661        return timeout;
10662    }
10663
10664    /**
10665     * Handle input dispatching timeouts.
10666     * Returns whether input dispatching should be aborted or not.
10667     */
10668    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10669            final ActivityRecord activity, final ActivityRecord parent,
10670            final boolean aboveSystem, String reason) {
10671        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10672                != PackageManager.PERMISSION_GRANTED) {
10673            throw new SecurityException("Requires permission "
10674                    + android.Manifest.permission.FILTER_EVENTS);
10675        }
10676
10677        final String annotation;
10678        if (reason == null) {
10679            annotation = "Input dispatching timed out";
10680        } else {
10681            annotation = "Input dispatching timed out (" + reason + ")";
10682        }
10683
10684        if (proc != null) {
10685            synchronized (this) {
10686                if (proc.debugging) {
10687                    return false;
10688                }
10689
10690                if (mDidDexOpt) {
10691                    // Give more time since we were dexopting.
10692                    mDidDexOpt = false;
10693                    return false;
10694                }
10695
10696                if (proc.instrumentationClass != null) {
10697                    Bundle info = new Bundle();
10698                    info.putString("shortMsg", "keyDispatchingTimedOut");
10699                    info.putString("longMsg", annotation);
10700                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10701                    return true;
10702                }
10703            }
10704            mHandler.post(new Runnable() {
10705                @Override
10706                public void run() {
10707                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10708                }
10709            });
10710        }
10711
10712        return true;
10713    }
10714
10715    @Override
10716    public Bundle getAssistContextExtras(int requestType) {
10717        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10718                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10719        if (pae == null) {
10720            return null;
10721        }
10722        synchronized (pae) {
10723            while (!pae.haveResult) {
10724                try {
10725                    pae.wait();
10726                } catch (InterruptedException e) {
10727                }
10728            }
10729        }
10730        synchronized (this) {
10731            buildAssistBundleLocked(pae, pae.result);
10732            mPendingAssistExtras.remove(pae);
10733            mUiHandler.removeCallbacks(pae);
10734        }
10735        return pae.extras;
10736    }
10737
10738    @Override
10739    public boolean isAssistDataAllowedOnCurrentActivity() {
10740        int userId = mCurrentUserId;
10741        synchronized (this) {
10742            ActivityRecord activity = getFocusedStack().topActivity();
10743            if (activity == null) {
10744                return false;
10745            }
10746            userId = activity.userId;
10747        }
10748        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10749                Context.DEVICE_POLICY_SERVICE);
10750        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10751    }
10752
10753    @Override
10754    public boolean showAssistFromActivity(IBinder token, Bundle args) {
10755        long ident = Binder.clearCallingIdentity();
10756        try {
10757            synchronized (this) {
10758                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
10759                ActivityRecord top = getFocusedStack().topActivity();
10760                if (top != caller) {
10761                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10762                            + " is not current top " + top);
10763                    return false;
10764                }
10765                if (!top.nowVisible) {
10766                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10767                            + " is not visible");
10768                    return false;
10769                }
10770            }
10771            AssistUtils utils = new AssistUtils(mContext);
10772            return utils.showSessionForActiveService(args,
10773                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
10774        } finally {
10775            Binder.restoreCallingIdentity(ident);
10776        }
10777    }
10778
10779    @Override
10780    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
10781            IBinder activityToken) {
10782        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
10783                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
10784    }
10785
10786    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10787            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
10788            long timeout) {
10789        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10790                "enqueueAssistContext()");
10791        synchronized (this) {
10792            ActivityRecord activity = getFocusedStack().topActivity();
10793            if (activity == null) {
10794                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10795                return null;
10796            }
10797            if (activity.app == null || activity.app.thread == null) {
10798                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10799                return null;
10800            }
10801            if (activityToken != null) {
10802                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
10803                if (activity != caller) {
10804                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
10805                            + " is not current top " + activity);
10806                    return null;
10807                }
10808            }
10809            PendingAssistExtras pae;
10810            Bundle extras = new Bundle();
10811            if (args != null) {
10812                extras.putAll(args);
10813            }
10814            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10815            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10816            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10817            try {
10818                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10819                        requestType);
10820                mPendingAssistExtras.add(pae);
10821                mUiHandler.postDelayed(pae, timeout);
10822            } catch (RemoteException e) {
10823                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10824                return null;
10825            }
10826            return pae;
10827        }
10828    }
10829
10830    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
10831        IResultReceiver receiver;
10832        synchronized (this) {
10833            mPendingAssistExtras.remove(pae);
10834            receiver = pae.receiver;
10835        }
10836        if (receiver != null) {
10837            // Caller wants result sent back to them.
10838            try {
10839                pae.receiver.send(0, null);
10840            } catch (RemoteException e) {
10841            }
10842        }
10843    }
10844
10845    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10846        if (result != null) {
10847            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10848        }
10849        if (pae.hint != null) {
10850            pae.extras.putBoolean(pae.hint, true);
10851        }
10852    }
10853
10854    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10855            AssistContent content, Uri referrer) {
10856        PendingAssistExtras pae = (PendingAssistExtras)token;
10857        synchronized (pae) {
10858            pae.result = extras;
10859            pae.structure = structure;
10860            pae.content = content;
10861            if (referrer != null) {
10862                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10863            }
10864            pae.haveResult = true;
10865            pae.notifyAll();
10866            if (pae.intent == null && pae.receiver == null) {
10867                // Caller is just waiting for the result.
10868                return;
10869            }
10870        }
10871
10872        // We are now ready to launch the assist activity.
10873        IResultReceiver sendReceiver = null;
10874        Bundle sendBundle = null;
10875        synchronized (this) {
10876            buildAssistBundleLocked(pae, extras);
10877            boolean exists = mPendingAssistExtras.remove(pae);
10878            mUiHandler.removeCallbacks(pae);
10879            if (!exists) {
10880                // Timed out.
10881                return;
10882            }
10883            if ((sendReceiver=pae.receiver) != null) {
10884                // Caller wants result sent back to them.
10885                sendBundle = new Bundle();
10886                sendBundle.putBundle("data", pae.extras);
10887                sendBundle.putParcelable("structure", pae.structure);
10888                sendBundle.putParcelable("content", pae.content);
10889            }
10890        }
10891        if (sendReceiver != null) {
10892            try {
10893                sendReceiver.send(0, sendBundle);
10894            } catch (RemoteException e) {
10895            }
10896            return;
10897        }
10898
10899        long ident = Binder.clearCallingIdentity();
10900        try {
10901            pae.intent.replaceExtras(pae.extras);
10902            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10903                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
10904                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10905            closeSystemDialogs("assist");
10906            try {
10907                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10908            } catch (ActivityNotFoundException e) {
10909                Slog.w(TAG, "No activity to handle assist action.", e);
10910            }
10911        } finally {
10912            Binder.restoreCallingIdentity(ident);
10913        }
10914    }
10915
10916    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10917            Bundle args) {
10918        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
10919                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10920    }
10921
10922    public void registerProcessObserver(IProcessObserver observer) {
10923        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10924                "registerProcessObserver()");
10925        synchronized (this) {
10926            mProcessObservers.register(observer);
10927        }
10928    }
10929
10930    @Override
10931    public void unregisterProcessObserver(IProcessObserver observer) {
10932        synchronized (this) {
10933            mProcessObservers.unregister(observer);
10934        }
10935    }
10936
10937    public void registerUidObserver(IUidObserver observer) {
10938        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10939                "registerUidObserver()");
10940        synchronized (this) {
10941            mUidObservers.register(observer);
10942        }
10943    }
10944
10945    @Override
10946    public void unregisterUidObserver(IUidObserver observer) {
10947        synchronized (this) {
10948            mUidObservers.unregister(observer);
10949        }
10950    }
10951
10952    @Override
10953    public boolean convertFromTranslucent(IBinder token) {
10954        final long origId = Binder.clearCallingIdentity();
10955        try {
10956            synchronized (this) {
10957                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10958                if (r == null) {
10959                    return false;
10960                }
10961                final boolean translucentChanged = r.changeWindowTranslucency(true);
10962                if (translucentChanged) {
10963                    r.task.stack.releaseBackgroundResources(r);
10964                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10965                }
10966                mWindowManager.setAppFullscreen(token, true);
10967                return translucentChanged;
10968            }
10969        } finally {
10970            Binder.restoreCallingIdentity(origId);
10971        }
10972    }
10973
10974    @Override
10975    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10976        final long origId = Binder.clearCallingIdentity();
10977        try {
10978            synchronized (this) {
10979                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10980                if (r == null) {
10981                    return false;
10982                }
10983                int index = r.task.mActivities.lastIndexOf(r);
10984                if (index > 0) {
10985                    ActivityRecord under = r.task.mActivities.get(index - 1);
10986                    under.returningOptions = options;
10987                }
10988                final boolean translucentChanged = r.changeWindowTranslucency(false);
10989                if (translucentChanged) {
10990                    r.task.stack.convertActivityToTranslucent(r);
10991                }
10992                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10993                mWindowManager.setAppFullscreen(token, false);
10994                return translucentChanged;
10995            }
10996        } finally {
10997            Binder.restoreCallingIdentity(origId);
10998        }
10999    }
11000
11001    @Override
11002    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11003        final long origId = Binder.clearCallingIdentity();
11004        try {
11005            synchronized (this) {
11006                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11007                if (r != null) {
11008                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11009                }
11010            }
11011            return false;
11012        } finally {
11013            Binder.restoreCallingIdentity(origId);
11014        }
11015    }
11016
11017    @Override
11018    public boolean isBackgroundVisibleBehind(IBinder token) {
11019        final long origId = Binder.clearCallingIdentity();
11020        try {
11021            synchronized (this) {
11022                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11023                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11024                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11025                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11026                return visible;
11027            }
11028        } finally {
11029            Binder.restoreCallingIdentity(origId);
11030        }
11031    }
11032
11033    @Override
11034    public ActivityOptions getActivityOptions(IBinder token) {
11035        final long origId = Binder.clearCallingIdentity();
11036        try {
11037            synchronized (this) {
11038                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11039                if (r != null) {
11040                    final ActivityOptions activityOptions = r.pendingOptions;
11041                    r.pendingOptions = null;
11042                    return activityOptions;
11043                }
11044                return null;
11045            }
11046        } finally {
11047            Binder.restoreCallingIdentity(origId);
11048        }
11049    }
11050
11051    @Override
11052    public void setImmersive(IBinder token, boolean immersive) {
11053        synchronized(this) {
11054            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11055            if (r == null) {
11056                throw new IllegalArgumentException();
11057            }
11058            r.immersive = immersive;
11059
11060            // update associated state if we're frontmost
11061            if (r == mFocusedActivity) {
11062                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11063                applyUpdateLockStateLocked(r);
11064            }
11065        }
11066    }
11067
11068    @Override
11069    public boolean isImmersive(IBinder token) {
11070        synchronized (this) {
11071            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11072            if (r == null) {
11073                throw new IllegalArgumentException();
11074            }
11075            return r.immersive;
11076        }
11077    }
11078
11079    public boolean isTopActivityImmersive() {
11080        enforceNotIsolatedCaller("startActivity");
11081        synchronized (this) {
11082            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
11083            return (r != null) ? r.immersive : false;
11084        }
11085    }
11086
11087    @Override
11088    public boolean isTopOfTask(IBinder token) {
11089        synchronized (this) {
11090            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11091            if (r == null) {
11092                throw new IllegalArgumentException();
11093            }
11094            return r.task.getTopActivity() == r;
11095        }
11096    }
11097
11098    public final void enterSafeMode() {
11099        synchronized(this) {
11100            // It only makes sense to do this before the system is ready
11101            // and started launching other packages.
11102            if (!mSystemReady) {
11103                try {
11104                    AppGlobals.getPackageManager().enterSafeMode();
11105                } catch (RemoteException e) {
11106                }
11107            }
11108
11109            mSafeMode = true;
11110        }
11111    }
11112
11113    public final void showSafeModeOverlay() {
11114        View v = LayoutInflater.from(mContext).inflate(
11115                com.android.internal.R.layout.safe_mode, null);
11116        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11117        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11118        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11119        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11120        lp.gravity = Gravity.BOTTOM | Gravity.START;
11121        lp.format = v.getBackground().getOpacity();
11122        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11123                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11124        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11125        ((WindowManager)mContext.getSystemService(
11126                Context.WINDOW_SERVICE)).addView(v, lp);
11127    }
11128
11129    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11130        if (!(sender instanceof PendingIntentRecord)) {
11131            return;
11132        }
11133        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11134        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11135        synchronized (stats) {
11136            if (mBatteryStatsService.isOnBattery()) {
11137                mBatteryStatsService.enforceCallingPermission();
11138                int MY_UID = Binder.getCallingUid();
11139                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11140                BatteryStatsImpl.Uid.Pkg pkg =
11141                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11142                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11143                pkg.noteWakeupAlarmLocked(tag);
11144            }
11145        }
11146    }
11147
11148    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11149        if (!(sender instanceof PendingIntentRecord)) {
11150            return;
11151        }
11152        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11153        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11154        synchronized (stats) {
11155            mBatteryStatsService.enforceCallingPermission();
11156            int MY_UID = Binder.getCallingUid();
11157            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11158            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11159        }
11160    }
11161
11162    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11163        if (!(sender instanceof PendingIntentRecord)) {
11164            return;
11165        }
11166        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11167        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11168        synchronized (stats) {
11169            mBatteryStatsService.enforceCallingPermission();
11170            int MY_UID = Binder.getCallingUid();
11171            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11172            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11173        }
11174    }
11175
11176    public boolean killPids(int[] pids, String pReason, boolean secure) {
11177        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11178            throw new SecurityException("killPids only available to the system");
11179        }
11180        String reason = (pReason == null) ? "Unknown" : pReason;
11181        // XXX Note: don't acquire main activity lock here, because the window
11182        // manager calls in with its locks held.
11183
11184        boolean killed = false;
11185        synchronized (mPidsSelfLocked) {
11186            int[] types = new int[pids.length];
11187            int worstType = 0;
11188            for (int i=0; i<pids.length; i++) {
11189                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11190                if (proc != null) {
11191                    int type = proc.setAdj;
11192                    types[i] = type;
11193                    if (type > worstType) {
11194                        worstType = type;
11195                    }
11196                }
11197            }
11198
11199            // If the worst oom_adj is somewhere in the cached proc LRU range,
11200            // then constrain it so we will kill all cached procs.
11201            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11202                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11203                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11204            }
11205
11206            // If this is not a secure call, don't let it kill processes that
11207            // are important.
11208            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11209                worstType = ProcessList.SERVICE_ADJ;
11210            }
11211
11212            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11213            for (int i=0; i<pids.length; i++) {
11214                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11215                if (proc == null) {
11216                    continue;
11217                }
11218                int adj = proc.setAdj;
11219                if (adj >= worstType && !proc.killedByAm) {
11220                    proc.kill(reason, true);
11221                    killed = true;
11222                }
11223            }
11224        }
11225        return killed;
11226    }
11227
11228    @Override
11229    public void killUid(int appId, int userId, String reason) {
11230        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11231        synchronized (this) {
11232            final long identity = Binder.clearCallingIdentity();
11233            try {
11234                killPackageProcessesLocked(null, appId, userId,
11235                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11236                        reason != null ? reason : "kill uid");
11237            } finally {
11238                Binder.restoreCallingIdentity(identity);
11239            }
11240        }
11241    }
11242
11243    @Override
11244    public boolean killProcessesBelowForeground(String reason) {
11245        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11246            throw new SecurityException("killProcessesBelowForeground() only available to system");
11247        }
11248
11249        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11250    }
11251
11252    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11253        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11254            throw new SecurityException("killProcessesBelowAdj() only available to system");
11255        }
11256
11257        boolean killed = false;
11258        synchronized (mPidsSelfLocked) {
11259            final int size = mPidsSelfLocked.size();
11260            for (int i = 0; i < size; i++) {
11261                final int pid = mPidsSelfLocked.keyAt(i);
11262                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11263                if (proc == null) continue;
11264
11265                final int adj = proc.setAdj;
11266                if (adj > belowAdj && !proc.killedByAm) {
11267                    proc.kill(reason, true);
11268                    killed = true;
11269                }
11270            }
11271        }
11272        return killed;
11273    }
11274
11275    @Override
11276    public void hang(final IBinder who, boolean allowRestart) {
11277        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11278                != PackageManager.PERMISSION_GRANTED) {
11279            throw new SecurityException("Requires permission "
11280                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11281        }
11282
11283        final IBinder.DeathRecipient death = new DeathRecipient() {
11284            @Override
11285            public void binderDied() {
11286                synchronized (this) {
11287                    notifyAll();
11288                }
11289            }
11290        };
11291
11292        try {
11293            who.linkToDeath(death, 0);
11294        } catch (RemoteException e) {
11295            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11296            return;
11297        }
11298
11299        synchronized (this) {
11300            Watchdog.getInstance().setAllowRestart(allowRestart);
11301            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11302            synchronized (death) {
11303                while (who.isBinderAlive()) {
11304                    try {
11305                        death.wait();
11306                    } catch (InterruptedException e) {
11307                    }
11308                }
11309            }
11310            Watchdog.getInstance().setAllowRestart(true);
11311        }
11312    }
11313
11314    @Override
11315    public void restart() {
11316        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11317                != PackageManager.PERMISSION_GRANTED) {
11318            throw new SecurityException("Requires permission "
11319                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11320        }
11321
11322        Log.i(TAG, "Sending shutdown broadcast...");
11323
11324        BroadcastReceiver br = new BroadcastReceiver() {
11325            @Override public void onReceive(Context context, Intent intent) {
11326                // Now the broadcast is done, finish up the low-level shutdown.
11327                Log.i(TAG, "Shutting down activity manager...");
11328                shutdown(10000);
11329                Log.i(TAG, "Shutdown complete, restarting!");
11330                Process.killProcess(Process.myPid());
11331                System.exit(10);
11332            }
11333        };
11334
11335        // First send the high-level shut down broadcast.
11336        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11337        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11338        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11339        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11340        mContext.sendOrderedBroadcastAsUser(intent,
11341                UserHandle.ALL, null, br, mHandler, 0, null, null);
11342        */
11343        br.onReceive(mContext, intent);
11344    }
11345
11346    private long getLowRamTimeSinceIdle(long now) {
11347        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11348    }
11349
11350    @Override
11351    public void performIdleMaintenance() {
11352        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11353                != PackageManager.PERMISSION_GRANTED) {
11354            throw new SecurityException("Requires permission "
11355                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11356        }
11357
11358        synchronized (this) {
11359            final long now = SystemClock.uptimeMillis();
11360            final long timeSinceLastIdle = now - mLastIdleTime;
11361            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11362            mLastIdleTime = now;
11363            mLowRamTimeSinceLastIdle = 0;
11364            if (mLowRamStartTime != 0) {
11365                mLowRamStartTime = now;
11366            }
11367
11368            StringBuilder sb = new StringBuilder(128);
11369            sb.append("Idle maintenance over ");
11370            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11371            sb.append(" low RAM for ");
11372            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11373            Slog.i(TAG, sb.toString());
11374
11375            // If at least 1/3 of our time since the last idle period has been spent
11376            // with RAM low, then we want to kill processes.
11377            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11378
11379            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11380                ProcessRecord proc = mLruProcesses.get(i);
11381                if (proc.notCachedSinceIdle) {
11382                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11383                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11384                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11385                        if (doKilling && proc.initialIdlePss != 0
11386                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11387                            sb = new StringBuilder(128);
11388                            sb.append("Kill");
11389                            sb.append(proc.processName);
11390                            sb.append(" in idle maint: pss=");
11391                            sb.append(proc.lastPss);
11392                            sb.append(", initialPss=");
11393                            sb.append(proc.initialIdlePss);
11394                            sb.append(", period=");
11395                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11396                            sb.append(", lowRamPeriod=");
11397                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11398                            Slog.wtfQuiet(TAG, sb.toString());
11399                            proc.kill("idle maint (pss " + proc.lastPss
11400                                    + " from " + proc.initialIdlePss + ")", true);
11401                        }
11402                    }
11403                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11404                    proc.notCachedSinceIdle = true;
11405                    proc.initialIdlePss = 0;
11406                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11407                            mTestPssMode, isSleeping(), now);
11408                }
11409            }
11410
11411            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11412            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11413        }
11414    }
11415
11416    private void retrieveSettings() {
11417        final ContentResolver resolver = mContext.getContentResolver();
11418        String debugApp = Settings.Global.getString(
11419            resolver, Settings.Global.DEBUG_APP);
11420        boolean waitForDebugger = Settings.Global.getInt(
11421            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11422        boolean alwaysFinishActivities = Settings.Global.getInt(
11423            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11424        boolean forceRtl = Settings.Global.getInt(
11425                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11426        // Transfer any global setting for forcing RTL layout, into a System Property
11427        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11428
11429        Configuration configuration = new Configuration();
11430        Settings.System.getConfiguration(resolver, configuration);
11431        if (forceRtl) {
11432            // This will take care of setting the correct layout direction flags
11433            configuration.setLayoutDirection(configuration.locale);
11434        }
11435
11436        synchronized (this) {
11437            mDebugApp = mOrigDebugApp = debugApp;
11438            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11439            mAlwaysFinishActivities = alwaysFinishActivities;
11440            // This happens before any activities are started, so we can
11441            // change mConfiguration in-place.
11442            updateConfigurationLocked(configuration, null, false, true);
11443            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11444                    "Initial config: " + mConfiguration);
11445        }
11446    }
11447
11448    /** Loads resources after the current configuration has been set. */
11449    private void loadResourcesOnSystemReady() {
11450        final Resources res = mContext.getResources();
11451        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11452        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11453        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11454    }
11455
11456    public boolean testIsSystemReady() {
11457        // no need to synchronize(this) just to read & return the value
11458        return mSystemReady;
11459    }
11460
11461    private static File getCalledPreBootReceiversFile() {
11462        File dataDir = Environment.getDataDirectory();
11463        File systemDir = new File(dataDir, "system");
11464        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11465        return fname;
11466    }
11467
11468    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11469        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11470        File file = getCalledPreBootReceiversFile();
11471        FileInputStream fis = null;
11472        try {
11473            fis = new FileInputStream(file);
11474            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11475            int fvers = dis.readInt();
11476            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11477                String vers = dis.readUTF();
11478                String codename = dis.readUTF();
11479                String build = dis.readUTF();
11480                if (android.os.Build.VERSION.RELEASE.equals(vers)
11481                        && android.os.Build.VERSION.CODENAME.equals(codename)
11482                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11483                    int num = dis.readInt();
11484                    while (num > 0) {
11485                        num--;
11486                        String pkg = dis.readUTF();
11487                        String cls = dis.readUTF();
11488                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11489                    }
11490                }
11491            }
11492        } catch (FileNotFoundException e) {
11493        } catch (IOException e) {
11494            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11495        } finally {
11496            if (fis != null) {
11497                try {
11498                    fis.close();
11499                } catch (IOException e) {
11500                }
11501            }
11502        }
11503        return lastDoneReceivers;
11504    }
11505
11506    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11507        File file = getCalledPreBootReceiversFile();
11508        FileOutputStream fos = null;
11509        DataOutputStream dos = null;
11510        try {
11511            fos = new FileOutputStream(file);
11512            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11513            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11514            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11515            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11516            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11517            dos.writeInt(list.size());
11518            for (int i=0; i<list.size(); i++) {
11519                dos.writeUTF(list.get(i).getPackageName());
11520                dos.writeUTF(list.get(i).getClassName());
11521            }
11522        } catch (IOException e) {
11523            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11524            file.delete();
11525        } finally {
11526            FileUtils.sync(fos);
11527            if (dos != null) {
11528                try {
11529                    dos.close();
11530                } catch (IOException e) {
11531                    // TODO Auto-generated catch block
11532                    e.printStackTrace();
11533                }
11534            }
11535        }
11536    }
11537
11538    final class PreBootContinuation extends IIntentReceiver.Stub {
11539        final Intent intent;
11540        final Runnable onFinishCallback;
11541        final ArrayList<ComponentName> doneReceivers;
11542        final List<ResolveInfo> ris;
11543        final int[] users;
11544        int lastRi = -1;
11545        int curRi = 0;
11546        int curUser = 0;
11547
11548        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11549                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11550            intent = _intent;
11551            onFinishCallback = _onFinishCallback;
11552            doneReceivers = _doneReceivers;
11553            ris = _ris;
11554            users = _users;
11555        }
11556
11557        void go() {
11558            if (lastRi != curRi) {
11559                ActivityInfo ai = ris.get(curRi).activityInfo;
11560                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11561                intent.setComponent(comp);
11562                doneReceivers.add(comp);
11563                lastRi = curRi;
11564                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11565                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11566            }
11567            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11568                    + " for user " + users[curUser]);
11569            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11570            broadcastIntentLocked(null, null, intent, null, this,
11571                    0, null, null, null, AppOpsManager.OP_NONE,
11572                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11573        }
11574
11575        public void performReceive(Intent intent, int resultCode,
11576                String data, Bundle extras, boolean ordered,
11577                boolean sticky, int sendingUser) {
11578            curUser++;
11579            if (curUser >= users.length) {
11580                curUser = 0;
11581                curRi++;
11582                if (curRi >= ris.size()) {
11583                    // All done sending broadcasts!
11584                    if (onFinishCallback != null) {
11585                        // The raw IIntentReceiver interface is called
11586                        // with the AM lock held, so redispatch to
11587                        // execute our code without the lock.
11588                        mHandler.post(onFinishCallback);
11589                    }
11590                    return;
11591                }
11592            }
11593            go();
11594        }
11595    }
11596
11597    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11598            ArrayList<ComponentName> doneReceivers, int userId) {
11599        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11600        List<ResolveInfo> ris = null;
11601        try {
11602            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11603                    intent, null, 0, userId);
11604        } catch (RemoteException e) {
11605        }
11606        if (ris == null) {
11607            return false;
11608        }
11609        for (int i=ris.size()-1; i>=0; i--) {
11610            if ((ris.get(i).activityInfo.applicationInfo.flags
11611                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11612                ris.remove(i);
11613            }
11614        }
11615        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11616
11617        // For User 0, load the version number. When delivering to a new user, deliver
11618        // to all receivers.
11619        if (userId == UserHandle.USER_OWNER) {
11620            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11621            for (int i=0; i<ris.size(); i++) {
11622                ActivityInfo ai = ris.get(i).activityInfo;
11623                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11624                if (lastDoneReceivers.contains(comp)) {
11625                    // We already did the pre boot receiver for this app with the current
11626                    // platform version, so don't do it again...
11627                    ris.remove(i);
11628                    i--;
11629                    // ...however, do keep it as one that has been done, so we don't
11630                    // forget about it when rewriting the file of last done receivers.
11631                    doneReceivers.add(comp);
11632                }
11633            }
11634        }
11635
11636        if (ris.size() <= 0) {
11637            return false;
11638        }
11639
11640        // If primary user, send broadcast to all available users, else just to userId
11641        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11642                : new int[] { userId };
11643        if (users.length <= 0) {
11644            return false;
11645        }
11646
11647        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11648                ris, users);
11649        cont.go();
11650        return true;
11651    }
11652
11653    public void systemReady(final Runnable goingCallback) {
11654        synchronized(this) {
11655            if (mSystemReady) {
11656                // If we're done calling all the receivers, run the next "boot phase" passed in
11657                // by the SystemServer
11658                if (goingCallback != null) {
11659                    goingCallback.run();
11660                }
11661                return;
11662            }
11663
11664            mLocalDeviceIdleController
11665                    = LocalServices.getService(DeviceIdleController.LocalService.class);
11666
11667            // Make sure we have the current profile info, since it is needed for
11668            // security checks.
11669            updateCurrentProfileIdsLocked();
11670
11671            mRecentTasks.clear();
11672            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11673            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11674            mTaskPersister.startPersisting();
11675
11676            // Check to see if there are any update receivers to run.
11677            if (!mDidUpdate) {
11678                if (mWaitingUpdate) {
11679                    return;
11680                }
11681                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11682                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11683                    public void run() {
11684                        synchronized (ActivityManagerService.this) {
11685                            mDidUpdate = true;
11686                        }
11687                        showBootMessage(mContext.getText(
11688                                R.string.android_upgrading_complete),
11689                                false);
11690                        writeLastDonePreBootReceivers(doneReceivers);
11691                        systemReady(goingCallback);
11692                    }
11693                }, doneReceivers, UserHandle.USER_OWNER);
11694
11695                if (mWaitingUpdate) {
11696                    return;
11697                }
11698                mDidUpdate = true;
11699            }
11700
11701            mAppOpsService.systemReady();
11702            mSystemReady = true;
11703        }
11704
11705        ArrayList<ProcessRecord> procsToKill = null;
11706        synchronized(mPidsSelfLocked) {
11707            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11708                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11709                if (!isAllowedWhileBooting(proc.info)){
11710                    if (procsToKill == null) {
11711                        procsToKill = new ArrayList<ProcessRecord>();
11712                    }
11713                    procsToKill.add(proc);
11714                }
11715            }
11716        }
11717
11718        synchronized(this) {
11719            if (procsToKill != null) {
11720                for (int i=procsToKill.size()-1; i>=0; i--) {
11721                    ProcessRecord proc = procsToKill.get(i);
11722                    Slog.i(TAG, "Removing system update proc: " + proc);
11723                    removeProcessLocked(proc, true, false, "system update done");
11724                }
11725            }
11726
11727            // Now that we have cleaned up any update processes, we
11728            // are ready to start launching real processes and know that
11729            // we won't trample on them any more.
11730            mProcessesReady = true;
11731        }
11732
11733        Slog.i(TAG, "System now ready");
11734        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11735            SystemClock.uptimeMillis());
11736
11737        synchronized(this) {
11738            // Make sure we have no pre-ready processes sitting around.
11739
11740            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11741                ResolveInfo ri = mContext.getPackageManager()
11742                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11743                                STOCK_PM_FLAGS);
11744                CharSequence errorMsg = null;
11745                if (ri != null) {
11746                    ActivityInfo ai = ri.activityInfo;
11747                    ApplicationInfo app = ai.applicationInfo;
11748                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11749                        mTopAction = Intent.ACTION_FACTORY_TEST;
11750                        mTopData = null;
11751                        mTopComponent = new ComponentName(app.packageName,
11752                                ai.name);
11753                    } else {
11754                        errorMsg = mContext.getResources().getText(
11755                                com.android.internal.R.string.factorytest_not_system);
11756                    }
11757                } else {
11758                    errorMsg = mContext.getResources().getText(
11759                            com.android.internal.R.string.factorytest_no_action);
11760                }
11761                if (errorMsg != null) {
11762                    mTopAction = null;
11763                    mTopData = null;
11764                    mTopComponent = null;
11765                    Message msg = Message.obtain();
11766                    msg.what = SHOW_FACTORY_ERROR_MSG;
11767                    msg.getData().putCharSequence("msg", errorMsg);
11768                    mUiHandler.sendMessage(msg);
11769                }
11770            }
11771        }
11772
11773        retrieveSettings();
11774        loadResourcesOnSystemReady();
11775
11776        synchronized (this) {
11777            readGrantedUriPermissionsLocked();
11778        }
11779
11780        if (goingCallback != null) goingCallback.run();
11781
11782        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11783                Integer.toString(mCurrentUserId), mCurrentUserId);
11784        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11785                Integer.toString(mCurrentUserId), mCurrentUserId);
11786        mSystemServiceManager.startUser(mCurrentUserId);
11787
11788        synchronized (this) {
11789            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11790                try {
11791                    List apps = AppGlobals.getPackageManager().
11792                        getPersistentApplications(STOCK_PM_FLAGS);
11793                    if (apps != null) {
11794                        int N = apps.size();
11795                        int i;
11796                        for (i=0; i<N; i++) {
11797                            ApplicationInfo info
11798                                = (ApplicationInfo)apps.get(i);
11799                            if (info != null &&
11800                                    !info.packageName.equals("android")) {
11801                                addAppLocked(info, false, null /* ABI override */);
11802                            }
11803                        }
11804                    }
11805                } catch (RemoteException ex) {
11806                    // pm is in same process, this will never happen.
11807                }
11808            }
11809
11810            // Start up initial activity.
11811            mBooting = true;
11812            startHomeActivityLocked(mCurrentUserId, "systemReady");
11813
11814            try {
11815                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11816                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11817                            + " data partition or your device will be unstable.");
11818                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11819                }
11820            } catch (RemoteException e) {
11821            }
11822
11823            if (!Build.isBuildConsistent()) {
11824                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11825                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11826            }
11827
11828            long ident = Binder.clearCallingIdentity();
11829            try {
11830                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11831                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11832                        | Intent.FLAG_RECEIVER_FOREGROUND);
11833                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11834                broadcastIntentLocked(null, null, intent,
11835                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11836                        null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11837                intent = new Intent(Intent.ACTION_USER_STARTING);
11838                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11839                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11840                broadcastIntentLocked(null, null, intent,
11841                        null, new IIntentReceiver.Stub() {
11842                            @Override
11843                            public void performReceive(Intent intent, int resultCode, String data,
11844                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11845                                    throws RemoteException {
11846                            }
11847                        }, 0, null, null,
11848                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
11849                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11850            } catch (Throwable t) {
11851                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11852            } finally {
11853                Binder.restoreCallingIdentity(ident);
11854            }
11855            mStackSupervisor.resumeTopActivitiesLocked();
11856            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11857        }
11858    }
11859
11860    private boolean makeAppCrashingLocked(ProcessRecord app,
11861            String shortMsg, String longMsg, String stackTrace) {
11862        app.crashing = true;
11863        app.crashingReport = generateProcessError(app,
11864                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11865        startAppProblemLocked(app);
11866        app.stopFreezingAllLocked();
11867        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11868    }
11869
11870    private void makeAppNotRespondingLocked(ProcessRecord app,
11871            String activity, String shortMsg, String longMsg) {
11872        app.notResponding = true;
11873        app.notRespondingReport = generateProcessError(app,
11874                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11875                activity, shortMsg, longMsg, null);
11876        startAppProblemLocked(app);
11877        app.stopFreezingAllLocked();
11878    }
11879
11880    /**
11881     * Generate a process error record, suitable for attachment to a ProcessRecord.
11882     *
11883     * @param app The ProcessRecord in which the error occurred.
11884     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11885     *                      ActivityManager.AppErrorStateInfo
11886     * @param activity The activity associated with the crash, if known.
11887     * @param shortMsg Short message describing the crash.
11888     * @param longMsg Long message describing the crash.
11889     * @param stackTrace Full crash stack trace, may be null.
11890     *
11891     * @return Returns a fully-formed AppErrorStateInfo record.
11892     */
11893    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11894            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11895        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11896
11897        report.condition = condition;
11898        report.processName = app.processName;
11899        report.pid = app.pid;
11900        report.uid = app.info.uid;
11901        report.tag = activity;
11902        report.shortMsg = shortMsg;
11903        report.longMsg = longMsg;
11904        report.stackTrace = stackTrace;
11905
11906        return report;
11907    }
11908
11909    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11910        synchronized (this) {
11911            app.crashing = false;
11912            app.crashingReport = null;
11913            app.notResponding = false;
11914            app.notRespondingReport = null;
11915            if (app.anrDialog == fromDialog) {
11916                app.anrDialog = null;
11917            }
11918            if (app.waitDialog == fromDialog) {
11919                app.waitDialog = null;
11920            }
11921            if (app.pid > 0 && app.pid != MY_PID) {
11922                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11923                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11924                app.kill("user request after error", true);
11925            }
11926        }
11927    }
11928
11929    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11930            String shortMsg, String longMsg, String stackTrace) {
11931        long now = SystemClock.uptimeMillis();
11932
11933        Long crashTime;
11934        if (!app.isolated) {
11935            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11936        } else {
11937            crashTime = null;
11938        }
11939        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11940            // This process loses!
11941            Slog.w(TAG, "Process " + app.info.processName
11942                    + " has crashed too many times: killing!");
11943            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11944                    app.userId, app.info.processName, app.uid);
11945            mStackSupervisor.handleAppCrashLocked(app);
11946            if (!app.persistent) {
11947                // We don't want to start this process again until the user
11948                // explicitly does so...  but for persistent process, we really
11949                // need to keep it running.  If a persistent process is actually
11950                // repeatedly crashing, then badness for everyone.
11951                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11952                        app.info.processName);
11953                if (!app.isolated) {
11954                    // XXX We don't have a way to mark isolated processes
11955                    // as bad, since they don't have a peristent identity.
11956                    mBadProcesses.put(app.info.processName, app.uid,
11957                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11958                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11959                }
11960                app.bad = true;
11961                app.removed = true;
11962                // Don't let services in this process be restarted and potentially
11963                // annoy the user repeatedly.  Unless it is persistent, since those
11964                // processes run critical code.
11965                removeProcessLocked(app, false, false, "crash");
11966                mStackSupervisor.resumeTopActivitiesLocked();
11967                return false;
11968            }
11969            mStackSupervisor.resumeTopActivitiesLocked();
11970        } else {
11971            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11972        }
11973
11974        // Bump up the crash count of any services currently running in the proc.
11975        for (int i=app.services.size()-1; i>=0; i--) {
11976            // Any services running in the application need to be placed
11977            // back in the pending list.
11978            ServiceRecord sr = app.services.valueAt(i);
11979            sr.crashCount++;
11980        }
11981
11982        // If the crashing process is what we consider to be the "home process" and it has been
11983        // replaced by a third-party app, clear the package preferred activities from packages
11984        // with a home activity running in the process to prevent a repeatedly crashing app
11985        // from blocking the user to manually clear the list.
11986        final ArrayList<ActivityRecord> activities = app.activities;
11987        if (app == mHomeProcess && activities.size() > 0
11988                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11989            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11990                final ActivityRecord r = activities.get(activityNdx);
11991                if (r.isHomeActivity()) {
11992                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11993                    try {
11994                        ActivityThread.getPackageManager()
11995                                .clearPackagePreferredActivities(r.packageName);
11996                    } catch (RemoteException c) {
11997                        // pm is in same process, this will never happen.
11998                    }
11999                }
12000            }
12001        }
12002
12003        if (!app.isolated) {
12004            // XXX Can't keep track of crash times for isolated processes,
12005            // because they don't have a perisistent identity.
12006            mProcessCrashTimes.put(app.info.processName, app.uid, now);
12007        }
12008
12009        if (app.crashHandler != null) mHandler.post(app.crashHandler);
12010        return true;
12011    }
12012
12013    void startAppProblemLocked(ProcessRecord app) {
12014        // If this app is not running under the current user, then we
12015        // can't give it a report button because that would require
12016        // launching the report UI under a different user.
12017        app.errorReportReceiver = null;
12018
12019        for (int userId : mCurrentProfileIds) {
12020            if (app.userId == userId) {
12021                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12022                        mContext, app.info.packageName, app.info.flags);
12023            }
12024        }
12025        skipCurrentReceiverLocked(app);
12026    }
12027
12028    void skipCurrentReceiverLocked(ProcessRecord app) {
12029        for (BroadcastQueue queue : mBroadcastQueues) {
12030            queue.skipCurrentReceiverLocked(app);
12031        }
12032    }
12033
12034    /**
12035     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12036     * The application process will exit immediately after this call returns.
12037     * @param app object of the crashing app, null for the system server
12038     * @param crashInfo describing the exception
12039     */
12040    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12041        ProcessRecord r = findAppProcess(app, "Crash");
12042        final String processName = app == null ? "system_server"
12043                : (r == null ? "unknown" : r.processName);
12044
12045        handleApplicationCrashInner("crash", r, processName, crashInfo);
12046    }
12047
12048    /* Native crash reporting uses this inner version because it needs to be somewhat
12049     * decoupled from the AM-managed cleanup lifecycle
12050     */
12051    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12052            ApplicationErrorReport.CrashInfo crashInfo) {
12053        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12054                UserHandle.getUserId(Binder.getCallingUid()), processName,
12055                r == null ? -1 : r.info.flags,
12056                crashInfo.exceptionClassName,
12057                crashInfo.exceptionMessage,
12058                crashInfo.throwFileName,
12059                crashInfo.throwLineNumber);
12060
12061        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12062
12063        crashApplication(r, crashInfo);
12064    }
12065
12066    public void handleApplicationStrictModeViolation(
12067            IBinder app,
12068            int violationMask,
12069            StrictMode.ViolationInfo info) {
12070        ProcessRecord r = findAppProcess(app, "StrictMode");
12071        if (r == null) {
12072            return;
12073        }
12074
12075        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12076            Integer stackFingerprint = info.hashCode();
12077            boolean logIt = true;
12078            synchronized (mAlreadyLoggedViolatedStacks) {
12079                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12080                    logIt = false;
12081                    // TODO: sub-sample into EventLog for these, with
12082                    // the info.durationMillis?  Then we'd get
12083                    // the relative pain numbers, without logging all
12084                    // the stack traces repeatedly.  We'd want to do
12085                    // likewise in the client code, which also does
12086                    // dup suppression, before the Binder call.
12087                } else {
12088                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12089                        mAlreadyLoggedViolatedStacks.clear();
12090                    }
12091                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12092                }
12093            }
12094            if (logIt) {
12095                logStrictModeViolationToDropBox(r, info);
12096            }
12097        }
12098
12099        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12100            AppErrorResult result = new AppErrorResult();
12101            synchronized (this) {
12102                final long origId = Binder.clearCallingIdentity();
12103
12104                Message msg = Message.obtain();
12105                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12106                HashMap<String, Object> data = new HashMap<String, Object>();
12107                data.put("result", result);
12108                data.put("app", r);
12109                data.put("violationMask", violationMask);
12110                data.put("info", info);
12111                msg.obj = data;
12112                mUiHandler.sendMessage(msg);
12113
12114                Binder.restoreCallingIdentity(origId);
12115            }
12116            int res = result.get();
12117            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12118        }
12119    }
12120
12121    // Depending on the policy in effect, there could be a bunch of
12122    // these in quick succession so we try to batch these together to
12123    // minimize disk writes, number of dropbox entries, and maximize
12124    // compression, by having more fewer, larger records.
12125    private void logStrictModeViolationToDropBox(
12126            ProcessRecord process,
12127            StrictMode.ViolationInfo info) {
12128        if (info == null) {
12129            return;
12130        }
12131        final boolean isSystemApp = process == null ||
12132                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12133                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12134        final String processName = process == null ? "unknown" : process.processName;
12135        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12136        final DropBoxManager dbox = (DropBoxManager)
12137                mContext.getSystemService(Context.DROPBOX_SERVICE);
12138
12139        // Exit early if the dropbox isn't configured to accept this report type.
12140        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12141
12142        boolean bufferWasEmpty;
12143        boolean needsFlush;
12144        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12145        synchronized (sb) {
12146            bufferWasEmpty = sb.length() == 0;
12147            appendDropBoxProcessHeaders(process, processName, sb);
12148            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12149            sb.append("System-App: ").append(isSystemApp).append("\n");
12150            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12151            if (info.violationNumThisLoop != 0) {
12152                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12153            }
12154            if (info.numAnimationsRunning != 0) {
12155                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12156            }
12157            if (info.broadcastIntentAction != null) {
12158                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12159            }
12160            if (info.durationMillis != -1) {
12161                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12162            }
12163            if (info.numInstances != -1) {
12164                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12165            }
12166            if (info.tags != null) {
12167                for (String tag : info.tags) {
12168                    sb.append("Span-Tag: ").append(tag).append("\n");
12169                }
12170            }
12171            sb.append("\n");
12172            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12173                sb.append(info.crashInfo.stackTrace);
12174                sb.append("\n");
12175            }
12176            if (info.message != null) {
12177                sb.append(info.message);
12178                sb.append("\n");
12179            }
12180
12181            // Only buffer up to ~64k.  Various logging bits truncate
12182            // things at 128k.
12183            needsFlush = (sb.length() > 64 * 1024);
12184        }
12185
12186        // Flush immediately if the buffer's grown too large, or this
12187        // is a non-system app.  Non-system apps are isolated with a
12188        // different tag & policy and not batched.
12189        //
12190        // Batching is useful during internal testing with
12191        // StrictMode settings turned up high.  Without batching,
12192        // thousands of separate files could be created on boot.
12193        if (!isSystemApp || needsFlush) {
12194            new Thread("Error dump: " + dropboxTag) {
12195                @Override
12196                public void run() {
12197                    String report;
12198                    synchronized (sb) {
12199                        report = sb.toString();
12200                        sb.delete(0, sb.length());
12201                        sb.trimToSize();
12202                    }
12203                    if (report.length() != 0) {
12204                        dbox.addText(dropboxTag, report);
12205                    }
12206                }
12207            }.start();
12208            return;
12209        }
12210
12211        // System app batching:
12212        if (!bufferWasEmpty) {
12213            // An existing dropbox-writing thread is outstanding, so
12214            // we don't need to start it up.  The existing thread will
12215            // catch the buffer appends we just did.
12216            return;
12217        }
12218
12219        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12220        // (After this point, we shouldn't access AMS internal data structures.)
12221        new Thread("Error dump: " + dropboxTag) {
12222            @Override
12223            public void run() {
12224                // 5 second sleep to let stacks arrive and be batched together
12225                try {
12226                    Thread.sleep(5000);  // 5 seconds
12227                } catch (InterruptedException e) {}
12228
12229                String errorReport;
12230                synchronized (mStrictModeBuffer) {
12231                    errorReport = mStrictModeBuffer.toString();
12232                    if (errorReport.length() == 0) {
12233                        return;
12234                    }
12235                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12236                    mStrictModeBuffer.trimToSize();
12237                }
12238                dbox.addText(dropboxTag, errorReport);
12239            }
12240        }.start();
12241    }
12242
12243    /**
12244     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12245     * @param app object of the crashing app, null for the system server
12246     * @param tag reported by the caller
12247     * @param system whether this wtf is coming from the system
12248     * @param crashInfo describing the context of the error
12249     * @return true if the process should exit immediately (WTF is fatal)
12250     */
12251    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12252            final ApplicationErrorReport.CrashInfo crashInfo) {
12253        final int callingUid = Binder.getCallingUid();
12254        final int callingPid = Binder.getCallingPid();
12255
12256        if (system) {
12257            // If this is coming from the system, we could very well have low-level
12258            // system locks held, so we want to do this all asynchronously.  And we
12259            // never want this to become fatal, so there is that too.
12260            mHandler.post(new Runnable() {
12261                @Override public void run() {
12262                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12263                }
12264            });
12265            return false;
12266        }
12267
12268        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12269                crashInfo);
12270
12271        if (r != null && r.pid != Process.myPid() &&
12272                Settings.Global.getInt(mContext.getContentResolver(),
12273                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12274            crashApplication(r, crashInfo);
12275            return true;
12276        } else {
12277            return false;
12278        }
12279    }
12280
12281    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12282            final ApplicationErrorReport.CrashInfo crashInfo) {
12283        final ProcessRecord r = findAppProcess(app, "WTF");
12284        final String processName = app == null ? "system_server"
12285                : (r == null ? "unknown" : r.processName);
12286
12287        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12288                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12289
12290        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12291
12292        return r;
12293    }
12294
12295    /**
12296     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12297     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12298     */
12299    private ProcessRecord findAppProcess(IBinder app, String reason) {
12300        if (app == null) {
12301            return null;
12302        }
12303
12304        synchronized (this) {
12305            final int NP = mProcessNames.getMap().size();
12306            for (int ip=0; ip<NP; ip++) {
12307                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12308                final int NA = apps.size();
12309                for (int ia=0; ia<NA; ia++) {
12310                    ProcessRecord p = apps.valueAt(ia);
12311                    if (p.thread != null && p.thread.asBinder() == app) {
12312                        return p;
12313                    }
12314                }
12315            }
12316
12317            Slog.w(TAG, "Can't find mystery application for " + reason
12318                    + " from pid=" + Binder.getCallingPid()
12319                    + " uid=" + Binder.getCallingUid() + ": " + app);
12320            return null;
12321        }
12322    }
12323
12324    /**
12325     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12326     * to append various headers to the dropbox log text.
12327     */
12328    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12329            StringBuilder sb) {
12330        // Watchdog thread ends up invoking this function (with
12331        // a null ProcessRecord) to add the stack file to dropbox.
12332        // Do not acquire a lock on this (am) in such cases, as it
12333        // could cause a potential deadlock, if and when watchdog
12334        // is invoked due to unavailability of lock on am and it
12335        // would prevent watchdog from killing system_server.
12336        if (process == null) {
12337            sb.append("Process: ").append(processName).append("\n");
12338            return;
12339        }
12340        // Note: ProcessRecord 'process' is guarded by the service
12341        // instance.  (notably process.pkgList, which could otherwise change
12342        // concurrently during execution of this method)
12343        synchronized (this) {
12344            sb.append("Process: ").append(processName).append("\n");
12345            int flags = process.info.flags;
12346            IPackageManager pm = AppGlobals.getPackageManager();
12347            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12348            for (int ip=0; ip<process.pkgList.size(); ip++) {
12349                String pkg = process.pkgList.keyAt(ip);
12350                sb.append("Package: ").append(pkg);
12351                try {
12352                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12353                    if (pi != null) {
12354                        sb.append(" v").append(pi.versionCode);
12355                        if (pi.versionName != null) {
12356                            sb.append(" (").append(pi.versionName).append(")");
12357                        }
12358                    }
12359                } catch (RemoteException e) {
12360                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12361                }
12362                sb.append("\n");
12363            }
12364        }
12365    }
12366
12367    private static String processClass(ProcessRecord process) {
12368        if (process == null || process.pid == MY_PID) {
12369            return "system_server";
12370        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12371            return "system_app";
12372        } else {
12373            return "data_app";
12374        }
12375    }
12376
12377    /**
12378     * Write a description of an error (crash, WTF, ANR) to the drop box.
12379     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12380     * @param process which caused the error, null means the system server
12381     * @param activity which triggered the error, null if unknown
12382     * @param parent activity related to the error, null if unknown
12383     * @param subject line related to the error, null if absent
12384     * @param report in long form describing the error, null if absent
12385     * @param logFile to include in the report, null if none
12386     * @param crashInfo giving an application stack trace, null if absent
12387     */
12388    public void addErrorToDropBox(String eventType,
12389            ProcessRecord process, String processName, ActivityRecord activity,
12390            ActivityRecord parent, String subject,
12391            final String report, final File logFile,
12392            final ApplicationErrorReport.CrashInfo crashInfo) {
12393        // NOTE -- this must never acquire the ActivityManagerService lock,
12394        // otherwise the watchdog may be prevented from resetting the system.
12395
12396        final String dropboxTag = processClass(process) + "_" + eventType;
12397        final DropBoxManager dbox = (DropBoxManager)
12398                mContext.getSystemService(Context.DROPBOX_SERVICE);
12399
12400        // Exit early if the dropbox isn't configured to accept this report type.
12401        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12402
12403        final StringBuilder sb = new StringBuilder(1024);
12404        appendDropBoxProcessHeaders(process, processName, sb);
12405        if (activity != null) {
12406            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12407        }
12408        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12409            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12410        }
12411        if (parent != null && parent != activity) {
12412            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12413        }
12414        if (subject != null) {
12415            sb.append("Subject: ").append(subject).append("\n");
12416        }
12417        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12418        if (Debug.isDebuggerConnected()) {
12419            sb.append("Debugger: Connected\n");
12420        }
12421        sb.append("\n");
12422
12423        // Do the rest in a worker thread to avoid blocking the caller on I/O
12424        // (After this point, we shouldn't access AMS internal data structures.)
12425        Thread worker = new Thread("Error dump: " + dropboxTag) {
12426            @Override
12427            public void run() {
12428                if (report != null) {
12429                    sb.append(report);
12430                }
12431                if (logFile != null) {
12432                    try {
12433                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12434                                    "\n\n[[TRUNCATED]]"));
12435                    } catch (IOException e) {
12436                        Slog.e(TAG, "Error reading " + logFile, e);
12437                    }
12438                }
12439                if (crashInfo != null && crashInfo.stackTrace != null) {
12440                    sb.append(crashInfo.stackTrace);
12441                }
12442
12443                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12444                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12445                if (lines > 0) {
12446                    sb.append("\n");
12447
12448                    // Merge several logcat streams, and take the last N lines
12449                    InputStreamReader input = null;
12450                    try {
12451                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12452                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12453                                "-b", "crash",
12454                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12455
12456                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12457                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12458                        input = new InputStreamReader(logcat.getInputStream());
12459
12460                        int num;
12461                        char[] buf = new char[8192];
12462                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12463                    } catch (IOException e) {
12464                        Slog.e(TAG, "Error running logcat", e);
12465                    } finally {
12466                        if (input != null) try { input.close(); } catch (IOException e) {}
12467                    }
12468                }
12469
12470                dbox.addText(dropboxTag, sb.toString());
12471            }
12472        };
12473
12474        if (process == null) {
12475            // If process is null, we are being called from some internal code
12476            // and may be about to die -- run this synchronously.
12477            worker.run();
12478        } else {
12479            worker.start();
12480        }
12481    }
12482
12483    /**
12484     * Bring up the "unexpected error" dialog box for a crashing app.
12485     * Deal with edge cases (intercepts from instrumented applications,
12486     * ActivityController, error intent receivers, that sort of thing).
12487     * @param r the application crashing
12488     * @param crashInfo describing the failure
12489     */
12490    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12491        long timeMillis = System.currentTimeMillis();
12492        String shortMsg = crashInfo.exceptionClassName;
12493        String longMsg = crashInfo.exceptionMessage;
12494        String stackTrace = crashInfo.stackTrace;
12495        if (shortMsg != null && longMsg != null) {
12496            longMsg = shortMsg + ": " + longMsg;
12497        } else if (shortMsg != null) {
12498            longMsg = shortMsg;
12499        }
12500
12501        AppErrorResult result = new AppErrorResult();
12502        synchronized (this) {
12503            if (mController != null) {
12504                try {
12505                    String name = r != null ? r.processName : null;
12506                    int pid = r != null ? r.pid : Binder.getCallingPid();
12507                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12508                    if (!mController.appCrashed(name, pid,
12509                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12510                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12511                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12512                            Slog.w(TAG, "Skip killing native crashed app " + name
12513                                    + "(" + pid + ") during testing");
12514                        } else {
12515                            Slog.w(TAG, "Force-killing crashed app " + name
12516                                    + " at watcher's request");
12517                            if (r != null) {
12518                                r.kill("crash", true);
12519                            } else {
12520                                // Huh.
12521                                Process.killProcess(pid);
12522                                killProcessGroup(uid, pid);
12523                            }
12524                        }
12525                        return;
12526                    }
12527                } catch (RemoteException e) {
12528                    mController = null;
12529                    Watchdog.getInstance().setActivityController(null);
12530                }
12531            }
12532
12533            final long origId = Binder.clearCallingIdentity();
12534
12535            // If this process is running instrumentation, finish it.
12536            if (r != null && r.instrumentationClass != null) {
12537                Slog.w(TAG, "Error in app " + r.processName
12538                      + " running instrumentation " + r.instrumentationClass + ":");
12539                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12540                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12541                Bundle info = new Bundle();
12542                info.putString("shortMsg", shortMsg);
12543                info.putString("longMsg", longMsg);
12544                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12545                Binder.restoreCallingIdentity(origId);
12546                return;
12547            }
12548
12549            // Log crash in battery stats.
12550            if (r != null) {
12551                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12552            }
12553
12554            // If we can't identify the process or it's already exceeded its crash quota,
12555            // quit right away without showing a crash dialog.
12556            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12557                Binder.restoreCallingIdentity(origId);
12558                return;
12559            }
12560
12561            Message msg = Message.obtain();
12562            msg.what = SHOW_ERROR_MSG;
12563            HashMap data = new HashMap();
12564            data.put("result", result);
12565            data.put("app", r);
12566            msg.obj = data;
12567            mUiHandler.sendMessage(msg);
12568
12569            Binder.restoreCallingIdentity(origId);
12570        }
12571
12572        int res = result.get();
12573
12574        Intent appErrorIntent = null;
12575        synchronized (this) {
12576            if (r != null && !r.isolated) {
12577                // XXX Can't keep track of crash time for isolated processes,
12578                // since they don't have a persistent identity.
12579                mProcessCrashTimes.put(r.info.processName, r.uid,
12580                        SystemClock.uptimeMillis());
12581            }
12582            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12583                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12584            }
12585        }
12586
12587        if (appErrorIntent != null) {
12588            try {
12589                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12590            } catch (ActivityNotFoundException e) {
12591                Slog.w(TAG, "bug report receiver dissappeared", e);
12592            }
12593        }
12594    }
12595
12596    Intent createAppErrorIntentLocked(ProcessRecord r,
12597            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12598        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12599        if (report == null) {
12600            return null;
12601        }
12602        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12603        result.setComponent(r.errorReportReceiver);
12604        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12605        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12606        return result;
12607    }
12608
12609    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12610            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12611        if (r.errorReportReceiver == null) {
12612            return null;
12613        }
12614
12615        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12616            return null;
12617        }
12618
12619        ApplicationErrorReport report = new ApplicationErrorReport();
12620        report.packageName = r.info.packageName;
12621        report.installerPackageName = r.errorReportReceiver.getPackageName();
12622        report.processName = r.processName;
12623        report.time = timeMillis;
12624        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12625
12626        if (r.crashing || r.forceCrashReport) {
12627            report.type = ApplicationErrorReport.TYPE_CRASH;
12628            report.crashInfo = crashInfo;
12629        } else if (r.notResponding) {
12630            report.type = ApplicationErrorReport.TYPE_ANR;
12631            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12632
12633            report.anrInfo.activity = r.notRespondingReport.tag;
12634            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12635            report.anrInfo.info = r.notRespondingReport.longMsg;
12636        }
12637
12638        return report;
12639    }
12640
12641    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12642        enforceNotIsolatedCaller("getProcessesInErrorState");
12643        // assume our apps are happy - lazy create the list
12644        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12645
12646        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12647                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12648        int userId = UserHandle.getUserId(Binder.getCallingUid());
12649
12650        synchronized (this) {
12651
12652            // iterate across all processes
12653            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12654                ProcessRecord app = mLruProcesses.get(i);
12655                if (!allUsers && app.userId != userId) {
12656                    continue;
12657                }
12658                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12659                    // This one's in trouble, so we'll generate a report for it
12660                    // crashes are higher priority (in case there's a crash *and* an anr)
12661                    ActivityManager.ProcessErrorStateInfo report = null;
12662                    if (app.crashing) {
12663                        report = app.crashingReport;
12664                    } else if (app.notResponding) {
12665                        report = app.notRespondingReport;
12666                    }
12667
12668                    if (report != null) {
12669                        if (errList == null) {
12670                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12671                        }
12672                        errList.add(report);
12673                    } else {
12674                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12675                                " crashing = " + app.crashing +
12676                                " notResponding = " + app.notResponding);
12677                    }
12678                }
12679            }
12680        }
12681
12682        return errList;
12683    }
12684
12685    static int procStateToImportance(int procState, int memAdj,
12686            ActivityManager.RunningAppProcessInfo currApp) {
12687        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12688        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12689            currApp.lru = memAdj;
12690        } else {
12691            currApp.lru = 0;
12692        }
12693        return imp;
12694    }
12695
12696    private void fillInProcMemInfo(ProcessRecord app,
12697            ActivityManager.RunningAppProcessInfo outInfo) {
12698        outInfo.pid = app.pid;
12699        outInfo.uid = app.info.uid;
12700        if (mHeavyWeightProcess == app) {
12701            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12702        }
12703        if (app.persistent) {
12704            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12705        }
12706        if (app.activities.size() > 0) {
12707            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12708        }
12709        outInfo.lastTrimLevel = app.trimMemoryLevel;
12710        int adj = app.curAdj;
12711        int procState = app.curProcState;
12712        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12713        outInfo.importanceReasonCode = app.adjTypeCode;
12714        outInfo.processState = app.curProcState;
12715    }
12716
12717    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12718        enforceNotIsolatedCaller("getRunningAppProcesses");
12719
12720        final int callingUid = Binder.getCallingUid();
12721
12722        // Lazy instantiation of list
12723        List<ActivityManager.RunningAppProcessInfo> runList = null;
12724        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12725                callingUid) == PackageManager.PERMISSION_GRANTED;
12726        final int userId = UserHandle.getUserId(callingUid);
12727        final boolean allUids = isGetTasksAllowed(
12728                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12729
12730        synchronized (this) {
12731            // Iterate across all processes
12732            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12733                ProcessRecord app = mLruProcesses.get(i);
12734                if ((!allUsers && app.userId != userId)
12735                        || (!allUids && app.uid != callingUid)) {
12736                    continue;
12737                }
12738                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12739                    // Generate process state info for running application
12740                    ActivityManager.RunningAppProcessInfo currApp =
12741                        new ActivityManager.RunningAppProcessInfo(app.processName,
12742                                app.pid, app.getPackageList());
12743                    fillInProcMemInfo(app, currApp);
12744                    if (app.adjSource instanceof ProcessRecord) {
12745                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12746                        currApp.importanceReasonImportance =
12747                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12748                                        app.adjSourceProcState);
12749                    } else if (app.adjSource instanceof ActivityRecord) {
12750                        ActivityRecord r = (ActivityRecord)app.adjSource;
12751                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12752                    }
12753                    if (app.adjTarget instanceof ComponentName) {
12754                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12755                    }
12756                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12757                    //        + " lru=" + currApp.lru);
12758                    if (runList == null) {
12759                        runList = new ArrayList<>();
12760                    }
12761                    runList.add(currApp);
12762                }
12763            }
12764        }
12765        return runList;
12766    }
12767
12768    public List<ApplicationInfo> getRunningExternalApplications() {
12769        enforceNotIsolatedCaller("getRunningExternalApplications");
12770        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12771        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12772        if (runningApps != null && runningApps.size() > 0) {
12773            Set<String> extList = new HashSet<String>();
12774            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12775                if (app.pkgList != null) {
12776                    for (String pkg : app.pkgList) {
12777                        extList.add(pkg);
12778                    }
12779                }
12780            }
12781            IPackageManager pm = AppGlobals.getPackageManager();
12782            for (String pkg : extList) {
12783                try {
12784                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12785                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12786                        retList.add(info);
12787                    }
12788                } catch (RemoteException e) {
12789                }
12790            }
12791        }
12792        return retList;
12793    }
12794
12795    @Override
12796    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12797        enforceNotIsolatedCaller("getMyMemoryState");
12798        synchronized (this) {
12799            ProcessRecord proc;
12800            synchronized (mPidsSelfLocked) {
12801                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12802            }
12803            fillInProcMemInfo(proc, outInfo);
12804        }
12805    }
12806
12807    @Override
12808    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12809        if (checkCallingPermission(android.Manifest.permission.DUMP)
12810                != PackageManager.PERMISSION_GRANTED) {
12811            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12812                    + Binder.getCallingPid()
12813                    + ", uid=" + Binder.getCallingUid()
12814                    + " without permission "
12815                    + android.Manifest.permission.DUMP);
12816            return;
12817        }
12818
12819        boolean dumpAll = false;
12820        boolean dumpClient = false;
12821        String dumpPackage = null;
12822
12823        int opti = 0;
12824        while (opti < args.length) {
12825            String opt = args[opti];
12826            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12827                break;
12828            }
12829            opti++;
12830            if ("-a".equals(opt)) {
12831                dumpAll = true;
12832            } else if ("-c".equals(opt)) {
12833                dumpClient = true;
12834            } else if ("-p".equals(opt)) {
12835                if (opti < args.length) {
12836                    dumpPackage = args[opti];
12837                    opti++;
12838                } else {
12839                    pw.println("Error: -p option requires package argument");
12840                    return;
12841                }
12842                dumpClient = true;
12843            } else if ("-h".equals(opt)) {
12844                pw.println("Activity manager dump options:");
12845                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12846                pw.println("  cmd may be one of:");
12847                pw.println("    a[ctivities]: activity stack state");
12848                pw.println("    r[recents]: recent activities state");
12849                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12850                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12851                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12852                pw.println("    o[om]: out of memory management");
12853                pw.println("    perm[issions]: URI permission grant state");
12854                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12855                pw.println("    provider [COMP_SPEC]: provider client-side state");
12856                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12857                pw.println("    as[sociations]: tracked app associations");
12858                pw.println("    service [COMP_SPEC]: service client-side state");
12859                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12860                pw.println("    all: dump all activities");
12861                pw.println("    top: dump the top activity");
12862                pw.println("    write: write all pending state to storage");
12863                pw.println("    track-associations: enable association tracking");
12864                pw.println("    untrack-associations: disable and clear association tracking");
12865                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12866                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12867                pw.println("    a partial substring in a component name, a");
12868                pw.println("    hex object identifier.");
12869                pw.println("  -a: include all available server state.");
12870                pw.println("  -c: include client state.");
12871                pw.println("  -p: limit output to given package.");
12872                return;
12873            } else {
12874                pw.println("Unknown argument: " + opt + "; use -h for help");
12875            }
12876        }
12877
12878        long origId = Binder.clearCallingIdentity();
12879        boolean more = false;
12880        // Is the caller requesting to dump a particular piece of data?
12881        if (opti < args.length) {
12882            String cmd = args[opti];
12883            opti++;
12884            if ("activities".equals(cmd) || "a".equals(cmd)) {
12885                synchronized (this) {
12886                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12887                }
12888            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12889                synchronized (this) {
12890                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12891                }
12892            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12893                String[] newArgs;
12894                String name;
12895                if (opti >= args.length) {
12896                    name = null;
12897                    newArgs = EMPTY_STRING_ARRAY;
12898                } else {
12899                    dumpPackage = args[opti];
12900                    opti++;
12901                    newArgs = new String[args.length - opti];
12902                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12903                            args.length - opti);
12904                }
12905                synchronized (this) {
12906                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12907                }
12908            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12909                String[] newArgs;
12910                String name;
12911                if (opti >= args.length) {
12912                    name = null;
12913                    newArgs = EMPTY_STRING_ARRAY;
12914                } else {
12915                    dumpPackage = args[opti];
12916                    opti++;
12917                    newArgs = new String[args.length - opti];
12918                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12919                            args.length - opti);
12920                }
12921                synchronized (this) {
12922                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12923                }
12924            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12925                String[] newArgs;
12926                String name;
12927                if (opti >= args.length) {
12928                    name = null;
12929                    newArgs = EMPTY_STRING_ARRAY;
12930                } else {
12931                    dumpPackage = args[opti];
12932                    opti++;
12933                    newArgs = new String[args.length - opti];
12934                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12935                            args.length - opti);
12936                }
12937                synchronized (this) {
12938                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12939                }
12940            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12941                synchronized (this) {
12942                    dumpOomLocked(fd, pw, args, opti, true);
12943                }
12944            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
12945                synchronized (this) {
12946                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
12947                }
12948            } else if ("provider".equals(cmd)) {
12949                String[] newArgs;
12950                String name;
12951                if (opti >= args.length) {
12952                    name = null;
12953                    newArgs = EMPTY_STRING_ARRAY;
12954                } else {
12955                    name = args[opti];
12956                    opti++;
12957                    newArgs = new String[args.length - opti];
12958                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12959                }
12960                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12961                    pw.println("No providers match: " + name);
12962                    pw.println("Use -h for help.");
12963                }
12964            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12965                synchronized (this) {
12966                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12967                }
12968            } else if ("service".equals(cmd)) {
12969                String[] newArgs;
12970                String name;
12971                if (opti >= args.length) {
12972                    name = null;
12973                    newArgs = EMPTY_STRING_ARRAY;
12974                } else {
12975                    name = args[opti];
12976                    opti++;
12977                    newArgs = new String[args.length - opti];
12978                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12979                            args.length - opti);
12980                }
12981                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12982                    pw.println("No services match: " + name);
12983                    pw.println("Use -h for help.");
12984                }
12985            } else if ("package".equals(cmd)) {
12986                String[] newArgs;
12987                if (opti >= args.length) {
12988                    pw.println("package: no package name specified");
12989                    pw.println("Use -h for help.");
12990                } else {
12991                    dumpPackage = args[opti];
12992                    opti++;
12993                    newArgs = new String[args.length - opti];
12994                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12995                            args.length - opti);
12996                    args = newArgs;
12997                    opti = 0;
12998                    more = true;
12999                }
13000            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13001                synchronized (this) {
13002                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13003                }
13004            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13005                synchronized (this) {
13006                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13007                }
13008            } else if ("write".equals(cmd)) {
13009                mTaskPersister.flush();
13010                pw.println("All tasks persisted.");
13011                return;
13012            } else if ("track-associations".equals(cmd)) {
13013                synchronized (this) {
13014                    if (!mTrackingAssociations) {
13015                        mTrackingAssociations = true;
13016                        pw.println("Association tracking started.");
13017                    } else {
13018                        pw.println("Association tracking already enabled.");
13019                    }
13020                }
13021                return;
13022            } else if ("untrack-associations".equals(cmd)) {
13023                synchronized (this) {
13024                    if (mTrackingAssociations) {
13025                        mTrackingAssociations = false;
13026                        mAssociations.clear();
13027                        pw.println("Association tracking stopped.");
13028                    } else {
13029                        pw.println("Association tracking not running.");
13030                    }
13031                }
13032                return;
13033            } else {
13034                // Dumping a single activity?
13035                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13036                    pw.println("Bad activity command, or no activities match: " + cmd);
13037                    pw.println("Use -h for help.");
13038                }
13039            }
13040            if (!more) {
13041                Binder.restoreCallingIdentity(origId);
13042                return;
13043            }
13044        }
13045
13046        // No piece of data specified, dump everything.
13047        synchronized (this) {
13048            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13049            pw.println();
13050            if (dumpAll) {
13051                pw.println("-------------------------------------------------------------------------------");
13052            }
13053            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13054            pw.println();
13055            if (dumpAll) {
13056                pw.println("-------------------------------------------------------------------------------");
13057            }
13058            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13059            pw.println();
13060            if (dumpAll) {
13061                pw.println("-------------------------------------------------------------------------------");
13062            }
13063            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13064            pw.println();
13065            if (dumpAll) {
13066                pw.println("-------------------------------------------------------------------------------");
13067            }
13068            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13069            pw.println();
13070            if (dumpAll) {
13071                pw.println("-------------------------------------------------------------------------------");
13072            }
13073            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13074            pw.println();
13075            if (dumpAll) {
13076                pw.println("-------------------------------------------------------------------------------");
13077            }
13078            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13079            if (mAssociations.size() > 0) {
13080                pw.println();
13081                if (dumpAll) {
13082                    pw.println("-------------------------------------------------------------------------------");
13083                }
13084                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13085            }
13086            pw.println();
13087            if (dumpAll) {
13088                pw.println("-------------------------------------------------------------------------------");
13089            }
13090            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13091        }
13092        Binder.restoreCallingIdentity(origId);
13093    }
13094
13095    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13096            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13097        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13098
13099        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13100                dumpPackage);
13101        boolean needSep = printedAnything;
13102
13103        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13104                dumpPackage, needSep, "  mFocusedActivity: ");
13105        if (printed) {
13106            printedAnything = true;
13107            needSep = false;
13108        }
13109
13110        if (dumpPackage == null) {
13111            if (needSep) {
13112                pw.println();
13113            }
13114            needSep = true;
13115            printedAnything = true;
13116            mStackSupervisor.dump(pw, "  ");
13117        }
13118
13119        if (!printedAnything) {
13120            pw.println("  (nothing)");
13121        }
13122    }
13123
13124    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13125            int opti, boolean dumpAll, String dumpPackage) {
13126        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13127
13128        boolean printedAnything = false;
13129
13130        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13131            boolean printedHeader = false;
13132
13133            final int N = mRecentTasks.size();
13134            for (int i=0; i<N; i++) {
13135                TaskRecord tr = mRecentTasks.get(i);
13136                if (dumpPackage != null) {
13137                    if (tr.realActivity == null ||
13138                            !dumpPackage.equals(tr.realActivity)) {
13139                        continue;
13140                    }
13141                }
13142                if (!printedHeader) {
13143                    pw.println("  Recent tasks:");
13144                    printedHeader = true;
13145                    printedAnything = true;
13146                }
13147                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13148                        pw.println(tr);
13149                if (dumpAll) {
13150                    mRecentTasks.get(i).dump(pw, "    ");
13151                }
13152            }
13153        }
13154
13155        if (!printedAnything) {
13156            pw.println("  (nothing)");
13157        }
13158    }
13159
13160    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13161            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13162        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13163
13164        int dumpUid = 0;
13165        if (dumpPackage != null) {
13166            IPackageManager pm = AppGlobals.getPackageManager();
13167            try {
13168                dumpUid = pm.getPackageUid(dumpPackage, 0);
13169            } catch (RemoteException e) {
13170            }
13171        }
13172
13173        boolean printedAnything = false;
13174
13175        final long now = SystemClock.uptimeMillis();
13176
13177        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13178            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13179                    = mAssociations.valueAt(i1);
13180            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13181                SparseArray<ArrayMap<String, Association>> sourceUids
13182                        = targetComponents.valueAt(i2);
13183                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13184                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13185                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13186                        Association ass = sourceProcesses.valueAt(i4);
13187                        if (dumpPackage != null) {
13188                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13189                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13190                                continue;
13191                            }
13192                        }
13193                        printedAnything = true;
13194                        pw.print("  ");
13195                        pw.print(ass.mTargetProcess);
13196                        pw.print("/");
13197                        UserHandle.formatUid(pw, ass.mTargetUid);
13198                        pw.print(" <- ");
13199                        pw.print(ass.mSourceProcess);
13200                        pw.print("/");
13201                        UserHandle.formatUid(pw, ass.mSourceUid);
13202                        pw.println();
13203                        pw.print("    via ");
13204                        pw.print(ass.mTargetComponent.flattenToShortString());
13205                        pw.println();
13206                        pw.print("    ");
13207                        long dur = ass.mTime;
13208                        if (ass.mNesting > 0) {
13209                            dur += now - ass.mStartTime;
13210                        }
13211                        TimeUtils.formatDuration(dur, pw);
13212                        pw.print(" (");
13213                        pw.print(ass.mCount);
13214                        pw.println(" times)");
13215                        if (ass.mNesting > 0) {
13216                            pw.print("    ");
13217                            pw.print(" Currently active: ");
13218                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13219                            pw.println();
13220                        }
13221                    }
13222                }
13223            }
13224
13225        }
13226
13227        if (!printedAnything) {
13228            pw.println("  (nothing)");
13229        }
13230    }
13231
13232    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13233            int opti, boolean dumpAll, String dumpPackage) {
13234        boolean needSep = false;
13235        boolean printedAnything = false;
13236        int numPers = 0;
13237
13238        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13239
13240        if (dumpAll) {
13241            final int NP = mProcessNames.getMap().size();
13242            for (int ip=0; ip<NP; ip++) {
13243                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13244                final int NA = procs.size();
13245                for (int ia=0; ia<NA; ia++) {
13246                    ProcessRecord r = procs.valueAt(ia);
13247                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13248                        continue;
13249                    }
13250                    if (!needSep) {
13251                        pw.println("  All known processes:");
13252                        needSep = true;
13253                        printedAnything = true;
13254                    }
13255                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13256                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13257                        pw.print(" "); pw.println(r);
13258                    r.dump(pw, "    ");
13259                    if (r.persistent) {
13260                        numPers++;
13261                    }
13262                }
13263            }
13264        }
13265
13266        if (mIsolatedProcesses.size() > 0) {
13267            boolean printed = false;
13268            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13269                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13270                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13271                    continue;
13272                }
13273                if (!printed) {
13274                    if (needSep) {
13275                        pw.println();
13276                    }
13277                    pw.println("  Isolated process list (sorted by uid):");
13278                    printedAnything = true;
13279                    printed = true;
13280                    needSep = true;
13281                }
13282                pw.println(String.format("%sIsolated #%2d: %s",
13283                        "    ", i, r.toString()));
13284            }
13285        }
13286
13287        if (mActiveUids.size() > 0) {
13288            if (needSep) {
13289                pw.println();
13290            }
13291            pw.println("  UID states:");
13292            for (int i=0; i<mActiveUids.size(); i++) {
13293                UidRecord uidRec = mActiveUids.valueAt(i);
13294                pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13295                pw.print(": "); pw.println(uidRec);
13296            }
13297            needSep = true;
13298            printedAnything = true;
13299        }
13300
13301        if (mLruProcesses.size() > 0) {
13302            if (needSep) {
13303                pw.println();
13304            }
13305            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13306                    pw.print(" total, non-act at ");
13307                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13308                    pw.print(", non-svc at ");
13309                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13310                    pw.println("):");
13311            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13312            needSep = true;
13313            printedAnything = true;
13314        }
13315
13316        if (dumpAll || dumpPackage != null) {
13317            synchronized (mPidsSelfLocked) {
13318                boolean printed = false;
13319                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13320                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13321                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13322                        continue;
13323                    }
13324                    if (!printed) {
13325                        if (needSep) pw.println();
13326                        needSep = true;
13327                        pw.println("  PID mappings:");
13328                        printed = true;
13329                        printedAnything = true;
13330                    }
13331                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13332                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13333                }
13334            }
13335        }
13336
13337        if (mForegroundProcesses.size() > 0) {
13338            synchronized (mPidsSelfLocked) {
13339                boolean printed = false;
13340                for (int i=0; i<mForegroundProcesses.size(); i++) {
13341                    ProcessRecord r = mPidsSelfLocked.get(
13342                            mForegroundProcesses.valueAt(i).pid);
13343                    if (dumpPackage != null && (r == null
13344                            || !r.pkgList.containsKey(dumpPackage))) {
13345                        continue;
13346                    }
13347                    if (!printed) {
13348                        if (needSep) pw.println();
13349                        needSep = true;
13350                        pw.println("  Foreground Processes:");
13351                        printed = true;
13352                        printedAnything = true;
13353                    }
13354                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13355                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13356                }
13357            }
13358        }
13359
13360        if (mPersistentStartingProcesses.size() > 0) {
13361            if (needSep) pw.println();
13362            needSep = true;
13363            printedAnything = true;
13364            pw.println("  Persisent processes that are starting:");
13365            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13366                    "Starting Norm", "Restarting PERS", dumpPackage);
13367        }
13368
13369        if (mRemovedProcesses.size() > 0) {
13370            if (needSep) pw.println();
13371            needSep = true;
13372            printedAnything = true;
13373            pw.println("  Processes that are being removed:");
13374            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13375                    "Removed Norm", "Removed PERS", dumpPackage);
13376        }
13377
13378        if (mProcessesOnHold.size() > 0) {
13379            if (needSep) pw.println();
13380            needSep = true;
13381            printedAnything = true;
13382            pw.println("  Processes that are on old until the system is ready:");
13383            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13384                    "OnHold Norm", "OnHold PERS", dumpPackage);
13385        }
13386
13387        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13388
13389        if (mProcessCrashTimes.getMap().size() > 0) {
13390            boolean printed = false;
13391            long now = SystemClock.uptimeMillis();
13392            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13393            final int NP = pmap.size();
13394            for (int ip=0; ip<NP; ip++) {
13395                String pname = pmap.keyAt(ip);
13396                SparseArray<Long> uids = pmap.valueAt(ip);
13397                final int N = uids.size();
13398                for (int i=0; i<N; i++) {
13399                    int puid = uids.keyAt(i);
13400                    ProcessRecord r = mProcessNames.get(pname, puid);
13401                    if (dumpPackage != null && (r == null
13402                            || !r.pkgList.containsKey(dumpPackage))) {
13403                        continue;
13404                    }
13405                    if (!printed) {
13406                        if (needSep) pw.println();
13407                        needSep = true;
13408                        pw.println("  Time since processes crashed:");
13409                        printed = true;
13410                        printedAnything = true;
13411                    }
13412                    pw.print("    Process "); pw.print(pname);
13413                            pw.print(" uid "); pw.print(puid);
13414                            pw.print(": last crashed ");
13415                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13416                            pw.println(" ago");
13417                }
13418            }
13419        }
13420
13421        if (mBadProcesses.getMap().size() > 0) {
13422            boolean printed = false;
13423            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13424            final int NP = pmap.size();
13425            for (int ip=0; ip<NP; ip++) {
13426                String pname = pmap.keyAt(ip);
13427                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13428                final int N = uids.size();
13429                for (int i=0; i<N; i++) {
13430                    int puid = uids.keyAt(i);
13431                    ProcessRecord r = mProcessNames.get(pname, puid);
13432                    if (dumpPackage != null && (r == null
13433                            || !r.pkgList.containsKey(dumpPackage))) {
13434                        continue;
13435                    }
13436                    if (!printed) {
13437                        if (needSep) pw.println();
13438                        needSep = true;
13439                        pw.println("  Bad processes:");
13440                        printedAnything = true;
13441                    }
13442                    BadProcessInfo info = uids.valueAt(i);
13443                    pw.print("    Bad process "); pw.print(pname);
13444                            pw.print(" uid "); pw.print(puid);
13445                            pw.print(": crashed at time "); pw.println(info.time);
13446                    if (info.shortMsg != null) {
13447                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13448                    }
13449                    if (info.longMsg != null) {
13450                        pw.print("      Long msg: "); pw.println(info.longMsg);
13451                    }
13452                    if (info.stack != null) {
13453                        pw.println("      Stack:");
13454                        int lastPos = 0;
13455                        for (int pos=0; pos<info.stack.length(); pos++) {
13456                            if (info.stack.charAt(pos) == '\n') {
13457                                pw.print("        ");
13458                                pw.write(info.stack, lastPos, pos-lastPos);
13459                                pw.println();
13460                                lastPos = pos+1;
13461                            }
13462                        }
13463                        if (lastPos < info.stack.length()) {
13464                            pw.print("        ");
13465                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13466                            pw.println();
13467                        }
13468                    }
13469                }
13470            }
13471        }
13472
13473        if (dumpPackage == null) {
13474            pw.println();
13475            needSep = false;
13476            pw.println("  mStartedUsers:");
13477            for (int i=0; i<mStartedUsers.size(); i++) {
13478                UserState uss = mStartedUsers.valueAt(i);
13479                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13480                        pw.print(": "); uss.dump("", pw);
13481            }
13482            pw.print("  mStartedUserArray: [");
13483            for (int i=0; i<mStartedUserArray.length; i++) {
13484                if (i > 0) pw.print(", ");
13485                pw.print(mStartedUserArray[i]);
13486            }
13487            pw.println("]");
13488            pw.print("  mUserLru: [");
13489            for (int i=0; i<mUserLru.size(); i++) {
13490                if (i > 0) pw.print(", ");
13491                pw.print(mUserLru.get(i));
13492            }
13493            pw.println("]");
13494            if (dumpAll) {
13495                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13496            }
13497            synchronized (mUserProfileGroupIdsSelfLocked) {
13498                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13499                    pw.println("  mUserProfileGroupIds:");
13500                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13501                        pw.print("    User #");
13502                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13503                        pw.print(" -> profile #");
13504                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13505                    }
13506                }
13507            }
13508        }
13509        if (mHomeProcess != null && (dumpPackage == null
13510                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13511            if (needSep) {
13512                pw.println();
13513                needSep = false;
13514            }
13515            pw.println("  mHomeProcess: " + mHomeProcess);
13516        }
13517        if (mPreviousProcess != null && (dumpPackage == null
13518                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13519            if (needSep) {
13520                pw.println();
13521                needSep = false;
13522            }
13523            pw.println("  mPreviousProcess: " + mPreviousProcess);
13524        }
13525        if (dumpAll) {
13526            StringBuilder sb = new StringBuilder(128);
13527            sb.append("  mPreviousProcessVisibleTime: ");
13528            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13529            pw.println(sb);
13530        }
13531        if (mHeavyWeightProcess != null && (dumpPackage == null
13532                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13533            if (needSep) {
13534                pw.println();
13535                needSep = false;
13536            }
13537            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13538        }
13539        if (dumpPackage == null) {
13540            pw.println("  mConfiguration: " + mConfiguration);
13541        }
13542        if (dumpAll) {
13543            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13544            if (mCompatModePackages.getPackages().size() > 0) {
13545                boolean printed = false;
13546                for (Map.Entry<String, Integer> entry
13547                        : mCompatModePackages.getPackages().entrySet()) {
13548                    String pkg = entry.getKey();
13549                    int mode = entry.getValue();
13550                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13551                        continue;
13552                    }
13553                    if (!printed) {
13554                        pw.println("  mScreenCompatPackages:");
13555                        printed = true;
13556                    }
13557                    pw.print("    "); pw.print(pkg); pw.print(": ");
13558                            pw.print(mode); pw.println();
13559                }
13560            }
13561        }
13562        if (dumpPackage == null) {
13563            pw.println("  mWakefulness="
13564                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13565            pw.println("  mSleepTokens=" + mSleepTokens);
13566            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13567                    + lockScreenShownToString());
13568            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13569            if (mRunningVoice != null) {
13570                pw.println("  mRunningVoice=" + mRunningVoice);
13571                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13572            }
13573        }
13574        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13575                || mOrigWaitForDebugger) {
13576            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13577                    || dumpPackage.equals(mOrigDebugApp)) {
13578                if (needSep) {
13579                    pw.println();
13580                    needSep = false;
13581                }
13582                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13583                        + " mDebugTransient=" + mDebugTransient
13584                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13585            }
13586        }
13587        if (mCurAppTimeTracker != null) {
13588            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13589        }
13590        if (mMemWatchProcesses.getMap().size() > 0) {
13591            pw.println("  Mem watch processes:");
13592            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13593                    = mMemWatchProcesses.getMap();
13594            for (int i=0; i<procs.size(); i++) {
13595                final String proc = procs.keyAt(i);
13596                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13597                for (int j=0; j<uids.size(); j++) {
13598                    if (needSep) {
13599                        pw.println();
13600                        needSep = false;
13601                    }
13602                    StringBuilder sb = new StringBuilder();
13603                    sb.append("    ").append(proc).append('/');
13604                    UserHandle.formatUid(sb, uids.keyAt(j));
13605                    Pair<Long, String> val = uids.valueAt(j);
13606                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13607                    if (val.second != null) {
13608                        sb.append(", report to ").append(val.second);
13609                    }
13610                    pw.println(sb.toString());
13611                }
13612            }
13613            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13614            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13615            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13616                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13617        }
13618        if (mOpenGlTraceApp != null) {
13619            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13620                if (needSep) {
13621                    pw.println();
13622                    needSep = false;
13623                }
13624                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13625            }
13626        }
13627        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13628                || mProfileFd != null) {
13629            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13630                if (needSep) {
13631                    pw.println();
13632                    needSep = false;
13633                }
13634                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13635                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13636                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13637                        + mAutoStopProfiler);
13638                pw.println("  mProfileType=" + mProfileType);
13639            }
13640        }
13641        if (dumpPackage == null) {
13642            if (mAlwaysFinishActivities || mController != null) {
13643                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13644                        + " mController=" + mController);
13645            }
13646            if (dumpAll) {
13647                pw.println("  Total persistent processes: " + numPers);
13648                pw.println("  mProcessesReady=" + mProcessesReady
13649                        + " mSystemReady=" + mSystemReady
13650                        + " mBooted=" + mBooted
13651                        + " mFactoryTest=" + mFactoryTest);
13652                pw.println("  mBooting=" + mBooting
13653                        + " mCallFinishBooting=" + mCallFinishBooting
13654                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13655                pw.print("  mLastPowerCheckRealtime=");
13656                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13657                        pw.println("");
13658                pw.print("  mLastPowerCheckUptime=");
13659                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13660                        pw.println("");
13661                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13662                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13663                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13664                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13665                        + " (" + mLruProcesses.size() + " total)"
13666                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13667                        + " mNumServiceProcs=" + mNumServiceProcs
13668                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13669                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13670                        + " mLastMemoryLevel" + mLastMemoryLevel
13671                        + " mLastNumProcesses" + mLastNumProcesses);
13672                long now = SystemClock.uptimeMillis();
13673                pw.print("  mLastIdleTime=");
13674                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13675                        pw.print(" mLowRamSinceLastIdle=");
13676                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13677                        pw.println();
13678            }
13679        }
13680
13681        if (!printedAnything) {
13682            pw.println("  (nothing)");
13683        }
13684    }
13685
13686    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13687            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13688        if (mProcessesToGc.size() > 0) {
13689            boolean printed = false;
13690            long now = SystemClock.uptimeMillis();
13691            for (int i=0; i<mProcessesToGc.size(); i++) {
13692                ProcessRecord proc = mProcessesToGc.get(i);
13693                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13694                    continue;
13695                }
13696                if (!printed) {
13697                    if (needSep) pw.println();
13698                    needSep = true;
13699                    pw.println("  Processes that are waiting to GC:");
13700                    printed = true;
13701                }
13702                pw.print("    Process "); pw.println(proc);
13703                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13704                        pw.print(", last gced=");
13705                        pw.print(now-proc.lastRequestedGc);
13706                        pw.print(" ms ago, last lowMem=");
13707                        pw.print(now-proc.lastLowMemory);
13708                        pw.println(" ms ago");
13709
13710            }
13711        }
13712        return needSep;
13713    }
13714
13715    void printOomLevel(PrintWriter pw, String name, int adj) {
13716        pw.print("    ");
13717        if (adj >= 0) {
13718            pw.print(' ');
13719            if (adj < 10) pw.print(' ');
13720        } else {
13721            if (adj > -10) pw.print(' ');
13722        }
13723        pw.print(adj);
13724        pw.print(": ");
13725        pw.print(name);
13726        pw.print(" (");
13727        pw.print(mProcessList.getMemLevel(adj)/1024);
13728        pw.println(" kB)");
13729    }
13730
13731    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13732            int opti, boolean dumpAll) {
13733        boolean needSep = false;
13734
13735        if (mLruProcesses.size() > 0) {
13736            if (needSep) pw.println();
13737            needSep = true;
13738            pw.println("  OOM levels:");
13739            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13740            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13741            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13742            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13743            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13744            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13745            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13746            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13747            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13748            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13749            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13750            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13751            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13752            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13753
13754            if (needSep) pw.println();
13755            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13756                    pw.print(" total, non-act at ");
13757                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13758                    pw.print(", non-svc at ");
13759                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13760                    pw.println("):");
13761            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13762            needSep = true;
13763        }
13764
13765        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13766
13767        pw.println();
13768        pw.println("  mHomeProcess: " + mHomeProcess);
13769        pw.println("  mPreviousProcess: " + mPreviousProcess);
13770        if (mHeavyWeightProcess != null) {
13771            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13772        }
13773
13774        return true;
13775    }
13776
13777    /**
13778     * There are three ways to call this:
13779     *  - no provider specified: dump all the providers
13780     *  - a flattened component name that matched an existing provider was specified as the
13781     *    first arg: dump that one provider
13782     *  - the first arg isn't the flattened component name of an existing provider:
13783     *    dump all providers whose component contains the first arg as a substring
13784     */
13785    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13786            int opti, boolean dumpAll) {
13787        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13788    }
13789
13790    static class ItemMatcher {
13791        ArrayList<ComponentName> components;
13792        ArrayList<String> strings;
13793        ArrayList<Integer> objects;
13794        boolean all;
13795
13796        ItemMatcher() {
13797            all = true;
13798        }
13799
13800        void build(String name) {
13801            ComponentName componentName = ComponentName.unflattenFromString(name);
13802            if (componentName != null) {
13803                if (components == null) {
13804                    components = new ArrayList<ComponentName>();
13805                }
13806                components.add(componentName);
13807                all = false;
13808            } else {
13809                int objectId = 0;
13810                // Not a '/' separated full component name; maybe an object ID?
13811                try {
13812                    objectId = Integer.parseInt(name, 16);
13813                    if (objects == null) {
13814                        objects = new ArrayList<Integer>();
13815                    }
13816                    objects.add(objectId);
13817                    all = false;
13818                } catch (RuntimeException e) {
13819                    // Not an integer; just do string match.
13820                    if (strings == null) {
13821                        strings = new ArrayList<String>();
13822                    }
13823                    strings.add(name);
13824                    all = false;
13825                }
13826            }
13827        }
13828
13829        int build(String[] args, int opti) {
13830            for (; opti<args.length; opti++) {
13831                String name = args[opti];
13832                if ("--".equals(name)) {
13833                    return opti+1;
13834                }
13835                build(name);
13836            }
13837            return opti;
13838        }
13839
13840        boolean match(Object object, ComponentName comp) {
13841            if (all) {
13842                return true;
13843            }
13844            if (components != null) {
13845                for (int i=0; i<components.size(); i++) {
13846                    if (components.get(i).equals(comp)) {
13847                        return true;
13848                    }
13849                }
13850            }
13851            if (objects != null) {
13852                for (int i=0; i<objects.size(); i++) {
13853                    if (System.identityHashCode(object) == objects.get(i)) {
13854                        return true;
13855                    }
13856                }
13857            }
13858            if (strings != null) {
13859                String flat = comp.flattenToString();
13860                for (int i=0; i<strings.size(); i++) {
13861                    if (flat.contains(strings.get(i))) {
13862                        return true;
13863                    }
13864                }
13865            }
13866            return false;
13867        }
13868    }
13869
13870    /**
13871     * There are three things that cmd can be:
13872     *  - a flattened component name that matches an existing activity
13873     *  - the cmd arg isn't the flattened component name of an existing activity:
13874     *    dump all activity whose component contains the cmd as a substring
13875     *  - A hex number of the ActivityRecord object instance.
13876     */
13877    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13878            int opti, boolean dumpAll) {
13879        ArrayList<ActivityRecord> activities;
13880
13881        synchronized (this) {
13882            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13883        }
13884
13885        if (activities.size() <= 0) {
13886            return false;
13887        }
13888
13889        String[] newArgs = new String[args.length - opti];
13890        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13891
13892        TaskRecord lastTask = null;
13893        boolean needSep = false;
13894        for (int i=activities.size()-1; i>=0; i--) {
13895            ActivityRecord r = activities.get(i);
13896            if (needSep) {
13897                pw.println();
13898            }
13899            needSep = true;
13900            synchronized (this) {
13901                if (lastTask != r.task) {
13902                    lastTask = r.task;
13903                    pw.print("TASK "); pw.print(lastTask.affinity);
13904                            pw.print(" id="); pw.println(lastTask.taskId);
13905                    if (dumpAll) {
13906                        lastTask.dump(pw, "  ");
13907                    }
13908                }
13909            }
13910            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13911        }
13912        return true;
13913    }
13914
13915    /**
13916     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13917     * there is a thread associated with the activity.
13918     */
13919    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13920            final ActivityRecord r, String[] args, boolean dumpAll) {
13921        String innerPrefix = prefix + "  ";
13922        synchronized (this) {
13923            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13924                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13925                    pw.print(" pid=");
13926                    if (r.app != null) pw.println(r.app.pid);
13927                    else pw.println("(not running)");
13928            if (dumpAll) {
13929                r.dump(pw, innerPrefix);
13930            }
13931        }
13932        if (r.app != null && r.app.thread != null) {
13933            // flush anything that is already in the PrintWriter since the thread is going
13934            // to write to the file descriptor directly
13935            pw.flush();
13936            try {
13937                TransferPipe tp = new TransferPipe();
13938                try {
13939                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13940                            r.appToken, innerPrefix, args);
13941                    tp.go(fd);
13942                } finally {
13943                    tp.kill();
13944                }
13945            } catch (IOException e) {
13946                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13947            } catch (RemoteException e) {
13948                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13949            }
13950        }
13951    }
13952
13953    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13954            int opti, boolean dumpAll, String dumpPackage) {
13955        boolean needSep = false;
13956        boolean onlyHistory = false;
13957        boolean printedAnything = false;
13958
13959        if ("history".equals(dumpPackage)) {
13960            if (opti < args.length && "-s".equals(args[opti])) {
13961                dumpAll = false;
13962            }
13963            onlyHistory = true;
13964            dumpPackage = null;
13965        }
13966
13967        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13968        if (!onlyHistory && dumpAll) {
13969            if (mRegisteredReceivers.size() > 0) {
13970                boolean printed = false;
13971                Iterator it = mRegisteredReceivers.values().iterator();
13972                while (it.hasNext()) {
13973                    ReceiverList r = (ReceiverList)it.next();
13974                    if (dumpPackage != null && (r.app == null ||
13975                            !dumpPackage.equals(r.app.info.packageName))) {
13976                        continue;
13977                    }
13978                    if (!printed) {
13979                        pw.println("  Registered Receivers:");
13980                        needSep = true;
13981                        printed = true;
13982                        printedAnything = true;
13983                    }
13984                    pw.print("  * "); pw.println(r);
13985                    r.dump(pw, "    ");
13986                }
13987            }
13988
13989            if (mReceiverResolver.dump(pw, needSep ?
13990                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13991                    "    ", dumpPackage, false, false)) {
13992                needSep = true;
13993                printedAnything = true;
13994            }
13995        }
13996
13997        for (BroadcastQueue q : mBroadcastQueues) {
13998            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13999            printedAnything |= needSep;
14000        }
14001
14002        needSep = true;
14003
14004        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14005            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14006                if (needSep) {
14007                    pw.println();
14008                }
14009                needSep = true;
14010                printedAnything = true;
14011                pw.print("  Sticky broadcasts for user ");
14012                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14013                StringBuilder sb = new StringBuilder(128);
14014                for (Map.Entry<String, ArrayList<Intent>> ent
14015                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14016                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14017                    if (dumpAll) {
14018                        pw.println(":");
14019                        ArrayList<Intent> intents = ent.getValue();
14020                        final int N = intents.size();
14021                        for (int i=0; i<N; i++) {
14022                            sb.setLength(0);
14023                            sb.append("    Intent: ");
14024                            intents.get(i).toShortString(sb, false, true, false, false);
14025                            pw.println(sb.toString());
14026                            Bundle bundle = intents.get(i).getExtras();
14027                            if (bundle != null) {
14028                                pw.print("      ");
14029                                pw.println(bundle.toString());
14030                            }
14031                        }
14032                    } else {
14033                        pw.println("");
14034                    }
14035                }
14036            }
14037        }
14038
14039        if (!onlyHistory && dumpAll) {
14040            pw.println();
14041            for (BroadcastQueue queue : mBroadcastQueues) {
14042                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14043                        + queue.mBroadcastsScheduled);
14044            }
14045            pw.println("  mHandler:");
14046            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14047            needSep = true;
14048            printedAnything = true;
14049        }
14050
14051        if (!printedAnything) {
14052            pw.println("  (nothing)");
14053        }
14054    }
14055
14056    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14057            int opti, boolean dumpAll, String dumpPackage) {
14058        boolean needSep;
14059        boolean printedAnything = false;
14060
14061        ItemMatcher matcher = new ItemMatcher();
14062        matcher.build(args, opti);
14063
14064        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14065
14066        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14067        printedAnything |= needSep;
14068
14069        if (mLaunchingProviders.size() > 0) {
14070            boolean printed = false;
14071            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14072                ContentProviderRecord r = mLaunchingProviders.get(i);
14073                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14074                    continue;
14075                }
14076                if (!printed) {
14077                    if (needSep) pw.println();
14078                    needSep = true;
14079                    pw.println("  Launching content providers:");
14080                    printed = true;
14081                    printedAnything = true;
14082                }
14083                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14084                        pw.println(r);
14085            }
14086        }
14087
14088        if (!printedAnything) {
14089            pw.println("  (nothing)");
14090        }
14091    }
14092
14093    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14094            int opti, boolean dumpAll, String dumpPackage) {
14095        boolean needSep = false;
14096        boolean printedAnything = false;
14097
14098        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14099
14100        if (mGrantedUriPermissions.size() > 0) {
14101            boolean printed = false;
14102            int dumpUid = -2;
14103            if (dumpPackage != null) {
14104                try {
14105                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14106                } catch (NameNotFoundException e) {
14107                    dumpUid = -1;
14108                }
14109            }
14110            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14111                int uid = mGrantedUriPermissions.keyAt(i);
14112                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14113                    continue;
14114                }
14115                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14116                if (!printed) {
14117                    if (needSep) pw.println();
14118                    needSep = true;
14119                    pw.println("  Granted Uri Permissions:");
14120                    printed = true;
14121                    printedAnything = true;
14122                }
14123                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14124                for (UriPermission perm : perms.values()) {
14125                    pw.print("    "); pw.println(perm);
14126                    if (dumpAll) {
14127                        perm.dump(pw, "      ");
14128                    }
14129                }
14130            }
14131        }
14132
14133        if (!printedAnything) {
14134            pw.println("  (nothing)");
14135        }
14136    }
14137
14138    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14139            int opti, boolean dumpAll, String dumpPackage) {
14140        boolean printed = false;
14141
14142        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14143
14144        if (mIntentSenderRecords.size() > 0) {
14145            Iterator<WeakReference<PendingIntentRecord>> it
14146                    = mIntentSenderRecords.values().iterator();
14147            while (it.hasNext()) {
14148                WeakReference<PendingIntentRecord> ref = it.next();
14149                PendingIntentRecord rec = ref != null ? ref.get(): null;
14150                if (dumpPackage != null && (rec == null
14151                        || !dumpPackage.equals(rec.key.packageName))) {
14152                    continue;
14153                }
14154                printed = true;
14155                if (rec != null) {
14156                    pw.print("  * "); pw.println(rec);
14157                    if (dumpAll) {
14158                        rec.dump(pw, "    ");
14159                    }
14160                } else {
14161                    pw.print("  * "); pw.println(ref);
14162                }
14163            }
14164        }
14165
14166        if (!printed) {
14167            pw.println("  (nothing)");
14168        }
14169    }
14170
14171    private static final int dumpProcessList(PrintWriter pw,
14172            ActivityManagerService service, List list,
14173            String prefix, String normalLabel, String persistentLabel,
14174            String dumpPackage) {
14175        int numPers = 0;
14176        final int N = list.size()-1;
14177        for (int i=N; i>=0; i--) {
14178            ProcessRecord r = (ProcessRecord)list.get(i);
14179            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14180                continue;
14181            }
14182            pw.println(String.format("%s%s #%2d: %s",
14183                    prefix, (r.persistent ? persistentLabel : normalLabel),
14184                    i, r.toString()));
14185            if (r.persistent) {
14186                numPers++;
14187            }
14188        }
14189        return numPers;
14190    }
14191
14192    private static final boolean dumpProcessOomList(PrintWriter pw,
14193            ActivityManagerService service, List<ProcessRecord> origList,
14194            String prefix, String normalLabel, String persistentLabel,
14195            boolean inclDetails, String dumpPackage) {
14196
14197        ArrayList<Pair<ProcessRecord, Integer>> list
14198                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14199        for (int i=0; i<origList.size(); i++) {
14200            ProcessRecord r = origList.get(i);
14201            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14202                continue;
14203            }
14204            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14205        }
14206
14207        if (list.size() <= 0) {
14208            return false;
14209        }
14210
14211        Comparator<Pair<ProcessRecord, Integer>> comparator
14212                = new Comparator<Pair<ProcessRecord, Integer>>() {
14213            @Override
14214            public int compare(Pair<ProcessRecord, Integer> object1,
14215                    Pair<ProcessRecord, Integer> object2) {
14216                if (object1.first.setAdj != object2.first.setAdj) {
14217                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14218                }
14219                if (object1.second.intValue() != object2.second.intValue()) {
14220                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14221                }
14222                return 0;
14223            }
14224        };
14225
14226        Collections.sort(list, comparator);
14227
14228        final long curRealtime = SystemClock.elapsedRealtime();
14229        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14230        final long curUptime = SystemClock.uptimeMillis();
14231        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14232
14233        for (int i=list.size()-1; i>=0; i--) {
14234            ProcessRecord r = list.get(i).first;
14235            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14236            char schedGroup;
14237            switch (r.setSchedGroup) {
14238                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14239                    schedGroup = 'B';
14240                    break;
14241                case Process.THREAD_GROUP_DEFAULT:
14242                    schedGroup = 'F';
14243                    break;
14244                default:
14245                    schedGroup = '?';
14246                    break;
14247            }
14248            char foreground;
14249            if (r.foregroundActivities) {
14250                foreground = 'A';
14251            } else if (r.foregroundServices) {
14252                foreground = 'S';
14253            } else {
14254                foreground = ' ';
14255            }
14256            String procState = ProcessList.makeProcStateString(r.curProcState);
14257            pw.print(prefix);
14258            pw.print(r.persistent ? persistentLabel : normalLabel);
14259            pw.print(" #");
14260            int num = (origList.size()-1)-list.get(i).second;
14261            if (num < 10) pw.print(' ');
14262            pw.print(num);
14263            pw.print(": ");
14264            pw.print(oomAdj);
14265            pw.print(' ');
14266            pw.print(schedGroup);
14267            pw.print('/');
14268            pw.print(foreground);
14269            pw.print('/');
14270            pw.print(procState);
14271            pw.print(" trm:");
14272            if (r.trimMemoryLevel < 10) pw.print(' ');
14273            pw.print(r.trimMemoryLevel);
14274            pw.print(' ');
14275            pw.print(r.toShortString());
14276            pw.print(" (");
14277            pw.print(r.adjType);
14278            pw.println(')');
14279            if (r.adjSource != null || r.adjTarget != null) {
14280                pw.print(prefix);
14281                pw.print("    ");
14282                if (r.adjTarget instanceof ComponentName) {
14283                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14284                } else if (r.adjTarget != null) {
14285                    pw.print(r.adjTarget.toString());
14286                } else {
14287                    pw.print("{null}");
14288                }
14289                pw.print("<=");
14290                if (r.adjSource instanceof ProcessRecord) {
14291                    pw.print("Proc{");
14292                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14293                    pw.println("}");
14294                } else if (r.adjSource != null) {
14295                    pw.println(r.adjSource.toString());
14296                } else {
14297                    pw.println("{null}");
14298                }
14299            }
14300            if (inclDetails) {
14301                pw.print(prefix);
14302                pw.print("    ");
14303                pw.print("oom: max="); pw.print(r.maxAdj);
14304                pw.print(" curRaw="); pw.print(r.curRawAdj);
14305                pw.print(" setRaw="); pw.print(r.setRawAdj);
14306                pw.print(" cur="); pw.print(r.curAdj);
14307                pw.print(" set="); pw.println(r.setAdj);
14308                pw.print(prefix);
14309                pw.print("    ");
14310                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14311                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14312                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14313                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14314                pw.println();
14315                pw.print(prefix);
14316                pw.print("    ");
14317                pw.print("cached="); pw.print(r.cached);
14318                pw.print(" empty="); pw.print(r.empty);
14319                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14320
14321                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14322                    if (r.lastWakeTime != 0) {
14323                        long wtime;
14324                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14325                        synchronized (stats) {
14326                            wtime = stats.getProcessWakeTime(r.info.uid,
14327                                    r.pid, curRealtime);
14328                        }
14329                        long timeUsed = wtime - r.lastWakeTime;
14330                        pw.print(prefix);
14331                        pw.print("    ");
14332                        pw.print("keep awake over ");
14333                        TimeUtils.formatDuration(realtimeSince, pw);
14334                        pw.print(" used ");
14335                        TimeUtils.formatDuration(timeUsed, pw);
14336                        pw.print(" (");
14337                        pw.print((timeUsed*100)/realtimeSince);
14338                        pw.println("%)");
14339                    }
14340                    if (r.lastCpuTime != 0) {
14341                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14342                        pw.print(prefix);
14343                        pw.print("    ");
14344                        pw.print("run cpu over ");
14345                        TimeUtils.formatDuration(uptimeSince, pw);
14346                        pw.print(" used ");
14347                        TimeUtils.formatDuration(timeUsed, pw);
14348                        pw.print(" (");
14349                        pw.print((timeUsed*100)/uptimeSince);
14350                        pw.println("%)");
14351                    }
14352                }
14353            }
14354        }
14355        return true;
14356    }
14357
14358    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14359            String[] args) {
14360        ArrayList<ProcessRecord> procs;
14361        synchronized (this) {
14362            if (args != null && args.length > start
14363                    && args[start].charAt(0) != '-') {
14364                procs = new ArrayList<ProcessRecord>();
14365                int pid = -1;
14366                try {
14367                    pid = Integer.parseInt(args[start]);
14368                } catch (NumberFormatException e) {
14369                }
14370                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14371                    ProcessRecord proc = mLruProcesses.get(i);
14372                    if (proc.pid == pid) {
14373                        procs.add(proc);
14374                    } else if (allPkgs && proc.pkgList != null
14375                            && proc.pkgList.containsKey(args[start])) {
14376                        procs.add(proc);
14377                    } else if (proc.processName.equals(args[start])) {
14378                        procs.add(proc);
14379                    }
14380                }
14381                if (procs.size() <= 0) {
14382                    return null;
14383                }
14384            } else {
14385                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14386            }
14387        }
14388        return procs;
14389    }
14390
14391    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14392            PrintWriter pw, String[] args) {
14393        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14394        if (procs == null) {
14395            pw.println("No process found for: " + args[0]);
14396            return;
14397        }
14398
14399        long uptime = SystemClock.uptimeMillis();
14400        long realtime = SystemClock.elapsedRealtime();
14401        pw.println("Applications Graphics Acceleration Info:");
14402        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14403
14404        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14405            ProcessRecord r = procs.get(i);
14406            if (r.thread != null) {
14407                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14408                pw.flush();
14409                try {
14410                    TransferPipe tp = new TransferPipe();
14411                    try {
14412                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14413                        tp.go(fd);
14414                    } finally {
14415                        tp.kill();
14416                    }
14417                } catch (IOException e) {
14418                    pw.println("Failure while dumping the app: " + r);
14419                    pw.flush();
14420                } catch (RemoteException e) {
14421                    pw.println("Got a RemoteException while dumping the app " + r);
14422                    pw.flush();
14423                }
14424            }
14425        }
14426    }
14427
14428    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14429        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14430        if (procs == null) {
14431            pw.println("No process found for: " + args[0]);
14432            return;
14433        }
14434
14435        pw.println("Applications Database Info:");
14436
14437        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14438            ProcessRecord r = procs.get(i);
14439            if (r.thread != null) {
14440                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14441                pw.flush();
14442                try {
14443                    TransferPipe tp = new TransferPipe();
14444                    try {
14445                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14446                        tp.go(fd);
14447                    } finally {
14448                        tp.kill();
14449                    }
14450                } catch (IOException e) {
14451                    pw.println("Failure while dumping the app: " + r);
14452                    pw.flush();
14453                } catch (RemoteException e) {
14454                    pw.println("Got a RemoteException while dumping the app " + r);
14455                    pw.flush();
14456                }
14457            }
14458        }
14459    }
14460
14461    final static class MemItem {
14462        final boolean isProc;
14463        final String label;
14464        final String shortLabel;
14465        final long pss;
14466        final int id;
14467        final boolean hasActivities;
14468        ArrayList<MemItem> subitems;
14469
14470        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14471                boolean _hasActivities) {
14472            isProc = true;
14473            label = _label;
14474            shortLabel = _shortLabel;
14475            pss = _pss;
14476            id = _id;
14477            hasActivities = _hasActivities;
14478        }
14479
14480        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14481            isProc = false;
14482            label = _label;
14483            shortLabel = _shortLabel;
14484            pss = _pss;
14485            id = _id;
14486            hasActivities = false;
14487        }
14488    }
14489
14490    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14491            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14492        if (sort && !isCompact) {
14493            Collections.sort(items, new Comparator<MemItem>() {
14494                @Override
14495                public int compare(MemItem lhs, MemItem rhs) {
14496                    if (lhs.pss < rhs.pss) {
14497                        return 1;
14498                    } else if (lhs.pss > rhs.pss) {
14499                        return -1;
14500                    }
14501                    return 0;
14502                }
14503            });
14504        }
14505
14506        for (int i=0; i<items.size(); i++) {
14507            MemItem mi = items.get(i);
14508            if (!isCompact) {
14509                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14510            } else if (mi.isProc) {
14511                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14512                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14513                pw.println(mi.hasActivities ? ",a" : ",e");
14514            } else {
14515                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14516                pw.println(mi.pss);
14517            }
14518            if (mi.subitems != null) {
14519                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14520                        true, isCompact);
14521            }
14522        }
14523    }
14524
14525    // These are in KB.
14526    static final long[] DUMP_MEM_BUCKETS = new long[] {
14527        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14528        120*1024, 160*1024, 200*1024,
14529        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14530        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14531    };
14532
14533    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14534            boolean stackLike) {
14535        int start = label.lastIndexOf('.');
14536        if (start >= 0) start++;
14537        else start = 0;
14538        int end = label.length();
14539        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14540            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14541                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14542                out.append(bucket);
14543                out.append(stackLike ? "MB." : "MB ");
14544                out.append(label, start, end);
14545                return;
14546            }
14547        }
14548        out.append(memKB/1024);
14549        out.append(stackLike ? "MB." : "MB ");
14550        out.append(label, start, end);
14551    }
14552
14553    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14554            ProcessList.NATIVE_ADJ,
14555            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14556            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14557            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14558            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14559            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14560            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14561    };
14562    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14563            "Native",
14564            "System", "Persistent", "Persistent Service", "Foreground",
14565            "Visible", "Perceptible",
14566            "Heavy Weight", "Backup",
14567            "A Services", "Home",
14568            "Previous", "B Services", "Cached"
14569    };
14570    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14571            "native",
14572            "sys", "pers", "persvc", "fore",
14573            "vis", "percept",
14574            "heavy", "backup",
14575            "servicea", "home",
14576            "prev", "serviceb", "cached"
14577    };
14578
14579    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14580            long realtime, boolean isCheckinRequest, boolean isCompact) {
14581        if (isCheckinRequest || isCompact) {
14582            // short checkin version
14583            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14584        } else {
14585            pw.println("Applications Memory Usage (kB):");
14586            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14587        }
14588    }
14589
14590    private static final int KSM_SHARED = 0;
14591    private static final int KSM_SHARING = 1;
14592    private static final int KSM_UNSHARED = 2;
14593    private static final int KSM_VOLATILE = 3;
14594
14595    private final long[] getKsmInfo() {
14596        long[] longOut = new long[4];
14597        final int[] SINGLE_LONG_FORMAT = new int[] {
14598            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14599        };
14600        long[] longTmp = new long[1];
14601        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14602                SINGLE_LONG_FORMAT, null, longTmp, null);
14603        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14604        longTmp[0] = 0;
14605        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14606                SINGLE_LONG_FORMAT, null, longTmp, null);
14607        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14608        longTmp[0] = 0;
14609        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14610                SINGLE_LONG_FORMAT, null, longTmp, null);
14611        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14612        longTmp[0] = 0;
14613        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14614                SINGLE_LONG_FORMAT, null, longTmp, null);
14615        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14616        return longOut;
14617    }
14618
14619    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14620            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14621        boolean dumpDetails = false;
14622        boolean dumpFullDetails = false;
14623        boolean dumpDalvik = false;
14624        boolean dumpSummaryOnly = false;
14625        boolean oomOnly = false;
14626        boolean isCompact = false;
14627        boolean localOnly = false;
14628        boolean packages = false;
14629
14630        int opti = 0;
14631        while (opti < args.length) {
14632            String opt = args[opti];
14633            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14634                break;
14635            }
14636            opti++;
14637            if ("-a".equals(opt)) {
14638                dumpDetails = true;
14639                dumpFullDetails = true;
14640                dumpDalvik = true;
14641            } else if ("-d".equals(opt)) {
14642                dumpDalvik = true;
14643            } else if ("-c".equals(opt)) {
14644                isCompact = true;
14645            } else if ("-s".equals(opt)) {
14646                dumpDetails = true;
14647                dumpSummaryOnly = true;
14648            } else if ("--oom".equals(opt)) {
14649                oomOnly = true;
14650            } else if ("--local".equals(opt)) {
14651                localOnly = true;
14652            } else if ("--package".equals(opt)) {
14653                packages = true;
14654            } else if ("-h".equals(opt)) {
14655                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14656                pw.println("  -a: include all available information for each process.");
14657                pw.println("  -d: include dalvik details.");
14658                pw.println("  -c: dump in a compact machine-parseable representation.");
14659                pw.println("  -s: dump only summary of application memory usage.");
14660                pw.println("  --oom: only show processes organized by oom adj.");
14661                pw.println("  --local: only collect details locally, don't call process.");
14662                pw.println("  --package: interpret process arg as package, dumping all");
14663                pw.println("             processes that have loaded that package.");
14664                pw.println("If [process] is specified it can be the name or ");
14665                pw.println("pid of a specific process to dump.");
14666                return;
14667            } else {
14668                pw.println("Unknown argument: " + opt + "; use -h for help");
14669            }
14670        }
14671
14672        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14673        long uptime = SystemClock.uptimeMillis();
14674        long realtime = SystemClock.elapsedRealtime();
14675        final long[] tmpLong = new long[1];
14676
14677        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14678        if (procs == null) {
14679            // No Java processes.  Maybe they want to print a native process.
14680            if (args != null && args.length > opti
14681                    && args[opti].charAt(0) != '-') {
14682                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14683                        = new ArrayList<ProcessCpuTracker.Stats>();
14684                updateCpuStatsNow();
14685                int findPid = -1;
14686                try {
14687                    findPid = Integer.parseInt(args[opti]);
14688                } catch (NumberFormatException e) {
14689                }
14690                synchronized (mProcessCpuTracker) {
14691                    final int N = mProcessCpuTracker.countStats();
14692                    for (int i=0; i<N; i++) {
14693                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14694                        if (st.pid == findPid || (st.baseName != null
14695                                && st.baseName.equals(args[opti]))) {
14696                            nativeProcs.add(st);
14697                        }
14698                    }
14699                }
14700                if (nativeProcs.size() > 0) {
14701                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14702                            isCompact);
14703                    Debug.MemoryInfo mi = null;
14704                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14705                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14706                        final int pid = r.pid;
14707                        if (!isCheckinRequest && dumpDetails) {
14708                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14709                        }
14710                        if (mi == null) {
14711                            mi = new Debug.MemoryInfo();
14712                        }
14713                        if (dumpDetails || (!brief && !oomOnly)) {
14714                            Debug.getMemoryInfo(pid, mi);
14715                        } else {
14716                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14717                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14718                        }
14719                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14720                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14721                        if (isCheckinRequest) {
14722                            pw.println();
14723                        }
14724                    }
14725                    return;
14726                }
14727            }
14728            pw.println("No process found for: " + args[opti]);
14729            return;
14730        }
14731
14732        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14733            dumpDetails = true;
14734        }
14735
14736        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14737
14738        String[] innerArgs = new String[args.length-opti];
14739        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14740
14741        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14742        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14743        long nativePss = 0;
14744        long dalvikPss = 0;
14745        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14746                EmptyArray.LONG;
14747        long otherPss = 0;
14748        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14749
14750        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14751        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14752                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14753
14754        long totalPss = 0;
14755        long cachedPss = 0;
14756
14757        Debug.MemoryInfo mi = null;
14758        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14759            final ProcessRecord r = procs.get(i);
14760            final IApplicationThread thread;
14761            final int pid;
14762            final int oomAdj;
14763            final boolean hasActivities;
14764            synchronized (this) {
14765                thread = r.thread;
14766                pid = r.pid;
14767                oomAdj = r.getSetAdjWithServices();
14768                hasActivities = r.activities.size() > 0;
14769            }
14770            if (thread != null) {
14771                if (!isCheckinRequest && dumpDetails) {
14772                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14773                }
14774                if (mi == null) {
14775                    mi = new Debug.MemoryInfo();
14776                }
14777                if (dumpDetails || (!brief && !oomOnly)) {
14778                    Debug.getMemoryInfo(pid, mi);
14779                } else {
14780                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14781                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14782                }
14783                if (dumpDetails) {
14784                    if (localOnly) {
14785                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14786                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14787                        if (isCheckinRequest) {
14788                            pw.println();
14789                        }
14790                    } else {
14791                        try {
14792                            pw.flush();
14793                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14794                                    dumpDalvik, dumpSummaryOnly, innerArgs);
14795                        } catch (RemoteException e) {
14796                            if (!isCheckinRequest) {
14797                                pw.println("Got RemoteException!");
14798                                pw.flush();
14799                            }
14800                        }
14801                    }
14802                }
14803
14804                final long myTotalPss = mi.getTotalPss();
14805                final long myTotalUss = mi.getTotalUss();
14806
14807                synchronized (this) {
14808                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14809                        // Record this for posterity if the process has been stable.
14810                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14811                    }
14812                }
14813
14814                if (!isCheckinRequest && mi != null) {
14815                    totalPss += myTotalPss;
14816                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14817                            (hasActivities ? " / activities)" : ")"),
14818                            r.processName, myTotalPss, pid, hasActivities);
14819                    procMems.add(pssItem);
14820                    procMemsMap.put(pid, pssItem);
14821
14822                    nativePss += mi.nativePss;
14823                    dalvikPss += mi.dalvikPss;
14824                    for (int j=0; j<dalvikSubitemPss.length; j++) {
14825                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14826                    }
14827                    otherPss += mi.otherPss;
14828                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14829                        long mem = mi.getOtherPss(j);
14830                        miscPss[j] += mem;
14831                        otherPss -= mem;
14832                    }
14833
14834                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14835                        cachedPss += myTotalPss;
14836                    }
14837
14838                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14839                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14840                                || oomIndex == (oomPss.length-1)) {
14841                            oomPss[oomIndex] += myTotalPss;
14842                            if (oomProcs[oomIndex] == null) {
14843                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14844                            }
14845                            oomProcs[oomIndex].add(pssItem);
14846                            break;
14847                        }
14848                    }
14849                }
14850            }
14851        }
14852
14853        long nativeProcTotalPss = 0;
14854
14855        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14856            // If we are showing aggregations, also look for native processes to
14857            // include so that our aggregations are more accurate.
14858            updateCpuStatsNow();
14859            mi = null;
14860            synchronized (mProcessCpuTracker) {
14861                final int N = mProcessCpuTracker.countStats();
14862                for (int i=0; i<N; i++) {
14863                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14864                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14865                        if (mi == null) {
14866                            mi = new Debug.MemoryInfo();
14867                        }
14868                        if (!brief && !oomOnly) {
14869                            Debug.getMemoryInfo(st.pid, mi);
14870                        } else {
14871                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14872                            mi.nativePrivateDirty = (int)tmpLong[0];
14873                        }
14874
14875                        final long myTotalPss = mi.getTotalPss();
14876                        totalPss += myTotalPss;
14877                        nativeProcTotalPss += myTotalPss;
14878
14879                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14880                                st.name, myTotalPss, st.pid, false);
14881                        procMems.add(pssItem);
14882
14883                        nativePss += mi.nativePss;
14884                        dalvikPss += mi.dalvikPss;
14885                        for (int j=0; j<dalvikSubitemPss.length; j++) {
14886                            dalvikSubitemPss[j] += mi.getOtherPss(
14887                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
14888                        }
14889                        otherPss += mi.otherPss;
14890                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14891                            long mem = mi.getOtherPss(j);
14892                            miscPss[j] += mem;
14893                            otherPss -= mem;
14894                        }
14895                        oomPss[0] += myTotalPss;
14896                        if (oomProcs[0] == null) {
14897                            oomProcs[0] = new ArrayList<MemItem>();
14898                        }
14899                        oomProcs[0].add(pssItem);
14900                    }
14901                }
14902            }
14903
14904            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14905
14906            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14907            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14908            if (dalvikSubitemPss.length > 0) {
14909                dalvikItem.subitems = new ArrayList<MemItem>();
14910                for (int j=0; j<dalvikSubitemPss.length; j++) {
14911                    final String name = Debug.MemoryInfo.getOtherLabel(
14912                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
14913                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14914                }
14915            }
14916            catMems.add(dalvikItem);
14917            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14918            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14919                String label = Debug.MemoryInfo.getOtherLabel(j);
14920                catMems.add(new MemItem(label, label, miscPss[j], j));
14921            }
14922
14923            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14924            for (int j=0; j<oomPss.length; j++) {
14925                if (oomPss[j] != 0) {
14926                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14927                            : DUMP_MEM_OOM_LABEL[j];
14928                    MemItem item = new MemItem(label, label, oomPss[j],
14929                            DUMP_MEM_OOM_ADJ[j]);
14930                    item.subitems = oomProcs[j];
14931                    oomMems.add(item);
14932                }
14933            }
14934
14935            if (!brief && !oomOnly && !isCompact) {
14936                pw.println();
14937                pw.println("Total PSS by process:");
14938                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14939                pw.println();
14940            }
14941            if (!isCompact) {
14942                pw.println("Total PSS by OOM adjustment:");
14943            }
14944            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14945            if (!brief && !oomOnly) {
14946                PrintWriter out = categoryPw != null ? categoryPw : pw;
14947                if (!isCompact) {
14948                    out.println();
14949                    out.println("Total PSS by category:");
14950                }
14951                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14952            }
14953            if (!isCompact) {
14954                pw.println();
14955            }
14956            MemInfoReader memInfo = new MemInfoReader();
14957            memInfo.readMemInfo();
14958            if (nativeProcTotalPss > 0) {
14959                synchronized (this) {
14960                    final long cachedKb = memInfo.getCachedSizeKb();
14961                    final long freeKb = memInfo.getFreeSizeKb();
14962                    final long zramKb = memInfo.getZramTotalSizeKb();
14963                    final long kernelKb = memInfo.getKernelUsedSizeKb();
14964                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14965                            kernelKb*1024, nativeProcTotalPss*1024);
14966                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14967                            nativeProcTotalPss);
14968                }
14969            }
14970            if (!brief) {
14971                if (!isCompact) {
14972                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14973                    pw.print(" kB (status ");
14974                    switch (mLastMemoryLevel) {
14975                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14976                            pw.println("normal)");
14977                            break;
14978                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14979                            pw.println("moderate)");
14980                            break;
14981                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14982                            pw.println("low)");
14983                            break;
14984                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14985                            pw.println("critical)");
14986                            break;
14987                        default:
14988                            pw.print(mLastMemoryLevel);
14989                            pw.println(")");
14990                            break;
14991                    }
14992                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14993                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14994                            pw.print(cachedPss); pw.print(" cached pss + ");
14995                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14996                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14997                } else {
14998                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14999                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15000                            + memInfo.getFreeSizeKb()); pw.print(",");
15001                    pw.println(totalPss - cachedPss);
15002                }
15003            }
15004            if (!isCompact) {
15005                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
15006                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
15007                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
15008                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
15009                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
15010                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15011                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
15012            }
15013            if (!brief) {
15014                if (memInfo.getZramTotalSizeKb() != 0) {
15015                    if (!isCompact) {
15016                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
15017                                pw.print(" kB physical used for ");
15018                                pw.print(memInfo.getSwapTotalSizeKb()
15019                                        - memInfo.getSwapFreeSizeKb());
15020                                pw.print(" kB in swap (");
15021                                pw.print(memInfo.getSwapTotalSizeKb());
15022                                pw.println(" kB total swap)");
15023                    } else {
15024                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15025                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15026                                pw.println(memInfo.getSwapFreeSizeKb());
15027                    }
15028                }
15029                final long[] ksm = getKsmInfo();
15030                if (!isCompact) {
15031                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15032                            || ksm[KSM_VOLATILE] != 0) {
15033                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
15034                                pw.print(" kB saved from shared ");
15035                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
15036                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
15037                                pw.print(" kB unshared; ");
15038                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
15039                    }
15040                    pw.print("   Tuning: ");
15041                    pw.print(ActivityManager.staticGetMemoryClass());
15042                    pw.print(" (large ");
15043                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15044                    pw.print("), oom ");
15045                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15046                    pw.print(" kB");
15047                    pw.print(", restore limit ");
15048                    pw.print(mProcessList.getCachedRestoreThresholdKb());
15049                    pw.print(" kB");
15050                    if (ActivityManager.isLowRamDeviceStatic()) {
15051                        pw.print(" (low-ram)");
15052                    }
15053                    if (ActivityManager.isHighEndGfx()) {
15054                        pw.print(" (high-end-gfx)");
15055                    }
15056                    pw.println();
15057                } else {
15058                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15059                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15060                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15061                    pw.print("tuning,");
15062                    pw.print(ActivityManager.staticGetMemoryClass());
15063                    pw.print(',');
15064                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15065                    pw.print(',');
15066                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15067                    if (ActivityManager.isLowRamDeviceStatic()) {
15068                        pw.print(",low-ram");
15069                    }
15070                    if (ActivityManager.isHighEndGfx()) {
15071                        pw.print(",high-end-gfx");
15072                    }
15073                    pw.println();
15074                }
15075            }
15076        }
15077    }
15078
15079    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15080            long memtrack, String name) {
15081        sb.append("  ");
15082        sb.append(ProcessList.makeOomAdjString(oomAdj));
15083        sb.append(' ');
15084        sb.append(ProcessList.makeProcStateString(procState));
15085        sb.append(' ');
15086        ProcessList.appendRamKb(sb, pss);
15087        sb.append(" kB: ");
15088        sb.append(name);
15089        if (memtrack > 0) {
15090            sb.append(" (");
15091            sb.append(memtrack);
15092            sb.append(" kB memtrack)");
15093        }
15094    }
15095
15096    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15097        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15098        sb.append(" (pid ");
15099        sb.append(mi.pid);
15100        sb.append(") ");
15101        sb.append(mi.adjType);
15102        sb.append('\n');
15103        if (mi.adjReason != null) {
15104            sb.append("                      ");
15105            sb.append(mi.adjReason);
15106            sb.append('\n');
15107        }
15108    }
15109
15110    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15111        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15112        for (int i=0, N=memInfos.size(); i<N; i++) {
15113            ProcessMemInfo mi = memInfos.get(i);
15114            infoMap.put(mi.pid, mi);
15115        }
15116        updateCpuStatsNow();
15117        long[] memtrackTmp = new long[1];
15118        synchronized (mProcessCpuTracker) {
15119            final int N = mProcessCpuTracker.countStats();
15120            for (int i=0; i<N; i++) {
15121                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15122                if (st.vsize > 0) {
15123                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15124                    if (pss > 0) {
15125                        if (infoMap.indexOfKey(st.pid) < 0) {
15126                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15127                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15128                            mi.pss = pss;
15129                            mi.memtrack = memtrackTmp[0];
15130                            memInfos.add(mi);
15131                        }
15132                    }
15133                }
15134            }
15135        }
15136
15137        long totalPss = 0;
15138        long totalMemtrack = 0;
15139        for (int i=0, N=memInfos.size(); i<N; i++) {
15140            ProcessMemInfo mi = memInfos.get(i);
15141            if (mi.pss == 0) {
15142                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15143                mi.memtrack = memtrackTmp[0];
15144            }
15145            totalPss += mi.pss;
15146            totalMemtrack += mi.memtrack;
15147        }
15148        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15149            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15150                if (lhs.oomAdj != rhs.oomAdj) {
15151                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15152                }
15153                if (lhs.pss != rhs.pss) {
15154                    return lhs.pss < rhs.pss ? 1 : -1;
15155                }
15156                return 0;
15157            }
15158        });
15159
15160        StringBuilder tag = new StringBuilder(128);
15161        StringBuilder stack = new StringBuilder(128);
15162        tag.append("Low on memory -- ");
15163        appendMemBucket(tag, totalPss, "total", false);
15164        appendMemBucket(stack, totalPss, "total", true);
15165
15166        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15167        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15168        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15169
15170        boolean firstLine = true;
15171        int lastOomAdj = Integer.MIN_VALUE;
15172        long extraNativeRam = 0;
15173        long extraNativeMemtrack = 0;
15174        long cachedPss = 0;
15175        for (int i=0, N=memInfos.size(); i<N; i++) {
15176            ProcessMemInfo mi = memInfos.get(i);
15177
15178            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15179                cachedPss += mi.pss;
15180            }
15181
15182            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15183                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15184                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15185                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15186                if (lastOomAdj != mi.oomAdj) {
15187                    lastOomAdj = mi.oomAdj;
15188                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15189                        tag.append(" / ");
15190                    }
15191                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15192                        if (firstLine) {
15193                            stack.append(":");
15194                            firstLine = false;
15195                        }
15196                        stack.append("\n\t at ");
15197                    } else {
15198                        stack.append("$");
15199                    }
15200                } else {
15201                    tag.append(" ");
15202                    stack.append("$");
15203                }
15204                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15205                    appendMemBucket(tag, mi.pss, mi.name, false);
15206                }
15207                appendMemBucket(stack, mi.pss, mi.name, true);
15208                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15209                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15210                    stack.append("(");
15211                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15212                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15213                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15214                            stack.append(":");
15215                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15216                        }
15217                    }
15218                    stack.append(")");
15219                }
15220            }
15221
15222            appendMemInfo(fullNativeBuilder, mi);
15223            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15224                // The short form only has native processes that are >= 512K.
15225                if (mi.pss >= 512) {
15226                    appendMemInfo(shortNativeBuilder, mi);
15227                } else {
15228                    extraNativeRam += mi.pss;
15229                    extraNativeMemtrack += mi.memtrack;
15230                }
15231            } else {
15232                // Short form has all other details, but if we have collected RAM
15233                // from smaller native processes let's dump a summary of that.
15234                if (extraNativeRam > 0) {
15235                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15236                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15237                    shortNativeBuilder.append('\n');
15238                    extraNativeRam = 0;
15239                }
15240                appendMemInfo(fullJavaBuilder, mi);
15241            }
15242        }
15243
15244        fullJavaBuilder.append("           ");
15245        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15246        fullJavaBuilder.append(" kB: TOTAL");
15247        if (totalMemtrack > 0) {
15248            fullJavaBuilder.append(" (");
15249            fullJavaBuilder.append(totalMemtrack);
15250            fullJavaBuilder.append(" kB memtrack)");
15251        } else {
15252        }
15253        fullJavaBuilder.append("\n");
15254
15255        MemInfoReader memInfo = new MemInfoReader();
15256        memInfo.readMemInfo();
15257        final long[] infos = memInfo.getRawInfo();
15258
15259        StringBuilder memInfoBuilder = new StringBuilder(1024);
15260        Debug.getMemInfo(infos);
15261        memInfoBuilder.append("  MemInfo: ");
15262        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15263        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15264        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15265        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15266        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15267        memInfoBuilder.append("           ");
15268        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15269        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15270        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15271        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15272        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15273            memInfoBuilder.append("  ZRAM: ");
15274            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15275            memInfoBuilder.append(" kB RAM, ");
15276            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15277            memInfoBuilder.append(" kB swap total, ");
15278            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15279            memInfoBuilder.append(" kB swap free\n");
15280        }
15281        final long[] ksm = getKsmInfo();
15282        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15283                || ksm[KSM_VOLATILE] != 0) {
15284            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15285            memInfoBuilder.append(" kB saved from shared ");
15286            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15287            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15288            memInfoBuilder.append(" kB unshared; ");
15289            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15290        }
15291        memInfoBuilder.append("  Free RAM: ");
15292        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15293                + memInfo.getFreeSizeKb());
15294        memInfoBuilder.append(" kB\n");
15295        memInfoBuilder.append("  Used RAM: ");
15296        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15297        memInfoBuilder.append(" kB\n");
15298        memInfoBuilder.append("  Lost RAM: ");
15299        memInfoBuilder.append(memInfo.getTotalSizeKb()
15300                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15301                - memInfo.getKernelUsedSizeKb());
15302        memInfoBuilder.append(" kB\n");
15303        Slog.i(TAG, "Low on memory:");
15304        Slog.i(TAG, shortNativeBuilder.toString());
15305        Slog.i(TAG, fullJavaBuilder.toString());
15306        Slog.i(TAG, memInfoBuilder.toString());
15307
15308        StringBuilder dropBuilder = new StringBuilder(1024);
15309        /*
15310        StringWriter oomSw = new StringWriter();
15311        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15312        StringWriter catSw = new StringWriter();
15313        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15314        String[] emptyArgs = new String[] { };
15315        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15316        oomPw.flush();
15317        String oomString = oomSw.toString();
15318        */
15319        dropBuilder.append("Low on memory:");
15320        dropBuilder.append(stack);
15321        dropBuilder.append('\n');
15322        dropBuilder.append(fullNativeBuilder);
15323        dropBuilder.append(fullJavaBuilder);
15324        dropBuilder.append('\n');
15325        dropBuilder.append(memInfoBuilder);
15326        dropBuilder.append('\n');
15327        /*
15328        dropBuilder.append(oomString);
15329        dropBuilder.append('\n');
15330        */
15331        StringWriter catSw = new StringWriter();
15332        synchronized (ActivityManagerService.this) {
15333            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15334            String[] emptyArgs = new String[] { };
15335            catPw.println();
15336            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15337            catPw.println();
15338            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15339                    false, false, null);
15340            catPw.println();
15341            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15342            catPw.flush();
15343        }
15344        dropBuilder.append(catSw.toString());
15345        addErrorToDropBox("lowmem", null, "system_server", null,
15346                null, tag.toString(), dropBuilder.toString(), null, null);
15347        //Slog.i(TAG, "Sent to dropbox:");
15348        //Slog.i(TAG, dropBuilder.toString());
15349        synchronized (ActivityManagerService.this) {
15350            long now = SystemClock.uptimeMillis();
15351            if (mLastMemUsageReportTime < now) {
15352                mLastMemUsageReportTime = now;
15353            }
15354        }
15355    }
15356
15357    /**
15358     * Searches array of arguments for the specified string
15359     * @param args array of argument strings
15360     * @param value value to search for
15361     * @return true if the value is contained in the array
15362     */
15363    private static boolean scanArgs(String[] args, String value) {
15364        if (args != null) {
15365            for (String arg : args) {
15366                if (value.equals(arg)) {
15367                    return true;
15368                }
15369            }
15370        }
15371        return false;
15372    }
15373
15374    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15375            ContentProviderRecord cpr, boolean always) {
15376        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15377
15378        if (!inLaunching || always) {
15379            synchronized (cpr) {
15380                cpr.launchingApp = null;
15381                cpr.notifyAll();
15382            }
15383            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15384            String names[] = cpr.info.authority.split(";");
15385            for (int j = 0; j < names.length; j++) {
15386                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15387            }
15388        }
15389
15390        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15391            ContentProviderConnection conn = cpr.connections.get(i);
15392            if (conn.waiting) {
15393                // If this connection is waiting for the provider, then we don't
15394                // need to mess with its process unless we are always removing
15395                // or for some reason the provider is not currently launching.
15396                if (inLaunching && !always) {
15397                    continue;
15398                }
15399            }
15400            ProcessRecord capp = conn.client;
15401            conn.dead = true;
15402            if (conn.stableCount > 0) {
15403                if (!capp.persistent && capp.thread != null
15404                        && capp.pid != 0
15405                        && capp.pid != MY_PID) {
15406                    capp.kill("depends on provider "
15407                            + cpr.name.flattenToShortString()
15408                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15409                }
15410            } else if (capp.thread != null && conn.provider.provider != null) {
15411                try {
15412                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15413                } catch (RemoteException e) {
15414                }
15415                // In the protocol here, we don't expect the client to correctly
15416                // clean up this connection, we'll just remove it.
15417                cpr.connections.remove(i);
15418                if (conn.client.conProviders.remove(conn)) {
15419                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15420                }
15421            }
15422        }
15423
15424        if (inLaunching && always) {
15425            mLaunchingProviders.remove(cpr);
15426        }
15427        return inLaunching;
15428    }
15429
15430    /**
15431     * Main code for cleaning up a process when it has gone away.  This is
15432     * called both as a result of the process dying, or directly when stopping
15433     * a process when running in single process mode.
15434     *
15435     * @return Returns true if the given process has been restarted, so the
15436     * app that was passed in must remain on the process lists.
15437     */
15438    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15439            boolean restarting, boolean allowRestart, int index) {
15440        if (index >= 0) {
15441            removeLruProcessLocked(app);
15442            ProcessList.remove(app.pid);
15443        }
15444
15445        mProcessesToGc.remove(app);
15446        mPendingPssProcesses.remove(app);
15447
15448        // Dismiss any open dialogs.
15449        if (app.crashDialog != null && !app.forceCrashReport) {
15450            app.crashDialog.dismiss();
15451            app.crashDialog = null;
15452        }
15453        if (app.anrDialog != null) {
15454            app.anrDialog.dismiss();
15455            app.anrDialog = null;
15456        }
15457        if (app.waitDialog != null) {
15458            app.waitDialog.dismiss();
15459            app.waitDialog = null;
15460        }
15461
15462        app.crashing = false;
15463        app.notResponding = false;
15464
15465        app.resetPackageList(mProcessStats);
15466        app.unlinkDeathRecipient();
15467        app.makeInactive(mProcessStats);
15468        app.waitingToKill = null;
15469        app.forcingToForeground = null;
15470        updateProcessForegroundLocked(app, false, false);
15471        app.foregroundActivities = false;
15472        app.hasShownUi = false;
15473        app.treatLikeActivity = false;
15474        app.hasAboveClient = false;
15475        app.hasClientActivities = false;
15476
15477        mServices.killServicesLocked(app, allowRestart);
15478
15479        boolean restart = false;
15480
15481        // Remove published content providers.
15482        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15483            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15484            final boolean always = app.bad || !allowRestart;
15485            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15486            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15487                // We left the provider in the launching list, need to
15488                // restart it.
15489                restart = true;
15490            }
15491
15492            cpr.provider = null;
15493            cpr.proc = null;
15494        }
15495        app.pubProviders.clear();
15496
15497        // Take care of any launching providers waiting for this process.
15498        if (checkAppInLaunchingProvidersLocked(app, false)) {
15499            restart = true;
15500        }
15501
15502        // Unregister from connected content providers.
15503        if (!app.conProviders.isEmpty()) {
15504            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15505                ContentProviderConnection conn = app.conProviders.get(i);
15506                conn.provider.connections.remove(conn);
15507                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15508                        conn.provider.name);
15509            }
15510            app.conProviders.clear();
15511        }
15512
15513        // At this point there may be remaining entries in mLaunchingProviders
15514        // where we were the only one waiting, so they are no longer of use.
15515        // Look for these and clean up if found.
15516        // XXX Commented out for now.  Trying to figure out a way to reproduce
15517        // the actual situation to identify what is actually going on.
15518        if (false) {
15519            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15520                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15521                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15522                    synchronized (cpr) {
15523                        cpr.launchingApp = null;
15524                        cpr.notifyAll();
15525                    }
15526                }
15527            }
15528        }
15529
15530        skipCurrentReceiverLocked(app);
15531
15532        // Unregister any receivers.
15533        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15534            removeReceiverLocked(app.receivers.valueAt(i));
15535        }
15536        app.receivers.clear();
15537
15538        // If the app is undergoing backup, tell the backup manager about it
15539        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15540            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15541                    + mBackupTarget.appInfo + " died during backup");
15542            try {
15543                IBackupManager bm = IBackupManager.Stub.asInterface(
15544                        ServiceManager.getService(Context.BACKUP_SERVICE));
15545                bm.agentDisconnected(app.info.packageName);
15546            } catch (RemoteException e) {
15547                // can't happen; backup manager is local
15548            }
15549        }
15550
15551        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15552            ProcessChangeItem item = mPendingProcessChanges.get(i);
15553            if (item.pid == app.pid) {
15554                mPendingProcessChanges.remove(i);
15555                mAvailProcessChanges.add(item);
15556            }
15557        }
15558        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15559
15560        // If the caller is restarting this app, then leave it in its
15561        // current lists and let the caller take care of it.
15562        if (restarting) {
15563            return false;
15564        }
15565
15566        if (!app.persistent || app.isolated) {
15567            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15568                    "Removing non-persistent process during cleanup: " + app);
15569            removeProcessNameLocked(app.processName, app.uid);
15570            if (mHeavyWeightProcess == app) {
15571                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15572                        mHeavyWeightProcess.userId, 0));
15573                mHeavyWeightProcess = null;
15574            }
15575        } else if (!app.removed) {
15576            // This app is persistent, so we need to keep its record around.
15577            // If it is not already on the pending app list, add it there
15578            // and start a new process for it.
15579            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15580                mPersistentStartingProcesses.add(app);
15581                restart = true;
15582            }
15583        }
15584        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15585                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15586        mProcessesOnHold.remove(app);
15587
15588        if (app == mHomeProcess) {
15589            mHomeProcess = null;
15590        }
15591        if (app == mPreviousProcess) {
15592            mPreviousProcess = null;
15593        }
15594
15595        if (restart && !app.isolated) {
15596            // We have components that still need to be running in the
15597            // process, so re-launch it.
15598            if (index < 0) {
15599                ProcessList.remove(app.pid);
15600            }
15601            addProcessNameLocked(app);
15602            startProcessLocked(app, "restart", app.processName);
15603            return true;
15604        } else if (app.pid > 0 && app.pid != MY_PID) {
15605            // Goodbye!
15606            boolean removed;
15607            synchronized (mPidsSelfLocked) {
15608                mPidsSelfLocked.remove(app.pid);
15609                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15610            }
15611            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15612            if (app.isolated) {
15613                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15614            }
15615            app.setPid(0);
15616        }
15617        return false;
15618    }
15619
15620    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15621        // Look through the content providers we are waiting to have launched,
15622        // and if any run in this process then either schedule a restart of
15623        // the process or kill the client waiting for it if this process has
15624        // gone bad.
15625        boolean restart = false;
15626        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15627            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15628            if (cpr.launchingApp == app) {
15629                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15630                    restart = true;
15631                } else {
15632                    removeDyingProviderLocked(app, cpr, true);
15633                }
15634            }
15635        }
15636        return restart;
15637    }
15638
15639    // =========================================================
15640    // SERVICES
15641    // =========================================================
15642
15643    @Override
15644    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15645            int flags) {
15646        enforceNotIsolatedCaller("getServices");
15647        synchronized (this) {
15648            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15649        }
15650    }
15651
15652    @Override
15653    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15654        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15655        synchronized (this) {
15656            return mServices.getRunningServiceControlPanelLocked(name);
15657        }
15658    }
15659
15660    @Override
15661    public ComponentName startService(IApplicationThread caller, Intent service,
15662            String resolvedType, String callingPackage, int userId)
15663            throws TransactionTooLargeException {
15664        enforceNotIsolatedCaller("startService");
15665        // Refuse possible leaked file descriptors
15666        if (service != null && service.hasFileDescriptors() == true) {
15667            throw new IllegalArgumentException("File descriptors passed in Intent");
15668        }
15669
15670        if (callingPackage == null) {
15671            throw new IllegalArgumentException("callingPackage cannot be null");
15672        }
15673
15674        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15675                "startService: " + service + " type=" + resolvedType);
15676        synchronized(this) {
15677            final int callingPid = Binder.getCallingPid();
15678            final int callingUid = Binder.getCallingUid();
15679            final long origId = Binder.clearCallingIdentity();
15680            ComponentName res = mServices.startServiceLocked(caller, service,
15681                    resolvedType, callingPid, callingUid, callingPackage, userId);
15682            Binder.restoreCallingIdentity(origId);
15683            return res;
15684        }
15685    }
15686
15687    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15688            String callingPackage, int userId)
15689            throws TransactionTooLargeException {
15690        synchronized(this) {
15691            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15692                    "startServiceInPackage: " + service + " type=" + resolvedType);
15693            final long origId = Binder.clearCallingIdentity();
15694            ComponentName res = mServices.startServiceLocked(null, service,
15695                    resolvedType, -1, uid, callingPackage, userId);
15696            Binder.restoreCallingIdentity(origId);
15697            return res;
15698        }
15699    }
15700
15701    @Override
15702    public int stopService(IApplicationThread caller, Intent service,
15703            String resolvedType, int userId) {
15704        enforceNotIsolatedCaller("stopService");
15705        // Refuse possible leaked file descriptors
15706        if (service != null && service.hasFileDescriptors() == true) {
15707            throw new IllegalArgumentException("File descriptors passed in Intent");
15708        }
15709
15710        synchronized(this) {
15711            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15712        }
15713    }
15714
15715    @Override
15716    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15717        enforceNotIsolatedCaller("peekService");
15718        // Refuse possible leaked file descriptors
15719        if (service != null && service.hasFileDescriptors() == true) {
15720            throw new IllegalArgumentException("File descriptors passed in Intent");
15721        }
15722
15723        if (callingPackage == null) {
15724            throw new IllegalArgumentException("callingPackage cannot be null");
15725        }
15726
15727        synchronized(this) {
15728            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
15729        }
15730    }
15731
15732    @Override
15733    public boolean stopServiceToken(ComponentName className, IBinder token,
15734            int startId) {
15735        synchronized(this) {
15736            return mServices.stopServiceTokenLocked(className, token, startId);
15737        }
15738    }
15739
15740    @Override
15741    public void setServiceForeground(ComponentName className, IBinder token,
15742            int id, Notification notification, boolean removeNotification) {
15743        synchronized(this) {
15744            mServices.setServiceForegroundLocked(className, token, id, notification,
15745                    removeNotification);
15746        }
15747    }
15748
15749    @Override
15750    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15751            boolean requireFull, String name, String callerPackage) {
15752        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15753                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15754    }
15755
15756    int unsafeConvertIncomingUser(int userId) {
15757        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15758                ? mCurrentUserId : userId;
15759    }
15760
15761    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15762            int allowMode, String name, String callerPackage) {
15763        final int callingUserId = UserHandle.getUserId(callingUid);
15764        if (callingUserId == userId) {
15765            return userId;
15766        }
15767
15768        // Note that we may be accessing mCurrentUserId outside of a lock...
15769        // shouldn't be a big deal, if this is being called outside
15770        // of a locked context there is intrinsically a race with
15771        // the value the caller will receive and someone else changing it.
15772        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15773        // we will switch to the calling user if access to the current user fails.
15774        int targetUserId = unsafeConvertIncomingUser(userId);
15775
15776        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15777            final boolean allow;
15778            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15779                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15780                // If the caller has this permission, they always pass go.  And collect $200.
15781                allow = true;
15782            } else if (allowMode == ALLOW_FULL_ONLY) {
15783                // We require full access, sucks to be you.
15784                allow = false;
15785            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15786                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15787                // If the caller does not have either permission, they are always doomed.
15788                allow = false;
15789            } else if (allowMode == ALLOW_NON_FULL) {
15790                // We are blanket allowing non-full access, you lucky caller!
15791                allow = true;
15792            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15793                // We may or may not allow this depending on whether the two users are
15794                // in the same profile.
15795                synchronized (mUserProfileGroupIdsSelfLocked) {
15796                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15797                            UserInfo.NO_PROFILE_GROUP_ID);
15798                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15799                            UserInfo.NO_PROFILE_GROUP_ID);
15800                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15801                            && callingProfile == targetProfile;
15802                }
15803            } else {
15804                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15805            }
15806            if (!allow) {
15807                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15808                    // In this case, they would like to just execute as their
15809                    // owner user instead of failing.
15810                    targetUserId = callingUserId;
15811                } else {
15812                    StringBuilder builder = new StringBuilder(128);
15813                    builder.append("Permission Denial: ");
15814                    builder.append(name);
15815                    if (callerPackage != null) {
15816                        builder.append(" from ");
15817                        builder.append(callerPackage);
15818                    }
15819                    builder.append(" asks to run as user ");
15820                    builder.append(userId);
15821                    builder.append(" but is calling from user ");
15822                    builder.append(UserHandle.getUserId(callingUid));
15823                    builder.append("; this requires ");
15824                    builder.append(INTERACT_ACROSS_USERS_FULL);
15825                    if (allowMode != ALLOW_FULL_ONLY) {
15826                        builder.append(" or ");
15827                        builder.append(INTERACT_ACROSS_USERS);
15828                    }
15829                    String msg = builder.toString();
15830                    Slog.w(TAG, msg);
15831                    throw new SecurityException(msg);
15832                }
15833            }
15834        }
15835        if (!allowAll && targetUserId < 0) {
15836            throw new IllegalArgumentException(
15837                    "Call does not support special user #" + targetUserId);
15838        }
15839        // Check shell permission
15840        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15841            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15842                    targetUserId)) {
15843                throw new SecurityException("Shell does not have permission to access user "
15844                        + targetUserId + "\n " + Debug.getCallers(3));
15845            }
15846        }
15847        return targetUserId;
15848    }
15849
15850    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15851            String className, int flags) {
15852        boolean result = false;
15853        // For apps that don't have pre-defined UIDs, check for permission
15854        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15855            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15856                if (ActivityManager.checkUidPermission(
15857                        INTERACT_ACROSS_USERS,
15858                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15859                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15860                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15861                            + " requests FLAG_SINGLE_USER, but app does not hold "
15862                            + INTERACT_ACROSS_USERS;
15863                    Slog.w(TAG, msg);
15864                    throw new SecurityException(msg);
15865                }
15866                // Permission passed
15867                result = true;
15868            }
15869        } else if ("system".equals(componentProcessName)) {
15870            result = true;
15871        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15872            // Phone app and persistent apps are allowed to export singleuser providers.
15873            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15874                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15875        }
15876        if (DEBUG_MU) Slog.v(TAG_MU,
15877                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15878                + Integer.toHexString(flags) + ") = " + result);
15879        return result;
15880    }
15881
15882    /**
15883     * Checks to see if the caller is in the same app as the singleton
15884     * component, or the component is in a special app. It allows special apps
15885     * to export singleton components but prevents exporting singleton
15886     * components for regular apps.
15887     */
15888    boolean isValidSingletonCall(int callingUid, int componentUid) {
15889        int componentAppId = UserHandle.getAppId(componentUid);
15890        return UserHandle.isSameApp(callingUid, componentUid)
15891                || componentAppId == Process.SYSTEM_UID
15892                || componentAppId == Process.PHONE_UID
15893                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15894                        == PackageManager.PERMISSION_GRANTED;
15895    }
15896
15897    public int bindService(IApplicationThread caller, IBinder token, Intent service,
15898            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
15899            int userId) throws TransactionTooLargeException {
15900        enforceNotIsolatedCaller("bindService");
15901
15902        // Refuse possible leaked file descriptors
15903        if (service != null && service.hasFileDescriptors() == true) {
15904            throw new IllegalArgumentException("File descriptors passed in Intent");
15905        }
15906
15907        if (callingPackage == null) {
15908            throw new IllegalArgumentException("callingPackage cannot be null");
15909        }
15910
15911        synchronized(this) {
15912            return mServices.bindServiceLocked(caller, token, service,
15913                    resolvedType, connection, flags, callingPackage, userId);
15914        }
15915    }
15916
15917    public boolean unbindService(IServiceConnection connection) {
15918        synchronized (this) {
15919            return mServices.unbindServiceLocked(connection);
15920        }
15921    }
15922
15923    public void publishService(IBinder token, Intent intent, IBinder service) {
15924        // Refuse possible leaked file descriptors
15925        if (intent != null && intent.hasFileDescriptors() == true) {
15926            throw new IllegalArgumentException("File descriptors passed in Intent");
15927        }
15928
15929        synchronized(this) {
15930            if (!(token instanceof ServiceRecord)) {
15931                throw new IllegalArgumentException("Invalid service token");
15932            }
15933            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15934        }
15935    }
15936
15937    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15938        // Refuse possible leaked file descriptors
15939        if (intent != null && intent.hasFileDescriptors() == true) {
15940            throw new IllegalArgumentException("File descriptors passed in Intent");
15941        }
15942
15943        synchronized(this) {
15944            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15945        }
15946    }
15947
15948    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15949        synchronized(this) {
15950            if (!(token instanceof ServiceRecord)) {
15951                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15952                throw new IllegalArgumentException("Invalid service token");
15953            }
15954            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15955        }
15956    }
15957
15958    // =========================================================
15959    // BACKUP AND RESTORE
15960    // =========================================================
15961
15962    // Cause the target app to be launched if necessary and its backup agent
15963    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15964    // activity manager to announce its creation.
15965    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15966        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15967                "bindBackupAgent: app=" + app + " mode=" + backupMode);
15968        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15969
15970        synchronized(this) {
15971            // !!! TODO: currently no check here that we're already bound
15972            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15973            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15974            synchronized (stats) {
15975                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15976            }
15977
15978            // Backup agent is now in use, its package can't be stopped.
15979            try {
15980                AppGlobals.getPackageManager().setPackageStoppedState(
15981                        app.packageName, false, UserHandle.getUserId(app.uid));
15982            } catch (RemoteException e) {
15983            } catch (IllegalArgumentException e) {
15984                Slog.w(TAG, "Failed trying to unstop package "
15985                        + app.packageName + ": " + e);
15986            }
15987
15988            BackupRecord r = new BackupRecord(ss, app, backupMode);
15989            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15990                    ? new ComponentName(app.packageName, app.backupAgentName)
15991                    : new ComponentName("android", "FullBackupAgent");
15992            // startProcessLocked() returns existing proc's record if it's already running
15993            ProcessRecord proc = startProcessLocked(app.processName, app,
15994                    false, 0, "backup", hostingName, false, false, false);
15995            if (proc == null) {
15996                Slog.e(TAG, "Unable to start backup agent process " + r);
15997                return false;
15998            }
15999
16000            r.app = proc;
16001            mBackupTarget = r;
16002            mBackupAppName = app.packageName;
16003
16004            // Try not to kill the process during backup
16005            updateOomAdjLocked(proc);
16006
16007            // If the process is already attached, schedule the creation of the backup agent now.
16008            // If it is not yet live, this will be done when it attaches to the framework.
16009            if (proc.thread != null) {
16010                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16011                try {
16012                    proc.thread.scheduleCreateBackupAgent(app,
16013                            compatibilityInfoForPackageLocked(app), backupMode);
16014                } catch (RemoteException e) {
16015                    // Will time out on the backup manager side
16016                }
16017            } else {
16018                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16019            }
16020            // Invariants: at this point, the target app process exists and the application
16021            // is either already running or in the process of coming up.  mBackupTarget and
16022            // mBackupAppName describe the app, so that when it binds back to the AM we
16023            // know that it's scheduled for a backup-agent operation.
16024        }
16025
16026        return true;
16027    }
16028
16029    @Override
16030    public void clearPendingBackup() {
16031        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16032        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16033
16034        synchronized (this) {
16035            mBackupTarget = null;
16036            mBackupAppName = null;
16037        }
16038    }
16039
16040    // A backup agent has just come up
16041    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16042        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16043                + " = " + agent);
16044
16045        synchronized(this) {
16046            if (!agentPackageName.equals(mBackupAppName)) {
16047                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16048                return;
16049            }
16050        }
16051
16052        long oldIdent = Binder.clearCallingIdentity();
16053        try {
16054            IBackupManager bm = IBackupManager.Stub.asInterface(
16055                    ServiceManager.getService(Context.BACKUP_SERVICE));
16056            bm.agentConnected(agentPackageName, agent);
16057        } catch (RemoteException e) {
16058            // can't happen; the backup manager service is local
16059        } catch (Exception e) {
16060            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16061            e.printStackTrace();
16062        } finally {
16063            Binder.restoreCallingIdentity(oldIdent);
16064        }
16065    }
16066
16067    // done with this agent
16068    public void unbindBackupAgent(ApplicationInfo appInfo) {
16069        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16070        if (appInfo == null) {
16071            Slog.w(TAG, "unbind backup agent for null app");
16072            return;
16073        }
16074
16075        synchronized(this) {
16076            try {
16077                if (mBackupAppName == null) {
16078                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16079                    return;
16080                }
16081
16082                if (!mBackupAppName.equals(appInfo.packageName)) {
16083                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16084                    return;
16085                }
16086
16087                // Not backing this app up any more; reset its OOM adjustment
16088                final ProcessRecord proc = mBackupTarget.app;
16089                updateOomAdjLocked(proc);
16090
16091                // If the app crashed during backup, 'thread' will be null here
16092                if (proc.thread != null) {
16093                    try {
16094                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16095                                compatibilityInfoForPackageLocked(appInfo));
16096                    } catch (Exception e) {
16097                        Slog.e(TAG, "Exception when unbinding backup agent:");
16098                        e.printStackTrace();
16099                    }
16100                }
16101            } finally {
16102                mBackupTarget = null;
16103                mBackupAppName = null;
16104            }
16105        }
16106    }
16107    // =========================================================
16108    // BROADCASTS
16109    // =========================================================
16110
16111    boolean isPendingBroadcastProcessLocked(int pid) {
16112        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16113                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16114    }
16115
16116    void skipPendingBroadcastLocked(int pid) {
16117            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16118            for (BroadcastQueue queue : mBroadcastQueues) {
16119                queue.skipPendingBroadcastLocked(pid);
16120            }
16121    }
16122
16123    // The app just attached; send any pending broadcasts that it should receive
16124    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16125        boolean didSomething = false;
16126        for (BroadcastQueue queue : mBroadcastQueues) {
16127            didSomething |= queue.sendPendingBroadcastsLocked(app);
16128        }
16129        return didSomething;
16130    }
16131
16132    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16133            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16134        enforceNotIsolatedCaller("registerReceiver");
16135        ArrayList<Intent> stickyIntents = null;
16136        ProcessRecord callerApp = null;
16137        int callingUid;
16138        int callingPid;
16139        synchronized(this) {
16140            if (caller != null) {
16141                callerApp = getRecordForAppLocked(caller);
16142                if (callerApp == null) {
16143                    throw new SecurityException(
16144                            "Unable to find app for caller " + caller
16145                            + " (pid=" + Binder.getCallingPid()
16146                            + ") when registering receiver " + receiver);
16147                }
16148                if (callerApp.info.uid != Process.SYSTEM_UID &&
16149                        !callerApp.pkgList.containsKey(callerPackage) &&
16150                        !"android".equals(callerPackage)) {
16151                    throw new SecurityException("Given caller package " + callerPackage
16152                            + " is not running in process " + callerApp);
16153                }
16154                callingUid = callerApp.info.uid;
16155                callingPid = callerApp.pid;
16156            } else {
16157                callerPackage = null;
16158                callingUid = Binder.getCallingUid();
16159                callingPid = Binder.getCallingPid();
16160            }
16161
16162            userId = handleIncomingUser(callingPid, callingUid, userId,
16163                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16164
16165            Iterator<String> actions = filter.actionsIterator();
16166            if (actions == null) {
16167                ArrayList<String> noAction = new ArrayList<String>(1);
16168                noAction.add(null);
16169                actions = noAction.iterator();
16170            }
16171
16172            // Collect stickies of users
16173            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16174            while (actions.hasNext()) {
16175                String action = actions.next();
16176                for (int id : userIds) {
16177                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16178                    if (stickies != null) {
16179                        ArrayList<Intent> intents = stickies.get(action);
16180                        if (intents != null) {
16181                            if (stickyIntents == null) {
16182                                stickyIntents = new ArrayList<Intent>();
16183                            }
16184                            stickyIntents.addAll(intents);
16185                        }
16186                    }
16187                }
16188            }
16189        }
16190
16191        ArrayList<Intent> allSticky = null;
16192        if (stickyIntents != null) {
16193            final ContentResolver resolver = mContext.getContentResolver();
16194            // Look for any matching sticky broadcasts...
16195            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16196                Intent intent = stickyIntents.get(i);
16197                // If intent has scheme "content", it will need to acccess
16198                // provider that needs to lock mProviderMap in ActivityThread
16199                // and also it may need to wait application response, so we
16200                // cannot lock ActivityManagerService here.
16201                if (filter.match(resolver, intent, true, TAG) >= 0) {
16202                    if (allSticky == null) {
16203                        allSticky = new ArrayList<Intent>();
16204                    }
16205                    allSticky.add(intent);
16206                }
16207            }
16208        }
16209
16210        // The first sticky in the list is returned directly back to the client.
16211        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16212        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16213        if (receiver == null) {
16214            return sticky;
16215        }
16216
16217        synchronized (this) {
16218            if (callerApp != null && (callerApp.thread == null
16219                    || callerApp.thread.asBinder() != caller.asBinder())) {
16220                // Original caller already died
16221                return null;
16222            }
16223            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16224            if (rl == null) {
16225                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16226                        userId, receiver);
16227                if (rl.app != null) {
16228                    rl.app.receivers.add(rl);
16229                } else {
16230                    try {
16231                        receiver.asBinder().linkToDeath(rl, 0);
16232                    } catch (RemoteException e) {
16233                        return sticky;
16234                    }
16235                    rl.linkedToDeath = true;
16236                }
16237                mRegisteredReceivers.put(receiver.asBinder(), rl);
16238            } else if (rl.uid != callingUid) {
16239                throw new IllegalArgumentException(
16240                        "Receiver requested to register for uid " + callingUid
16241                        + " was previously registered for uid " + rl.uid);
16242            } else if (rl.pid != callingPid) {
16243                throw new IllegalArgumentException(
16244                        "Receiver requested to register for pid " + callingPid
16245                        + " was previously registered for pid " + rl.pid);
16246            } else if (rl.userId != userId) {
16247                throw new IllegalArgumentException(
16248                        "Receiver requested to register for user " + userId
16249                        + " was previously registered for user " + rl.userId);
16250            }
16251            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16252                    permission, callingUid, userId);
16253            rl.add(bf);
16254            if (!bf.debugCheck()) {
16255                Slog.w(TAG, "==> For Dynamic broadcast");
16256            }
16257            mReceiverResolver.addFilter(bf);
16258
16259            // Enqueue broadcasts for all existing stickies that match
16260            // this filter.
16261            if (allSticky != null) {
16262                ArrayList receivers = new ArrayList();
16263                receivers.add(bf);
16264
16265                final int stickyCount = allSticky.size();
16266                for (int i = 0; i < stickyCount; i++) {
16267                    Intent intent = allSticky.get(i);
16268                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16269                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16270                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16271                            null, 0, null, null, false, true, true, -1);
16272                    queue.enqueueParallelBroadcastLocked(r);
16273                    queue.scheduleBroadcastsLocked();
16274                }
16275            }
16276
16277            return sticky;
16278        }
16279    }
16280
16281    public void unregisterReceiver(IIntentReceiver receiver) {
16282        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16283
16284        final long origId = Binder.clearCallingIdentity();
16285        try {
16286            boolean doTrim = false;
16287
16288            synchronized(this) {
16289                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16290                if (rl != null) {
16291                    final BroadcastRecord r = rl.curBroadcast;
16292                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16293                        final boolean doNext = r.queue.finishReceiverLocked(
16294                                r, r.resultCode, r.resultData, r.resultExtras,
16295                                r.resultAbort, false);
16296                        if (doNext) {
16297                            doTrim = true;
16298                            r.queue.processNextBroadcast(false);
16299                        }
16300                    }
16301
16302                    if (rl.app != null) {
16303                        rl.app.receivers.remove(rl);
16304                    }
16305                    removeReceiverLocked(rl);
16306                    if (rl.linkedToDeath) {
16307                        rl.linkedToDeath = false;
16308                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16309                    }
16310                }
16311            }
16312
16313            // If we actually concluded any broadcasts, we might now be able
16314            // to trim the recipients' apps from our working set
16315            if (doTrim) {
16316                trimApplications();
16317                return;
16318            }
16319
16320        } finally {
16321            Binder.restoreCallingIdentity(origId);
16322        }
16323    }
16324
16325    void removeReceiverLocked(ReceiverList rl) {
16326        mRegisteredReceivers.remove(rl.receiver.asBinder());
16327        for (int i = rl.size() - 1; i >= 0; i--) {
16328            mReceiverResolver.removeFilter(rl.get(i));
16329        }
16330    }
16331
16332    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16333        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16334            ProcessRecord r = mLruProcesses.get(i);
16335            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16336                try {
16337                    r.thread.dispatchPackageBroadcast(cmd, packages);
16338                } catch (RemoteException ex) {
16339                }
16340            }
16341        }
16342    }
16343
16344    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16345            int callingUid, int[] users) {
16346        List<ResolveInfo> receivers = null;
16347        try {
16348            HashSet<ComponentName> singleUserReceivers = null;
16349            boolean scannedFirstReceivers = false;
16350            for (int user : users) {
16351                // Skip users that have Shell restrictions
16352                if (callingUid == Process.SHELL_UID
16353                        && getUserManagerLocked().hasUserRestriction(
16354                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16355                    continue;
16356                }
16357                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16358                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16359                if (user != UserHandle.USER_OWNER && newReceivers != null) {
16360                    // If this is not the primary user, we need to check for
16361                    // any receivers that should be filtered out.
16362                    for (int i=0; i<newReceivers.size(); i++) {
16363                        ResolveInfo ri = newReceivers.get(i);
16364                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16365                            newReceivers.remove(i);
16366                            i--;
16367                        }
16368                    }
16369                }
16370                if (newReceivers != null && newReceivers.size() == 0) {
16371                    newReceivers = null;
16372                }
16373                if (receivers == null) {
16374                    receivers = newReceivers;
16375                } else if (newReceivers != null) {
16376                    // We need to concatenate the additional receivers
16377                    // found with what we have do far.  This would be easy,
16378                    // but we also need to de-dup any receivers that are
16379                    // singleUser.
16380                    if (!scannedFirstReceivers) {
16381                        // Collect any single user receivers we had already retrieved.
16382                        scannedFirstReceivers = true;
16383                        for (int i=0; i<receivers.size(); i++) {
16384                            ResolveInfo ri = receivers.get(i);
16385                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16386                                ComponentName cn = new ComponentName(
16387                                        ri.activityInfo.packageName, ri.activityInfo.name);
16388                                if (singleUserReceivers == null) {
16389                                    singleUserReceivers = new HashSet<ComponentName>();
16390                                }
16391                                singleUserReceivers.add(cn);
16392                            }
16393                        }
16394                    }
16395                    // Add the new results to the existing results, tracking
16396                    // and de-dupping single user receivers.
16397                    for (int i=0; i<newReceivers.size(); i++) {
16398                        ResolveInfo ri = newReceivers.get(i);
16399                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16400                            ComponentName cn = new ComponentName(
16401                                    ri.activityInfo.packageName, ri.activityInfo.name);
16402                            if (singleUserReceivers == null) {
16403                                singleUserReceivers = new HashSet<ComponentName>();
16404                            }
16405                            if (!singleUserReceivers.contains(cn)) {
16406                                singleUserReceivers.add(cn);
16407                                receivers.add(ri);
16408                            }
16409                        } else {
16410                            receivers.add(ri);
16411                        }
16412                    }
16413                }
16414            }
16415        } catch (RemoteException ex) {
16416            // pm is in same process, this will never happen.
16417        }
16418        return receivers;
16419    }
16420
16421    private final int broadcastIntentLocked(ProcessRecord callerApp,
16422            String callerPackage, Intent intent, String resolvedType,
16423            IIntentReceiver resultTo, int resultCode, String resultData,
16424            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
16425            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16426        intent = new Intent(intent);
16427
16428        // By default broadcasts do not go to stopped apps.
16429        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16430
16431        // If we have not finished booting, don't allow this to launch new processes.
16432        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16433            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16434        }
16435
16436        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16437                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16438                + " ordered=" + ordered + " userid=" + userId);
16439        if ((resultTo != null) && !ordered) {
16440            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16441        }
16442
16443        userId = handleIncomingUser(callingPid, callingUid, userId,
16444                true, ALLOW_NON_FULL, "broadcast", callerPackage);
16445
16446        // Make sure that the user who is receiving this broadcast is running.
16447        // If not, we will just skip it. Make an exception for shutdown broadcasts
16448        // and upgrade steps.
16449
16450        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16451            if ((callingUid != Process.SYSTEM_UID
16452                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16453                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16454                Slog.w(TAG, "Skipping broadcast of " + intent
16455                        + ": user " + userId + " is stopped");
16456                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16457            }
16458        }
16459
16460        BroadcastOptions brOptions = null;
16461        if (options != null) {
16462            brOptions = new BroadcastOptions(options);
16463            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16464                // See if the caller is allowed to do this.  Note we are checking against
16465                // the actual real caller (not whoever provided the operation as say a
16466                // PendingIntent), because that who is actually supplied the arguments.
16467                if (checkComponentPermission(
16468                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16469                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16470                        != PackageManager.PERMISSION_GRANTED) {
16471                    String msg = "Permission Denial: " + intent.getAction()
16472                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16473                            + ", uid=" + callingUid + ")"
16474                            + " requires "
16475                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16476                    Slog.w(TAG, msg);
16477                    throw new SecurityException(msg);
16478                }
16479            }
16480        }
16481
16482        /*
16483         * Prevent non-system code (defined here to be non-persistent
16484         * processes) from sending protected broadcasts.
16485         */
16486        int callingAppId = UserHandle.getAppId(callingUid);
16487        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16488            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16489            || callingAppId == Process.NFC_UID || callingUid == 0) {
16490            // Always okay.
16491        } else if (callerApp == null || !callerApp.persistent) {
16492            try {
16493                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16494                        intent.getAction())) {
16495                    String msg = "Permission Denial: not allowed to send broadcast "
16496                            + intent.getAction() + " from pid="
16497                            + callingPid + ", uid=" + callingUid;
16498                    Slog.w(TAG, msg);
16499                    throw new SecurityException(msg);
16500                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16501                    // Special case for compatibility: we don't want apps to send this,
16502                    // but historically it has not been protected and apps may be using it
16503                    // to poke their own app widget.  So, instead of making it protected,
16504                    // just limit it to the caller.
16505                    if (callerApp == null) {
16506                        String msg = "Permission Denial: not allowed to send broadcast "
16507                                + intent.getAction() + " from unknown caller.";
16508                        Slog.w(TAG, msg);
16509                        throw new SecurityException(msg);
16510                    } else if (intent.getComponent() != null) {
16511                        // They are good enough to send to an explicit component...  verify
16512                        // it is being sent to the calling app.
16513                        if (!intent.getComponent().getPackageName().equals(
16514                                callerApp.info.packageName)) {
16515                            String msg = "Permission Denial: not allowed to send broadcast "
16516                                    + intent.getAction() + " to "
16517                                    + intent.getComponent().getPackageName() + " from "
16518                                    + callerApp.info.packageName;
16519                            Slog.w(TAG, msg);
16520                            throw new SecurityException(msg);
16521                        }
16522                    } else {
16523                        // Limit broadcast to their own package.
16524                        intent.setPackage(callerApp.info.packageName);
16525                    }
16526                }
16527            } catch (RemoteException e) {
16528                Slog.w(TAG, "Remote exception", e);
16529                return ActivityManager.BROADCAST_SUCCESS;
16530            }
16531        }
16532
16533        final String action = intent.getAction();
16534        if (action != null) {
16535            switch (action) {
16536                case Intent.ACTION_UID_REMOVED:
16537                case Intent.ACTION_PACKAGE_REMOVED:
16538                case Intent.ACTION_PACKAGE_CHANGED:
16539                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16540                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16541                    // Handle special intents: if this broadcast is from the package
16542                    // manager about a package being removed, we need to remove all of
16543                    // its activities from the history stack.
16544                    if (checkComponentPermission(
16545                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16546                            callingPid, callingUid, -1, true)
16547                            != PackageManager.PERMISSION_GRANTED) {
16548                        String msg = "Permission Denial: " + intent.getAction()
16549                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16550                                + ", uid=" + callingUid + ")"
16551                                + " requires "
16552                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16553                        Slog.w(TAG, msg);
16554                        throw new SecurityException(msg);
16555                    }
16556                    switch (action) {
16557                        case Intent.ACTION_UID_REMOVED:
16558                            final Bundle intentExtras = intent.getExtras();
16559                            final int uid = intentExtras != null
16560                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16561                            if (uid >= 0) {
16562                                mBatteryStatsService.removeUid(uid);
16563                                mAppOpsService.uidRemoved(uid);
16564                            }
16565                            break;
16566                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16567                            // If resources are unavailable just force stop all those packages
16568                            // and flush the attribute cache as well.
16569                            String list[] =
16570                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16571                            if (list != null && list.length > 0) {
16572                                for (int i = 0; i < list.length; i++) {
16573                                    forceStopPackageLocked(list[i], -1, false, true, true,
16574                                            false, false, userId, "storage unmount");
16575                                }
16576                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16577                                sendPackageBroadcastLocked(
16578                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16579                                        userId);
16580                            }
16581                            break;
16582                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16583                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16584                            break;
16585                        case Intent.ACTION_PACKAGE_REMOVED:
16586                        case Intent.ACTION_PACKAGE_CHANGED:
16587                            Uri data = intent.getData();
16588                            String ssp;
16589                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16590                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16591                                boolean fullUninstall = removed &&
16592                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16593                                final boolean killProcess =
16594                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
16595                                if (killProcess) {
16596                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16597                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16598                                            false, true, true, false, fullUninstall, userId,
16599                                            removed ? "pkg removed" : "pkg changed");
16600                                }
16601                                if (removed) {
16602                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16603                                            new String[] {ssp}, userId);
16604                                    if (fullUninstall) {
16605                                        mAppOpsService.packageRemoved(
16606                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16607
16608                                        // Remove all permissions granted from/to this package
16609                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16610
16611                                        removeTasksByPackageNameLocked(ssp, userId);
16612                                        mBatteryStatsService.notePackageUninstalled(ssp);
16613                                    }
16614                                } else {
16615                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
16616                                            intent.getStringArrayExtra(
16617                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16618                                }
16619                            }
16620                            break;
16621                    }
16622                    break;
16623                case Intent.ACTION_PACKAGE_ADDED:
16624                    // Special case for adding a package: by default turn on compatibility mode.
16625                    Uri data = intent.getData();
16626                    String ssp;
16627                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16628                        final boolean replacing =
16629                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16630                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16631
16632                        try {
16633                            ApplicationInfo ai = AppGlobals.getPackageManager().
16634                                    getApplicationInfo(ssp, 0, 0);
16635                            mBatteryStatsService.notePackageInstalled(ssp,
16636                                    ai != null ? ai.versionCode : 0);
16637                        } catch (RemoteException e) {
16638                        }
16639                    }
16640                    break;
16641                case Intent.ACTION_TIMEZONE_CHANGED:
16642                    // If this is the time zone changed action, queue up a message that will reset
16643                    // the timezone of all currently running processes. This message will get
16644                    // queued up before the broadcast happens.
16645                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16646                    break;
16647                case Intent.ACTION_TIME_CHANGED:
16648                    // If the user set the time, let all running processes know.
16649                    final int is24Hour =
16650                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16651                                    : 0;
16652                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16653                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16654                    synchronized (stats) {
16655                        stats.noteCurrentTimeChangedLocked();
16656                    }
16657                    break;
16658                case Intent.ACTION_CLEAR_DNS_CACHE:
16659                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16660                    break;
16661                case Proxy.PROXY_CHANGE_ACTION:
16662                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16663                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16664                    break;
16665            }
16666        }
16667
16668        // Add to the sticky list if requested.
16669        if (sticky) {
16670            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16671                    callingPid, callingUid)
16672                    != PackageManager.PERMISSION_GRANTED) {
16673                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16674                        + callingPid + ", uid=" + callingUid
16675                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16676                Slog.w(TAG, msg);
16677                throw new SecurityException(msg);
16678            }
16679            if (requiredPermissions != null && requiredPermissions.length > 0) {
16680                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16681                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
16682                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16683            }
16684            if (intent.getComponent() != null) {
16685                throw new SecurityException(
16686                        "Sticky broadcasts can't target a specific component");
16687            }
16688            // We use userId directly here, since the "all" target is maintained
16689            // as a separate set of sticky broadcasts.
16690            if (userId != UserHandle.USER_ALL) {
16691                // But first, if this is not a broadcast to all users, then
16692                // make sure it doesn't conflict with an existing broadcast to
16693                // all users.
16694                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16695                        UserHandle.USER_ALL);
16696                if (stickies != null) {
16697                    ArrayList<Intent> list = stickies.get(intent.getAction());
16698                    if (list != null) {
16699                        int N = list.size();
16700                        int i;
16701                        for (i=0; i<N; i++) {
16702                            if (intent.filterEquals(list.get(i))) {
16703                                throw new IllegalArgumentException(
16704                                        "Sticky broadcast " + intent + " for user "
16705                                        + userId + " conflicts with existing global broadcast");
16706                            }
16707                        }
16708                    }
16709                }
16710            }
16711            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16712            if (stickies == null) {
16713                stickies = new ArrayMap<>();
16714                mStickyBroadcasts.put(userId, stickies);
16715            }
16716            ArrayList<Intent> list = stickies.get(intent.getAction());
16717            if (list == null) {
16718                list = new ArrayList<>();
16719                stickies.put(intent.getAction(), list);
16720            }
16721            final int stickiesCount = list.size();
16722            int i;
16723            for (i = 0; i < stickiesCount; i++) {
16724                if (intent.filterEquals(list.get(i))) {
16725                    // This sticky already exists, replace it.
16726                    list.set(i, new Intent(intent));
16727                    break;
16728                }
16729            }
16730            if (i >= stickiesCount) {
16731                list.add(new Intent(intent));
16732            }
16733        }
16734
16735        int[] users;
16736        if (userId == UserHandle.USER_ALL) {
16737            // Caller wants broadcast to go to all started users.
16738            users = mStartedUserArray;
16739        } else {
16740            // Caller wants broadcast to go to one specific user.
16741            users = new int[] {userId};
16742        }
16743
16744        // Figure out who all will receive this broadcast.
16745        List receivers = null;
16746        List<BroadcastFilter> registeredReceivers = null;
16747        // Need to resolve the intent to interested receivers...
16748        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16749                 == 0) {
16750            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16751        }
16752        if (intent.getComponent() == null) {
16753            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16754                // Query one target user at a time, excluding shell-restricted users
16755                UserManagerService ums = getUserManagerLocked();
16756                for (int i = 0; i < users.length; i++) {
16757                    if (ums.hasUserRestriction(
16758                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16759                        continue;
16760                    }
16761                    List<BroadcastFilter> registeredReceiversForUser =
16762                            mReceiverResolver.queryIntent(intent,
16763                                    resolvedType, false, users[i]);
16764                    if (registeredReceivers == null) {
16765                        registeredReceivers = registeredReceiversForUser;
16766                    } else if (registeredReceiversForUser != null) {
16767                        registeredReceivers.addAll(registeredReceiversForUser);
16768                    }
16769                }
16770            } else {
16771                registeredReceivers = mReceiverResolver.queryIntent(intent,
16772                        resolvedType, false, userId);
16773            }
16774        }
16775
16776        final boolean replacePending =
16777                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16778
16779        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16780                + " replacePending=" + replacePending);
16781
16782        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16783        if (!ordered && NR > 0) {
16784            // If we are not serializing this broadcast, then send the
16785            // registered receivers separately so they don't wait for the
16786            // components to be launched.
16787            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16788            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16789                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
16790                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16791                    resultExtras, ordered, sticky, false, userId);
16792            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16793            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16794            if (!replaced) {
16795                queue.enqueueParallelBroadcastLocked(r);
16796                queue.scheduleBroadcastsLocked();
16797            }
16798            registeredReceivers = null;
16799            NR = 0;
16800        }
16801
16802        // Merge into one list.
16803        int ir = 0;
16804        if (receivers != null) {
16805            // A special case for PACKAGE_ADDED: do not allow the package
16806            // being added to see this broadcast.  This prevents them from
16807            // using this as a back door to get run as soon as they are
16808            // installed.  Maybe in the future we want to have a special install
16809            // broadcast or such for apps, but we'd like to deliberately make
16810            // this decision.
16811            String skipPackages[] = null;
16812            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16813                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16814                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16815                Uri data = intent.getData();
16816                if (data != null) {
16817                    String pkgName = data.getSchemeSpecificPart();
16818                    if (pkgName != null) {
16819                        skipPackages = new String[] { pkgName };
16820                    }
16821                }
16822            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16823                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16824            }
16825            if (skipPackages != null && (skipPackages.length > 0)) {
16826                for (String skipPackage : skipPackages) {
16827                    if (skipPackage != null) {
16828                        int NT = receivers.size();
16829                        for (int it=0; it<NT; it++) {
16830                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16831                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16832                                receivers.remove(it);
16833                                it--;
16834                                NT--;
16835                            }
16836                        }
16837                    }
16838                }
16839            }
16840
16841            int NT = receivers != null ? receivers.size() : 0;
16842            int it = 0;
16843            ResolveInfo curt = null;
16844            BroadcastFilter curr = null;
16845            while (it < NT && ir < NR) {
16846                if (curt == null) {
16847                    curt = (ResolveInfo)receivers.get(it);
16848                }
16849                if (curr == null) {
16850                    curr = registeredReceivers.get(ir);
16851                }
16852                if (curr.getPriority() >= curt.priority) {
16853                    // Insert this broadcast record into the final list.
16854                    receivers.add(it, curr);
16855                    ir++;
16856                    curr = null;
16857                    it++;
16858                    NT++;
16859                } else {
16860                    // Skip to the next ResolveInfo in the final list.
16861                    it++;
16862                    curt = null;
16863                }
16864            }
16865        }
16866        while (ir < NR) {
16867            if (receivers == null) {
16868                receivers = new ArrayList();
16869            }
16870            receivers.add(registeredReceivers.get(ir));
16871            ir++;
16872        }
16873
16874        if ((receivers != null && receivers.size() > 0)
16875                || resultTo != null) {
16876            BroadcastQueue queue = broadcastQueueForIntent(intent);
16877            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16878                    callerPackage, callingPid, callingUid, resolvedType,
16879                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
16880                    resultData, resultExtras, ordered, sticky, false, userId);
16881
16882            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16883                    + ": prev had " + queue.mOrderedBroadcasts.size());
16884            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16885                    "Enqueueing broadcast " + r.intent.getAction());
16886
16887            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16888            if (!replaced) {
16889                queue.enqueueOrderedBroadcastLocked(r);
16890                queue.scheduleBroadcastsLocked();
16891            }
16892        }
16893
16894        return ActivityManager.BROADCAST_SUCCESS;
16895    }
16896
16897    final Intent verifyBroadcastLocked(Intent intent) {
16898        // Refuse possible leaked file descriptors
16899        if (intent != null && intent.hasFileDescriptors() == true) {
16900            throw new IllegalArgumentException("File descriptors passed in Intent");
16901        }
16902
16903        int flags = intent.getFlags();
16904
16905        if (!mProcessesReady) {
16906            // if the caller really truly claims to know what they're doing, go
16907            // ahead and allow the broadcast without launching any receivers
16908            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16909                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16910            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16911                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16912                        + " before boot completion");
16913                throw new IllegalStateException("Cannot broadcast before boot completed");
16914            }
16915        }
16916
16917        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16918            throw new IllegalArgumentException(
16919                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16920        }
16921
16922        return intent;
16923    }
16924
16925    public final int broadcastIntent(IApplicationThread caller,
16926            Intent intent, String resolvedType, IIntentReceiver resultTo,
16927            int resultCode, String resultData, Bundle resultExtras,
16928            String[] requiredPermissions, int appOp, Bundle options,
16929            boolean serialized, boolean sticky, int userId) {
16930        enforceNotIsolatedCaller("broadcastIntent");
16931        synchronized(this) {
16932            intent = verifyBroadcastLocked(intent);
16933
16934            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16935            final int callingPid = Binder.getCallingPid();
16936            final int callingUid = Binder.getCallingUid();
16937            final long origId = Binder.clearCallingIdentity();
16938            int res = broadcastIntentLocked(callerApp,
16939                    callerApp != null ? callerApp.info.packageName : null,
16940                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
16941                    requiredPermissions, appOp, null, serialized, sticky,
16942                    callingPid, callingUid, userId);
16943            Binder.restoreCallingIdentity(origId);
16944            return res;
16945        }
16946    }
16947
16948
16949    int broadcastIntentInPackage(String packageName, int uid,
16950            Intent intent, String resolvedType, IIntentReceiver resultTo,
16951            int resultCode, String resultData, Bundle resultExtras,
16952            String requiredPermission, Bundle options, boolean serialized, boolean sticky,
16953            int userId) {
16954        synchronized(this) {
16955            intent = verifyBroadcastLocked(intent);
16956
16957            final long origId = Binder.clearCallingIdentity();
16958            String[] requiredPermissions = requiredPermission == null ? null
16959                    : new String[] {requiredPermission};
16960            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16961                    resultTo, resultCode, resultData, resultExtras,
16962                    requiredPermissions, AppOpsManager.OP_NONE, options, serialized,
16963                    sticky, -1, uid, userId);
16964            Binder.restoreCallingIdentity(origId);
16965            return res;
16966        }
16967    }
16968
16969    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16970        // Refuse possible leaked file descriptors
16971        if (intent != null && intent.hasFileDescriptors() == true) {
16972            throw new IllegalArgumentException("File descriptors passed in Intent");
16973        }
16974
16975        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16976                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16977
16978        synchronized(this) {
16979            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16980                    != PackageManager.PERMISSION_GRANTED) {
16981                String msg = "Permission Denial: unbroadcastIntent() from pid="
16982                        + Binder.getCallingPid()
16983                        + ", uid=" + Binder.getCallingUid()
16984                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16985                Slog.w(TAG, msg);
16986                throw new SecurityException(msg);
16987            }
16988            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16989            if (stickies != null) {
16990                ArrayList<Intent> list = stickies.get(intent.getAction());
16991                if (list != null) {
16992                    int N = list.size();
16993                    int i;
16994                    for (i=0; i<N; i++) {
16995                        if (intent.filterEquals(list.get(i))) {
16996                            list.remove(i);
16997                            break;
16998                        }
16999                    }
17000                    if (list.size() <= 0) {
17001                        stickies.remove(intent.getAction());
17002                    }
17003                }
17004                if (stickies.size() <= 0) {
17005                    mStickyBroadcasts.remove(userId);
17006                }
17007            }
17008        }
17009    }
17010
17011    void backgroundServicesFinishedLocked(int userId) {
17012        for (BroadcastQueue queue : mBroadcastQueues) {
17013            queue.backgroundServicesFinishedLocked(userId);
17014        }
17015    }
17016
17017    public void finishReceiver(IBinder who, int resultCode, String resultData,
17018            Bundle resultExtras, boolean resultAbort, int flags) {
17019        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17020
17021        // Refuse possible leaked file descriptors
17022        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17023            throw new IllegalArgumentException("File descriptors passed in Bundle");
17024        }
17025
17026        final long origId = Binder.clearCallingIdentity();
17027        try {
17028            boolean doNext = false;
17029            BroadcastRecord r;
17030
17031            synchronized(this) {
17032                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17033                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17034                r = queue.getMatchingOrderedReceiver(who);
17035                if (r != null) {
17036                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17037                        resultData, resultExtras, resultAbort, true);
17038                }
17039            }
17040
17041            if (doNext) {
17042                r.queue.processNextBroadcast(false);
17043            }
17044            trimApplications();
17045        } finally {
17046            Binder.restoreCallingIdentity(origId);
17047        }
17048    }
17049
17050    // =========================================================
17051    // INSTRUMENTATION
17052    // =========================================================
17053
17054    public boolean startInstrumentation(ComponentName className,
17055            String profileFile, int flags, Bundle arguments,
17056            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17057            int userId, String abiOverride) {
17058        enforceNotIsolatedCaller("startInstrumentation");
17059        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17060                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17061        // Refuse possible leaked file descriptors
17062        if (arguments != null && arguments.hasFileDescriptors()) {
17063            throw new IllegalArgumentException("File descriptors passed in Bundle");
17064        }
17065
17066        synchronized(this) {
17067            InstrumentationInfo ii = null;
17068            ApplicationInfo ai = null;
17069            try {
17070                ii = mContext.getPackageManager().getInstrumentationInfo(
17071                    className, STOCK_PM_FLAGS);
17072                ai = AppGlobals.getPackageManager().getApplicationInfo(
17073                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17074            } catch (PackageManager.NameNotFoundException e) {
17075            } catch (RemoteException e) {
17076            }
17077            if (ii == null) {
17078                reportStartInstrumentationFailure(watcher, className,
17079                        "Unable to find instrumentation info for: " + className);
17080                return false;
17081            }
17082            if (ai == null) {
17083                reportStartInstrumentationFailure(watcher, className,
17084                        "Unable to find instrumentation target package: " + ii.targetPackage);
17085                return false;
17086            }
17087
17088            int match = mContext.getPackageManager().checkSignatures(
17089                    ii.targetPackage, ii.packageName);
17090            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17091                String msg = "Permission Denial: starting instrumentation "
17092                        + className + " from pid="
17093                        + Binder.getCallingPid()
17094                        + ", uid=" + Binder.getCallingPid()
17095                        + " not allowed because package " + ii.packageName
17096                        + " does not have a signature matching the target "
17097                        + ii.targetPackage;
17098                reportStartInstrumentationFailure(watcher, className, msg);
17099                throw new SecurityException(msg);
17100            }
17101
17102            final long origId = Binder.clearCallingIdentity();
17103            // Instrumentation can kill and relaunch even persistent processes
17104            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17105                    "start instr");
17106            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17107            app.instrumentationClass = className;
17108            app.instrumentationInfo = ai;
17109            app.instrumentationProfileFile = profileFile;
17110            app.instrumentationArguments = arguments;
17111            app.instrumentationWatcher = watcher;
17112            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17113            app.instrumentationResultClass = className;
17114            Binder.restoreCallingIdentity(origId);
17115        }
17116
17117        return true;
17118    }
17119
17120    /**
17121     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17122     * error to the logs, but if somebody is watching, send the report there too.  This enables
17123     * the "am" command to report errors with more information.
17124     *
17125     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17126     * @param cn The component name of the instrumentation.
17127     * @param report The error report.
17128     */
17129    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17130            ComponentName cn, String report) {
17131        Slog.w(TAG, report);
17132        try {
17133            if (watcher != null) {
17134                Bundle results = new Bundle();
17135                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17136                results.putString("Error", report);
17137                watcher.instrumentationStatus(cn, -1, results);
17138            }
17139        } catch (RemoteException e) {
17140            Slog.w(TAG, e);
17141        }
17142    }
17143
17144    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17145        if (app.instrumentationWatcher != null) {
17146            try {
17147                // NOTE:  IInstrumentationWatcher *must* be oneway here
17148                app.instrumentationWatcher.instrumentationFinished(
17149                    app.instrumentationClass,
17150                    resultCode,
17151                    results);
17152            } catch (RemoteException e) {
17153            }
17154        }
17155
17156        // Can't call out of the system process with a lock held, so post a message.
17157        if (app.instrumentationUiAutomationConnection != null) {
17158            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17159                    app.instrumentationUiAutomationConnection).sendToTarget();
17160        }
17161
17162        app.instrumentationWatcher = null;
17163        app.instrumentationUiAutomationConnection = null;
17164        app.instrumentationClass = null;
17165        app.instrumentationInfo = null;
17166        app.instrumentationProfileFile = null;
17167        app.instrumentationArguments = null;
17168
17169        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17170                "finished inst");
17171    }
17172
17173    public void finishInstrumentation(IApplicationThread target,
17174            int resultCode, Bundle results) {
17175        int userId = UserHandle.getCallingUserId();
17176        // Refuse possible leaked file descriptors
17177        if (results != null && results.hasFileDescriptors()) {
17178            throw new IllegalArgumentException("File descriptors passed in Intent");
17179        }
17180
17181        synchronized(this) {
17182            ProcessRecord app = getRecordForAppLocked(target);
17183            if (app == null) {
17184                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17185                return;
17186            }
17187            final long origId = Binder.clearCallingIdentity();
17188            finishInstrumentationLocked(app, resultCode, results);
17189            Binder.restoreCallingIdentity(origId);
17190        }
17191    }
17192
17193    // =========================================================
17194    // CONFIGURATION
17195    // =========================================================
17196
17197    public ConfigurationInfo getDeviceConfigurationInfo() {
17198        ConfigurationInfo config = new ConfigurationInfo();
17199        synchronized (this) {
17200            config.reqTouchScreen = mConfiguration.touchscreen;
17201            config.reqKeyboardType = mConfiguration.keyboard;
17202            config.reqNavigation = mConfiguration.navigation;
17203            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17204                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17205                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17206            }
17207            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17208                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17209                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17210            }
17211            config.reqGlEsVersion = GL_ES_VERSION;
17212        }
17213        return config;
17214    }
17215
17216    ActivityStack getFocusedStack() {
17217        return mStackSupervisor.getFocusedStack();
17218    }
17219
17220    @Override
17221    public int getFocusedStackId() throws RemoteException {
17222        ActivityStack focusedStack = getFocusedStack();
17223        if (focusedStack != null) {
17224            return focusedStack.getStackId();
17225        }
17226        return -1;
17227    }
17228
17229    public Configuration getConfiguration() {
17230        Configuration ci;
17231        synchronized(this) {
17232            ci = new Configuration(mConfiguration);
17233            ci.userSetLocale = false;
17234        }
17235        return ci;
17236    }
17237
17238    public void updatePersistentConfiguration(Configuration values) {
17239        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17240                "updateConfiguration()");
17241        enforceWriteSettingsPermission("updateConfiguration()");
17242        if (values == null) {
17243            throw new NullPointerException("Configuration must not be null");
17244        }
17245
17246        synchronized(this) {
17247            final long origId = Binder.clearCallingIdentity();
17248            updateConfigurationLocked(values, null, true, false);
17249            Binder.restoreCallingIdentity(origId);
17250        }
17251    }
17252
17253    private void enforceWriteSettingsPermission(String func) {
17254        int uid = Binder.getCallingUid();
17255        if (uid == Process.ROOT_UID) {
17256            return;
17257        }
17258
17259        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17260                Settings.getPackageNameForUid(mContext, uid), false)) {
17261            return;
17262        }
17263
17264        String msg = "Permission Denial: " + func + " from pid="
17265                + Binder.getCallingPid()
17266                + ", uid=" + uid
17267                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17268        Slog.w(TAG, msg);
17269        throw new SecurityException(msg);
17270    }
17271
17272    public void updateConfiguration(Configuration values) {
17273        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17274                "updateConfiguration()");
17275
17276        synchronized(this) {
17277            if (values == null && mWindowManager != null) {
17278                // sentinel: fetch the current configuration from the window manager
17279                values = mWindowManager.computeNewConfiguration();
17280            }
17281
17282            if (mWindowManager != null) {
17283                mProcessList.applyDisplaySize(mWindowManager);
17284            }
17285
17286            final long origId = Binder.clearCallingIdentity();
17287            if (values != null) {
17288                Settings.System.clearConfiguration(values);
17289            }
17290            updateConfigurationLocked(values, null, false, false);
17291            Binder.restoreCallingIdentity(origId);
17292        }
17293    }
17294
17295    /**
17296     * Do either or both things: (1) change the current configuration, and (2)
17297     * make sure the given activity is running with the (now) current
17298     * configuration.  Returns true if the activity has been left running, or
17299     * false if <var>starting</var> is being destroyed to match the new
17300     * configuration.
17301     * @param persistent TODO
17302     */
17303    boolean updateConfigurationLocked(Configuration values,
17304            ActivityRecord starting, boolean persistent, boolean initLocale) {
17305        int changes = 0;
17306
17307        if (values != null) {
17308            Configuration newConfig = new Configuration(mConfiguration);
17309            changes = newConfig.updateFrom(values);
17310            if (changes != 0) {
17311                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17312                        "Updating configuration to: " + values);
17313
17314                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17315
17316                if (!initLocale && values.locale != null && values.userSetLocale) {
17317                    final String languageTag = values.locale.toLanguageTag();
17318                    SystemProperties.set("persist.sys.locale", languageTag);
17319                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17320                            values.locale));
17321                }
17322
17323                mConfigurationSeq++;
17324                if (mConfigurationSeq <= 0) {
17325                    mConfigurationSeq = 1;
17326                }
17327                newConfig.seq = mConfigurationSeq;
17328                mConfiguration = newConfig;
17329                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17330                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17331                //mUsageStatsService.noteStartConfig(newConfig);
17332
17333                final Configuration configCopy = new Configuration(mConfiguration);
17334
17335                // TODO: If our config changes, should we auto dismiss any currently
17336                // showing dialogs?
17337                mShowDialogs = shouldShowDialogs(newConfig);
17338
17339                AttributeCache ac = AttributeCache.instance();
17340                if (ac != null) {
17341                    ac.updateConfiguration(configCopy);
17342                }
17343
17344                // Make sure all resources in our process are updated
17345                // right now, so that anyone who is going to retrieve
17346                // resource values after we return will be sure to get
17347                // the new ones.  This is especially important during
17348                // boot, where the first config change needs to guarantee
17349                // all resources have that config before following boot
17350                // code is executed.
17351                mSystemThread.applyConfigurationToResources(configCopy);
17352
17353                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17354                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17355                    msg.obj = new Configuration(configCopy);
17356                    mHandler.sendMessage(msg);
17357                }
17358
17359                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17360                    ProcessRecord app = mLruProcesses.get(i);
17361                    try {
17362                        if (app.thread != null) {
17363                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17364                                    + app.processName + " new config " + mConfiguration);
17365                            app.thread.scheduleConfigurationChanged(configCopy);
17366                        }
17367                    } catch (Exception e) {
17368                    }
17369                }
17370                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17371                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17372                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17373                        | Intent.FLAG_RECEIVER_FOREGROUND);
17374                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17375                        null, AppOpsManager.OP_NONE, null, false, false,
17376                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17377                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17378                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17379                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17380                    if (!mProcessesReady) {
17381                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17382                    }
17383                    broadcastIntentLocked(null, null, intent,
17384                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17385                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17386                }
17387            }
17388        }
17389
17390        boolean kept = true;
17391        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17392        // mainStack is null during startup.
17393        if (mainStack != null) {
17394            if (changes != 0 && starting == null) {
17395                // If the configuration changed, and the caller is not already
17396                // in the process of starting an activity, then find the top
17397                // activity to check if its configuration needs to change.
17398                starting = mainStack.topRunningActivityLocked(null);
17399            }
17400
17401            if (starting != null) {
17402                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17403                // And we need to make sure at this point that all other activities
17404                // are made visible with the correct configuration.
17405                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17406            }
17407        }
17408
17409        if (values != null && mWindowManager != null) {
17410            mWindowManager.setNewConfiguration(mConfiguration);
17411        }
17412
17413        return kept;
17414    }
17415
17416    /**
17417     * Decide based on the configuration whether we should shouw the ANR,
17418     * crash, etc dialogs.  The idea is that if there is no affordnace to
17419     * press the on-screen buttons, we shouldn't show the dialog.
17420     *
17421     * A thought: SystemUI might also want to get told about this, the Power
17422     * dialog / global actions also might want different behaviors.
17423     */
17424    private static final boolean shouldShowDialogs(Configuration config) {
17425        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17426                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17427                && config.navigation == Configuration.NAVIGATION_NONAV);
17428    }
17429
17430    @Override
17431    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17432        synchronized (this) {
17433            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17434            if (srec != null) {
17435                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17436            }
17437        }
17438        return false;
17439    }
17440
17441    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17442            Intent resultData) {
17443
17444        synchronized (this) {
17445            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17446            if (r != null) {
17447                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17448            }
17449            return false;
17450        }
17451    }
17452
17453    public int getLaunchedFromUid(IBinder activityToken) {
17454        ActivityRecord srec;
17455        synchronized (this) {
17456            srec = ActivityRecord.forTokenLocked(activityToken);
17457        }
17458        if (srec == null) {
17459            return -1;
17460        }
17461        return srec.launchedFromUid;
17462    }
17463
17464    public String getLaunchedFromPackage(IBinder activityToken) {
17465        ActivityRecord srec;
17466        synchronized (this) {
17467            srec = ActivityRecord.forTokenLocked(activityToken);
17468        }
17469        if (srec == null) {
17470            return null;
17471        }
17472        return srec.launchedFromPackage;
17473    }
17474
17475    // =========================================================
17476    // LIFETIME MANAGEMENT
17477    // =========================================================
17478
17479    // Returns which broadcast queue the app is the current [or imminent] receiver
17480    // on, or 'null' if the app is not an active broadcast recipient.
17481    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17482        BroadcastRecord r = app.curReceiver;
17483        if (r != null) {
17484            return r.queue;
17485        }
17486
17487        // It's not the current receiver, but it might be starting up to become one
17488        synchronized (this) {
17489            for (BroadcastQueue queue : mBroadcastQueues) {
17490                r = queue.mPendingBroadcast;
17491                if (r != null && r.curApp == app) {
17492                    // found it; report which queue it's in
17493                    return queue;
17494                }
17495            }
17496        }
17497
17498        return null;
17499    }
17500
17501    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17502            ComponentName targetComponent, String targetProcess) {
17503        if (!mTrackingAssociations) {
17504            return null;
17505        }
17506        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17507                = mAssociations.get(targetUid);
17508        if (components == null) {
17509            components = new ArrayMap<>();
17510            mAssociations.put(targetUid, components);
17511        }
17512        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17513        if (sourceUids == null) {
17514            sourceUids = new SparseArray<>();
17515            components.put(targetComponent, sourceUids);
17516        }
17517        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17518        if (sourceProcesses == null) {
17519            sourceProcesses = new ArrayMap<>();
17520            sourceUids.put(sourceUid, sourceProcesses);
17521        }
17522        Association ass = sourceProcesses.get(sourceProcess);
17523        if (ass == null) {
17524            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17525                    targetProcess);
17526            sourceProcesses.put(sourceProcess, ass);
17527        }
17528        ass.mCount++;
17529        ass.mNesting++;
17530        if (ass.mNesting == 1) {
17531            ass.mStartTime = SystemClock.uptimeMillis();
17532        }
17533        return ass;
17534    }
17535
17536    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17537            ComponentName targetComponent) {
17538        if (!mTrackingAssociations) {
17539            return;
17540        }
17541        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17542                = mAssociations.get(targetUid);
17543        if (components == null) {
17544            return;
17545        }
17546        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17547        if (sourceUids == null) {
17548            return;
17549        }
17550        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17551        if (sourceProcesses == null) {
17552            return;
17553        }
17554        Association ass = sourceProcesses.get(sourceProcess);
17555        if (ass == null || ass.mNesting <= 0) {
17556            return;
17557        }
17558        ass.mNesting--;
17559        if (ass.mNesting == 0) {
17560            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17561        }
17562    }
17563
17564    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17565            boolean doingAll, long now) {
17566        if (mAdjSeq == app.adjSeq) {
17567            // This adjustment has already been computed.
17568            return app.curRawAdj;
17569        }
17570
17571        if (app.thread == null) {
17572            app.adjSeq = mAdjSeq;
17573            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17574            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17575            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17576        }
17577
17578        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17579        app.adjSource = null;
17580        app.adjTarget = null;
17581        app.empty = false;
17582        app.cached = false;
17583
17584        final int activitiesSize = app.activities.size();
17585
17586        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17587            // The max adjustment doesn't allow this app to be anything
17588            // below foreground, so it is not worth doing work for it.
17589            app.adjType = "fixed";
17590            app.adjSeq = mAdjSeq;
17591            app.curRawAdj = app.maxAdj;
17592            app.foregroundActivities = false;
17593            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17594            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17595            // System processes can do UI, and when they do we want to have
17596            // them trim their memory after the user leaves the UI.  To
17597            // facilitate this, here we need to determine whether or not it
17598            // is currently showing UI.
17599            app.systemNoUi = true;
17600            if (app == TOP_APP) {
17601                app.systemNoUi = false;
17602            } else if (activitiesSize > 0) {
17603                for (int j = 0; j < activitiesSize; j++) {
17604                    final ActivityRecord r = app.activities.get(j);
17605                    if (r.visible) {
17606                        app.systemNoUi = false;
17607                    }
17608                }
17609            }
17610            if (!app.systemNoUi) {
17611                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17612            }
17613            return (app.curAdj=app.maxAdj);
17614        }
17615
17616        app.systemNoUi = false;
17617
17618        final int PROCESS_STATE_TOP = mTopProcessState;
17619
17620        // Determine the importance of the process, starting with most
17621        // important to least, and assign an appropriate OOM adjustment.
17622        int adj;
17623        int schedGroup;
17624        int procState;
17625        boolean foregroundActivities = false;
17626        BroadcastQueue queue;
17627        if (app == TOP_APP) {
17628            // The last app on the list is the foreground app.
17629            adj = ProcessList.FOREGROUND_APP_ADJ;
17630            schedGroup = Process.THREAD_GROUP_DEFAULT;
17631            app.adjType = "top-activity";
17632            foregroundActivities = true;
17633            procState = PROCESS_STATE_TOP;
17634        } else if (app.instrumentationClass != null) {
17635            // Don't want to kill running instrumentation.
17636            adj = ProcessList.FOREGROUND_APP_ADJ;
17637            schedGroup = Process.THREAD_GROUP_DEFAULT;
17638            app.adjType = "instrumentation";
17639            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17640        } else if ((queue = isReceivingBroadcast(app)) != null) {
17641            // An app that is currently receiving a broadcast also
17642            // counts as being in the foreground for OOM killer purposes.
17643            // It's placed in a sched group based on the nature of the
17644            // broadcast as reflected by which queue it's active in.
17645            adj = ProcessList.FOREGROUND_APP_ADJ;
17646            schedGroup = (queue == mFgBroadcastQueue)
17647                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17648            app.adjType = "broadcast";
17649            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17650        } else if (app.executingServices.size() > 0) {
17651            // An app that is currently executing a service callback also
17652            // counts as being in the foreground.
17653            adj = ProcessList.FOREGROUND_APP_ADJ;
17654            schedGroup = app.execServicesFg ?
17655                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17656            app.adjType = "exec-service";
17657            procState = ActivityManager.PROCESS_STATE_SERVICE;
17658            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17659        } else {
17660            // As far as we know the process is empty.  We may change our mind later.
17661            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17662            // At this point we don't actually know the adjustment.  Use the cached adj
17663            // value that the caller wants us to.
17664            adj = cachedAdj;
17665            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17666            app.cached = true;
17667            app.empty = true;
17668            app.adjType = "cch-empty";
17669        }
17670
17671        // Examine all activities if not already foreground.
17672        if (!foregroundActivities && activitiesSize > 0) {
17673            for (int j = 0; j < activitiesSize; j++) {
17674                final ActivityRecord r = app.activities.get(j);
17675                if (r.app != app) {
17676                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17677                            + app + "?!? Using " + r.app + " instead.");
17678                    continue;
17679                }
17680                if (r.visible) {
17681                    // App has a visible activity; only upgrade adjustment.
17682                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17683                        adj = ProcessList.VISIBLE_APP_ADJ;
17684                        app.adjType = "visible";
17685                    }
17686                    if (procState > PROCESS_STATE_TOP) {
17687                        procState = PROCESS_STATE_TOP;
17688                    }
17689                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17690                    app.cached = false;
17691                    app.empty = false;
17692                    foregroundActivities = true;
17693                    break;
17694                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17695                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17696                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17697                        app.adjType = "pausing";
17698                    }
17699                    if (procState > PROCESS_STATE_TOP) {
17700                        procState = PROCESS_STATE_TOP;
17701                    }
17702                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17703                    app.cached = false;
17704                    app.empty = false;
17705                    foregroundActivities = true;
17706                } else if (r.state == ActivityState.STOPPING) {
17707                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17708                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17709                        app.adjType = "stopping";
17710                    }
17711                    // For the process state, we will at this point consider the
17712                    // process to be cached.  It will be cached either as an activity
17713                    // or empty depending on whether the activity is finishing.  We do
17714                    // this so that we can treat the process as cached for purposes of
17715                    // memory trimming (determing current memory level, trim command to
17716                    // send to process) since there can be an arbitrary number of stopping
17717                    // processes and they should soon all go into the cached state.
17718                    if (!r.finishing) {
17719                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17720                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17721                        }
17722                    }
17723                    app.cached = false;
17724                    app.empty = false;
17725                    foregroundActivities = true;
17726                } else {
17727                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17728                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17729                        app.adjType = "cch-act";
17730                    }
17731                }
17732            }
17733        }
17734
17735        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17736            if (app.foregroundServices) {
17737                // The user is aware of this app, so make it visible.
17738                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17739                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17740                app.cached = false;
17741                app.adjType = "fg-service";
17742                schedGroup = Process.THREAD_GROUP_DEFAULT;
17743            } else if (app.forcingToForeground != null) {
17744                // The user is aware of this app, so make it visible.
17745                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17746                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17747                app.cached = false;
17748                app.adjType = "force-fg";
17749                app.adjSource = app.forcingToForeground;
17750                schedGroup = Process.THREAD_GROUP_DEFAULT;
17751            }
17752        }
17753
17754        if (app == mHeavyWeightProcess) {
17755            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17756                // We don't want to kill the current heavy-weight process.
17757                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17758                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17759                app.cached = false;
17760                app.adjType = "heavy";
17761            }
17762            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17763                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17764            }
17765        }
17766
17767        if (app == mHomeProcess) {
17768            if (adj > ProcessList.HOME_APP_ADJ) {
17769                // This process is hosting what we currently consider to be the
17770                // home app, so we don't want to let it go into the background.
17771                adj = ProcessList.HOME_APP_ADJ;
17772                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17773                app.cached = false;
17774                app.adjType = "home";
17775            }
17776            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17777                procState = ActivityManager.PROCESS_STATE_HOME;
17778            }
17779        }
17780
17781        if (app == mPreviousProcess && app.activities.size() > 0) {
17782            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17783                // This was the previous process that showed UI to the user.
17784                // We want to try to keep it around more aggressively, to give
17785                // a good experience around switching between two apps.
17786                adj = ProcessList.PREVIOUS_APP_ADJ;
17787                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17788                app.cached = false;
17789                app.adjType = "previous";
17790            }
17791            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17792                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17793            }
17794        }
17795
17796        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17797                + " reason=" + app.adjType);
17798
17799        // By default, we use the computed adjustment.  It may be changed if
17800        // there are applications dependent on our services or providers, but
17801        // this gives us a baseline and makes sure we don't get into an
17802        // infinite recursion.
17803        app.adjSeq = mAdjSeq;
17804        app.curRawAdj = adj;
17805        app.hasStartedServices = false;
17806
17807        if (mBackupTarget != null && app == mBackupTarget.app) {
17808            // If possible we want to avoid killing apps while they're being backed up
17809            if (adj > ProcessList.BACKUP_APP_ADJ) {
17810                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17811                adj = ProcessList.BACKUP_APP_ADJ;
17812                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17813                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17814                }
17815                app.adjType = "backup";
17816                app.cached = false;
17817            }
17818            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17819                procState = ActivityManager.PROCESS_STATE_BACKUP;
17820            }
17821        }
17822
17823        boolean mayBeTop = false;
17824
17825        for (int is = app.services.size()-1;
17826                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17827                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17828                        || procState > ActivityManager.PROCESS_STATE_TOP);
17829                is--) {
17830            ServiceRecord s = app.services.valueAt(is);
17831            if (s.startRequested) {
17832                app.hasStartedServices = true;
17833                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17834                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17835                }
17836                if (app.hasShownUi && app != mHomeProcess) {
17837                    // If this process has shown some UI, let it immediately
17838                    // go to the LRU list because it may be pretty heavy with
17839                    // UI stuff.  We'll tag it with a label just to help
17840                    // debug and understand what is going on.
17841                    if (adj > ProcessList.SERVICE_ADJ) {
17842                        app.adjType = "cch-started-ui-services";
17843                    }
17844                } else {
17845                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17846                        // This service has seen some activity within
17847                        // recent memory, so we will keep its process ahead
17848                        // of the background processes.
17849                        if (adj > ProcessList.SERVICE_ADJ) {
17850                            adj = ProcessList.SERVICE_ADJ;
17851                            app.adjType = "started-services";
17852                            app.cached = false;
17853                        }
17854                    }
17855                    // If we have let the service slide into the background
17856                    // state, still have some text describing what it is doing
17857                    // even though the service no longer has an impact.
17858                    if (adj > ProcessList.SERVICE_ADJ) {
17859                        app.adjType = "cch-started-services";
17860                    }
17861                }
17862            }
17863            for (int conni = s.connections.size()-1;
17864                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17865                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17866                            || procState > ActivityManager.PROCESS_STATE_TOP);
17867                    conni--) {
17868                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17869                for (int i = 0;
17870                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17871                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17872                                || procState > ActivityManager.PROCESS_STATE_TOP);
17873                        i++) {
17874                    // XXX should compute this based on the max of
17875                    // all connected clients.
17876                    ConnectionRecord cr = clist.get(i);
17877                    if (cr.binding.client == app) {
17878                        // Binding to ourself is not interesting.
17879                        continue;
17880                    }
17881                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17882                        ProcessRecord client = cr.binding.client;
17883                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17884                                TOP_APP, doingAll, now);
17885                        int clientProcState = client.curProcState;
17886                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17887                            // If the other app is cached for any reason, for purposes here
17888                            // we are going to consider it empty.  The specific cached state
17889                            // doesn't propagate except under certain conditions.
17890                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17891                        }
17892                        String adjType = null;
17893                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17894                            // Not doing bind OOM management, so treat
17895                            // this guy more like a started service.
17896                            if (app.hasShownUi && app != mHomeProcess) {
17897                                // If this process has shown some UI, let it immediately
17898                                // go to the LRU list because it may be pretty heavy with
17899                                // UI stuff.  We'll tag it with a label just to help
17900                                // debug and understand what is going on.
17901                                if (adj > clientAdj) {
17902                                    adjType = "cch-bound-ui-services";
17903                                }
17904                                app.cached = false;
17905                                clientAdj = adj;
17906                                clientProcState = procState;
17907                            } else {
17908                                if (now >= (s.lastActivity
17909                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17910                                    // This service has not seen activity within
17911                                    // recent memory, so allow it to drop to the
17912                                    // LRU list if there is no other reason to keep
17913                                    // it around.  We'll also tag it with a label just
17914                                    // to help debug and undertand what is going on.
17915                                    if (adj > clientAdj) {
17916                                        adjType = "cch-bound-services";
17917                                    }
17918                                    clientAdj = adj;
17919                                }
17920                            }
17921                        }
17922                        if (adj > clientAdj) {
17923                            // If this process has recently shown UI, and
17924                            // the process that is binding to it is less
17925                            // important than being visible, then we don't
17926                            // care about the binding as much as we care
17927                            // about letting this process get into the LRU
17928                            // list to be killed and restarted if needed for
17929                            // memory.
17930                            if (app.hasShownUi && app != mHomeProcess
17931                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17932                                adjType = "cch-bound-ui-services";
17933                            } else {
17934                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17935                                        |Context.BIND_IMPORTANT)) != 0) {
17936                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17937                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17938                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17939                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17940                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17941                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17942                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17943                                    adj = clientAdj;
17944                                } else {
17945                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17946                                        adj = ProcessList.VISIBLE_APP_ADJ;
17947                                    }
17948                                }
17949                                if (!client.cached) {
17950                                    app.cached = false;
17951                                }
17952                                adjType = "service";
17953                            }
17954                        }
17955                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17956                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17957                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17958                            }
17959                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17960                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17961                                    // Special handling of clients who are in the top state.
17962                                    // We *may* want to consider this process to be in the
17963                                    // top state as well, but only if there is not another
17964                                    // reason for it to be running.  Being on the top is a
17965                                    // special state, meaning you are specifically running
17966                                    // for the current top app.  If the process is already
17967                                    // running in the background for some other reason, it
17968                                    // is more important to continue considering it to be
17969                                    // in the background state.
17970                                    mayBeTop = true;
17971                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17972                                } else {
17973                                    // Special handling for above-top states (persistent
17974                                    // processes).  These should not bring the current process
17975                                    // into the top state, since they are not on top.  Instead
17976                                    // give them the best state after that.
17977                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
17978                                        clientProcState =
17979                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17980                                    } else if (mWakefulness
17981                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
17982                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
17983                                                    != 0) {
17984                                        clientProcState =
17985                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17986                                    } else {
17987                                        clientProcState =
17988                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17989                                    }
17990                                }
17991                            }
17992                        } else {
17993                            if (clientProcState <
17994                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17995                                clientProcState =
17996                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17997                            }
17998                        }
17999                        if (procState > clientProcState) {
18000                            procState = clientProcState;
18001                        }
18002                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18003                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18004                            app.pendingUiClean = true;
18005                        }
18006                        if (adjType != null) {
18007                            app.adjType = adjType;
18008                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18009                                    .REASON_SERVICE_IN_USE;
18010                            app.adjSource = cr.binding.client;
18011                            app.adjSourceProcState = clientProcState;
18012                            app.adjTarget = s.name;
18013                        }
18014                    }
18015                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18016                        app.treatLikeActivity = true;
18017                    }
18018                    final ActivityRecord a = cr.activity;
18019                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18020                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18021                                (a.visible || a.state == ActivityState.RESUMED
18022                                 || a.state == ActivityState.PAUSING)) {
18023                            adj = ProcessList.FOREGROUND_APP_ADJ;
18024                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18025                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18026                            }
18027                            app.cached = false;
18028                            app.adjType = "service";
18029                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18030                                    .REASON_SERVICE_IN_USE;
18031                            app.adjSource = a;
18032                            app.adjSourceProcState = procState;
18033                            app.adjTarget = s.name;
18034                        }
18035                    }
18036                }
18037            }
18038        }
18039
18040        for (int provi = app.pubProviders.size()-1;
18041                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18042                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18043                        || procState > ActivityManager.PROCESS_STATE_TOP);
18044                provi--) {
18045            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18046            for (int i = cpr.connections.size()-1;
18047                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18048                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18049                            || procState > ActivityManager.PROCESS_STATE_TOP);
18050                    i--) {
18051                ContentProviderConnection conn = cpr.connections.get(i);
18052                ProcessRecord client = conn.client;
18053                if (client == app) {
18054                    // Being our own client is not interesting.
18055                    continue;
18056                }
18057                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18058                int clientProcState = client.curProcState;
18059                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18060                    // If the other app is cached for any reason, for purposes here
18061                    // we are going to consider it empty.
18062                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18063                }
18064                if (adj > clientAdj) {
18065                    if (app.hasShownUi && app != mHomeProcess
18066                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18067                        app.adjType = "cch-ui-provider";
18068                    } else {
18069                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18070                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18071                        app.adjType = "provider";
18072                    }
18073                    app.cached &= client.cached;
18074                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18075                            .REASON_PROVIDER_IN_USE;
18076                    app.adjSource = client;
18077                    app.adjSourceProcState = clientProcState;
18078                    app.adjTarget = cpr.name;
18079                }
18080                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18081                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18082                        // Special handling of clients who are in the top state.
18083                        // We *may* want to consider this process to be in the
18084                        // top state as well, but only if there is not another
18085                        // reason for it to be running.  Being on the top is a
18086                        // special state, meaning you are specifically running
18087                        // for the current top app.  If the process is already
18088                        // running in the background for some other reason, it
18089                        // is more important to continue considering it to be
18090                        // in the background state.
18091                        mayBeTop = true;
18092                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18093                    } else {
18094                        // Special handling for above-top states (persistent
18095                        // processes).  These should not bring the current process
18096                        // into the top state, since they are not on top.  Instead
18097                        // give them the best state after that.
18098                        clientProcState =
18099                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18100                    }
18101                }
18102                if (procState > clientProcState) {
18103                    procState = clientProcState;
18104                }
18105                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18106                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18107                }
18108            }
18109            // If the provider has external (non-framework) process
18110            // dependencies, ensure that its adjustment is at least
18111            // FOREGROUND_APP_ADJ.
18112            if (cpr.hasExternalProcessHandles()) {
18113                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18114                    adj = ProcessList.FOREGROUND_APP_ADJ;
18115                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18116                    app.cached = false;
18117                    app.adjType = "provider";
18118                    app.adjTarget = cpr.name;
18119                }
18120                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18121                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18122                }
18123            }
18124        }
18125
18126        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18127            // A client of one of our services or providers is in the top state.  We
18128            // *may* want to be in the top state, but not if we are already running in
18129            // the background for some other reason.  For the decision here, we are going
18130            // to pick out a few specific states that we want to remain in when a client
18131            // is top (states that tend to be longer-term) and otherwise allow it to go
18132            // to the top state.
18133            switch (procState) {
18134                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18135                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18136                case ActivityManager.PROCESS_STATE_SERVICE:
18137                    // These all are longer-term states, so pull them up to the top
18138                    // of the background states, but not all the way to the top state.
18139                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18140                    break;
18141                default:
18142                    // Otherwise, top is a better choice, so take it.
18143                    procState = ActivityManager.PROCESS_STATE_TOP;
18144                    break;
18145            }
18146        }
18147
18148        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18149            if (app.hasClientActivities) {
18150                // This is a cached process, but with client activities.  Mark it so.
18151                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18152                app.adjType = "cch-client-act";
18153            } else if (app.treatLikeActivity) {
18154                // This is a cached process, but somebody wants us to treat it like it has
18155                // an activity, okay!
18156                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18157                app.adjType = "cch-as-act";
18158            }
18159        }
18160
18161        if (adj == ProcessList.SERVICE_ADJ) {
18162            if (doingAll) {
18163                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18164                mNewNumServiceProcs++;
18165                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18166                if (!app.serviceb) {
18167                    // This service isn't far enough down on the LRU list to
18168                    // normally be a B service, but if we are low on RAM and it
18169                    // is large we want to force it down since we would prefer to
18170                    // keep launcher over it.
18171                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18172                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18173                        app.serviceHighRam = true;
18174                        app.serviceb = true;
18175                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18176                    } else {
18177                        mNewNumAServiceProcs++;
18178                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18179                    }
18180                } else {
18181                    app.serviceHighRam = false;
18182                }
18183            }
18184            if (app.serviceb) {
18185                adj = ProcessList.SERVICE_B_ADJ;
18186            }
18187        }
18188
18189        app.curRawAdj = adj;
18190
18191        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18192        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18193        if (adj > app.maxAdj) {
18194            adj = app.maxAdj;
18195            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18196                schedGroup = Process.THREAD_GROUP_DEFAULT;
18197            }
18198        }
18199
18200        // Do final modification to adj.  Everything we do between here and applying
18201        // the final setAdj must be done in this function, because we will also use
18202        // it when computing the final cached adj later.  Note that we don't need to
18203        // worry about this for max adj above, since max adj will always be used to
18204        // keep it out of the cached vaues.
18205        app.curAdj = app.modifyRawOomAdj(adj);
18206        app.curSchedGroup = schedGroup;
18207        app.curProcState = procState;
18208        app.foregroundActivities = foregroundActivities;
18209
18210        return app.curRawAdj;
18211    }
18212
18213    /**
18214     * Record new PSS sample for a process.
18215     */
18216    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18217        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18218        proc.lastPssTime = now;
18219        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18220        if (DEBUG_PSS) Slog.d(TAG_PSS,
18221                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18222                + " state=" + ProcessList.makeProcStateString(procState));
18223        if (proc.initialIdlePss == 0) {
18224            proc.initialIdlePss = pss;
18225        }
18226        proc.lastPss = pss;
18227        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18228            proc.lastCachedPss = pss;
18229        }
18230
18231        final SparseArray<Pair<Long, String>> watchUids
18232                = mMemWatchProcesses.getMap().get(proc.processName);
18233        Long check = null;
18234        if (watchUids != null) {
18235            Pair<Long, String> val = watchUids.get(proc.uid);
18236            if (val == null) {
18237                val = watchUids.get(0);
18238            }
18239            if (val != null) {
18240                check = val.first;
18241            }
18242        }
18243        if (check != null) {
18244            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18245                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18246                if (!isDebuggable) {
18247                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18248                        isDebuggable = true;
18249                    }
18250                }
18251                if (isDebuggable) {
18252                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18253                    final ProcessRecord myProc = proc;
18254                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18255                    mMemWatchDumpProcName = proc.processName;
18256                    mMemWatchDumpFile = heapdumpFile.toString();
18257                    mMemWatchDumpPid = proc.pid;
18258                    mMemWatchDumpUid = proc.uid;
18259                    BackgroundThread.getHandler().post(new Runnable() {
18260                        @Override
18261                        public void run() {
18262                            revokeUriPermission(ActivityThread.currentActivityThread()
18263                                            .getApplicationThread(),
18264                                    DumpHeapActivity.JAVA_URI,
18265                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18266                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18267                                    UserHandle.myUserId());
18268                            ParcelFileDescriptor fd = null;
18269                            try {
18270                                heapdumpFile.delete();
18271                                fd = ParcelFileDescriptor.open(heapdumpFile,
18272                                        ParcelFileDescriptor.MODE_CREATE |
18273                                                ParcelFileDescriptor.MODE_TRUNCATE |
18274                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18275                                                ParcelFileDescriptor.MODE_APPEND);
18276                                IApplicationThread thread = myProc.thread;
18277                                if (thread != null) {
18278                                    try {
18279                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18280                                                "Requesting dump heap from "
18281                                                + myProc + " to " + heapdumpFile);
18282                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18283                                    } catch (RemoteException e) {
18284                                    }
18285                                }
18286                            } catch (FileNotFoundException e) {
18287                                e.printStackTrace();
18288                            } finally {
18289                                if (fd != null) {
18290                                    try {
18291                                        fd.close();
18292                                    } catch (IOException e) {
18293                                    }
18294                                }
18295                            }
18296                        }
18297                    });
18298                } else {
18299                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18300                            + ", but debugging not enabled");
18301                }
18302            }
18303        }
18304    }
18305
18306    /**
18307     * Schedule PSS collection of a process.
18308     */
18309    void requestPssLocked(ProcessRecord proc, int procState) {
18310        if (mPendingPssProcesses.contains(proc)) {
18311            return;
18312        }
18313        if (mPendingPssProcesses.size() == 0) {
18314            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18315        }
18316        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18317        proc.pssProcState = procState;
18318        mPendingPssProcesses.add(proc);
18319    }
18320
18321    /**
18322     * Schedule PSS collection of all processes.
18323     */
18324    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18325        if (!always) {
18326            if (now < (mLastFullPssTime +
18327                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18328                return;
18329            }
18330        }
18331        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18332        mLastFullPssTime = now;
18333        mFullPssPending = true;
18334        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18335        mPendingPssProcesses.clear();
18336        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18337            ProcessRecord app = mLruProcesses.get(i);
18338            if (app.thread == null
18339                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18340                continue;
18341            }
18342            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18343                app.pssProcState = app.setProcState;
18344                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18345                        mTestPssMode, isSleeping(), now);
18346                mPendingPssProcesses.add(app);
18347            }
18348        }
18349        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18350    }
18351
18352    public void setTestPssMode(boolean enabled) {
18353        synchronized (this) {
18354            mTestPssMode = enabled;
18355            if (enabled) {
18356                // Whenever we enable the mode, we want to take a snapshot all of current
18357                // process mem use.
18358                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18359            }
18360        }
18361    }
18362
18363    /**
18364     * Ask a given process to GC right now.
18365     */
18366    final void performAppGcLocked(ProcessRecord app) {
18367        try {
18368            app.lastRequestedGc = SystemClock.uptimeMillis();
18369            if (app.thread != null) {
18370                if (app.reportLowMemory) {
18371                    app.reportLowMemory = false;
18372                    app.thread.scheduleLowMemory();
18373                } else {
18374                    app.thread.processInBackground();
18375                }
18376            }
18377        } catch (Exception e) {
18378            // whatever.
18379        }
18380    }
18381
18382    /**
18383     * Returns true if things are idle enough to perform GCs.
18384     */
18385    private final boolean canGcNowLocked() {
18386        boolean processingBroadcasts = false;
18387        for (BroadcastQueue q : mBroadcastQueues) {
18388            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18389                processingBroadcasts = true;
18390            }
18391        }
18392        return !processingBroadcasts
18393                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18394    }
18395
18396    /**
18397     * Perform GCs on all processes that are waiting for it, but only
18398     * if things are idle.
18399     */
18400    final void performAppGcsLocked() {
18401        final int N = mProcessesToGc.size();
18402        if (N <= 0) {
18403            return;
18404        }
18405        if (canGcNowLocked()) {
18406            while (mProcessesToGc.size() > 0) {
18407                ProcessRecord proc = mProcessesToGc.remove(0);
18408                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18409                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18410                            <= SystemClock.uptimeMillis()) {
18411                        // To avoid spamming the system, we will GC processes one
18412                        // at a time, waiting a few seconds between each.
18413                        performAppGcLocked(proc);
18414                        scheduleAppGcsLocked();
18415                        return;
18416                    } else {
18417                        // It hasn't been long enough since we last GCed this
18418                        // process...  put it in the list to wait for its time.
18419                        addProcessToGcListLocked(proc);
18420                        break;
18421                    }
18422                }
18423            }
18424
18425            scheduleAppGcsLocked();
18426        }
18427    }
18428
18429    /**
18430     * If all looks good, perform GCs on all processes waiting for them.
18431     */
18432    final void performAppGcsIfAppropriateLocked() {
18433        if (canGcNowLocked()) {
18434            performAppGcsLocked();
18435            return;
18436        }
18437        // Still not idle, wait some more.
18438        scheduleAppGcsLocked();
18439    }
18440
18441    /**
18442     * Schedule the execution of all pending app GCs.
18443     */
18444    final void scheduleAppGcsLocked() {
18445        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18446
18447        if (mProcessesToGc.size() > 0) {
18448            // Schedule a GC for the time to the next process.
18449            ProcessRecord proc = mProcessesToGc.get(0);
18450            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18451
18452            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18453            long now = SystemClock.uptimeMillis();
18454            if (when < (now+GC_TIMEOUT)) {
18455                when = now + GC_TIMEOUT;
18456            }
18457            mHandler.sendMessageAtTime(msg, when);
18458        }
18459    }
18460
18461    /**
18462     * Add a process to the array of processes waiting to be GCed.  Keeps the
18463     * list in sorted order by the last GC time.  The process can't already be
18464     * on the list.
18465     */
18466    final void addProcessToGcListLocked(ProcessRecord proc) {
18467        boolean added = false;
18468        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18469            if (mProcessesToGc.get(i).lastRequestedGc <
18470                    proc.lastRequestedGc) {
18471                added = true;
18472                mProcessesToGc.add(i+1, proc);
18473                break;
18474            }
18475        }
18476        if (!added) {
18477            mProcessesToGc.add(0, proc);
18478        }
18479    }
18480
18481    /**
18482     * Set up to ask a process to GC itself.  This will either do it
18483     * immediately, or put it on the list of processes to gc the next
18484     * time things are idle.
18485     */
18486    final void scheduleAppGcLocked(ProcessRecord app) {
18487        long now = SystemClock.uptimeMillis();
18488        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18489            return;
18490        }
18491        if (!mProcessesToGc.contains(app)) {
18492            addProcessToGcListLocked(app);
18493            scheduleAppGcsLocked();
18494        }
18495    }
18496
18497    final void checkExcessivePowerUsageLocked(boolean doKills) {
18498        updateCpuStatsNow();
18499
18500        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18501        boolean doWakeKills = doKills;
18502        boolean doCpuKills = doKills;
18503        if (mLastPowerCheckRealtime == 0) {
18504            doWakeKills = false;
18505        }
18506        if (mLastPowerCheckUptime == 0) {
18507            doCpuKills = false;
18508        }
18509        if (stats.isScreenOn()) {
18510            doWakeKills = false;
18511        }
18512        final long curRealtime = SystemClock.elapsedRealtime();
18513        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18514        final long curUptime = SystemClock.uptimeMillis();
18515        final long uptimeSince = curUptime - mLastPowerCheckUptime;
18516        mLastPowerCheckRealtime = curRealtime;
18517        mLastPowerCheckUptime = curUptime;
18518        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18519            doWakeKills = false;
18520        }
18521        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18522            doCpuKills = false;
18523        }
18524        int i = mLruProcesses.size();
18525        while (i > 0) {
18526            i--;
18527            ProcessRecord app = mLruProcesses.get(i);
18528            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18529                long wtime;
18530                synchronized (stats) {
18531                    wtime = stats.getProcessWakeTime(app.info.uid,
18532                            app.pid, curRealtime);
18533                }
18534                long wtimeUsed = wtime - app.lastWakeTime;
18535                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18536                if (DEBUG_POWER) {
18537                    StringBuilder sb = new StringBuilder(128);
18538                    sb.append("Wake for ");
18539                    app.toShortString(sb);
18540                    sb.append(": over ");
18541                    TimeUtils.formatDuration(realtimeSince, sb);
18542                    sb.append(" used ");
18543                    TimeUtils.formatDuration(wtimeUsed, sb);
18544                    sb.append(" (");
18545                    sb.append((wtimeUsed*100)/realtimeSince);
18546                    sb.append("%)");
18547                    Slog.i(TAG_POWER, sb.toString());
18548                    sb.setLength(0);
18549                    sb.append("CPU for ");
18550                    app.toShortString(sb);
18551                    sb.append(": over ");
18552                    TimeUtils.formatDuration(uptimeSince, sb);
18553                    sb.append(" used ");
18554                    TimeUtils.formatDuration(cputimeUsed, sb);
18555                    sb.append(" (");
18556                    sb.append((cputimeUsed*100)/uptimeSince);
18557                    sb.append("%)");
18558                    Slog.i(TAG_POWER, sb.toString());
18559                }
18560                // If a process has held a wake lock for more
18561                // than 50% of the time during this period,
18562                // that sounds bad.  Kill!
18563                if (doWakeKills && realtimeSince > 0
18564                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
18565                    synchronized (stats) {
18566                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18567                                realtimeSince, wtimeUsed);
18568                    }
18569                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18570                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18571                } else if (doCpuKills && uptimeSince > 0
18572                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
18573                    synchronized (stats) {
18574                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18575                                uptimeSince, cputimeUsed);
18576                    }
18577                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18578                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18579                } else {
18580                    app.lastWakeTime = wtime;
18581                    app.lastCpuTime = app.curCpuTime;
18582                }
18583            }
18584        }
18585    }
18586
18587    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
18588        boolean success = true;
18589
18590        if (app.curRawAdj != app.setRawAdj) {
18591            app.setRawAdj = app.curRawAdj;
18592        }
18593
18594        int changes = 0;
18595
18596        if (app.curAdj != app.setAdj) {
18597            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18598            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18599                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18600                    + app.adjType);
18601            app.setAdj = app.curAdj;
18602        }
18603
18604        if (app.setSchedGroup != app.curSchedGroup) {
18605            app.setSchedGroup = app.curSchedGroup;
18606            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18607                    "Setting process group of " + app.processName
18608                    + " to " + app.curSchedGroup);
18609            if (app.waitingToKill != null && app.curReceiver == null
18610                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18611                app.kill(app.waitingToKill, true);
18612                success = false;
18613            } else {
18614                if (true) {
18615                    long oldId = Binder.clearCallingIdentity();
18616                    try {
18617                        Process.setProcessGroup(app.pid, app.curSchedGroup);
18618                    } catch (Exception e) {
18619                        Slog.w(TAG, "Failed setting process group of " + app.pid
18620                                + " to " + app.curSchedGroup);
18621                        e.printStackTrace();
18622                    } finally {
18623                        Binder.restoreCallingIdentity(oldId);
18624                    }
18625                } else {
18626                    if (app.thread != null) {
18627                        try {
18628                            app.thread.setSchedulingGroup(app.curSchedGroup);
18629                        } catch (RemoteException e) {
18630                        }
18631                    }
18632                }
18633                Process.setSwappiness(app.pid,
18634                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18635            }
18636        }
18637        if (app.repForegroundActivities != app.foregroundActivities) {
18638            app.repForegroundActivities = app.foregroundActivities;
18639            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18640        }
18641        if (app.repProcState != app.curProcState) {
18642            app.repProcState = app.curProcState;
18643            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18644            if (app.thread != null) {
18645                try {
18646                    if (false) {
18647                        //RuntimeException h = new RuntimeException("here");
18648                        Slog.i(TAG, "Sending new process state " + app.repProcState
18649                                + " to " + app /*, h*/);
18650                    }
18651                    app.thread.setProcessState(app.repProcState);
18652                } catch (RemoteException e) {
18653                }
18654            }
18655        }
18656        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18657                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18658            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18659                // Experimental code to more aggressively collect pss while
18660                // running test...  the problem is that this tends to collect
18661                // the data right when a process is transitioning between process
18662                // states, which well tend to give noisy data.
18663                long start = SystemClock.uptimeMillis();
18664                long pss = Debug.getPss(app.pid, mTmpLong, null);
18665                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18666                mPendingPssProcesses.remove(app);
18667                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18668                        + " to " + app.curProcState + ": "
18669                        + (SystemClock.uptimeMillis()-start) + "ms");
18670            }
18671            app.lastStateTime = now;
18672            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18673                    mTestPssMode, isSleeping(), now);
18674            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18675                    + ProcessList.makeProcStateString(app.setProcState) + " to "
18676                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18677                    + (app.nextPssTime-now) + ": " + app);
18678        } else {
18679            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18680                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18681                    mTestPssMode)))) {
18682                requestPssLocked(app, app.setProcState);
18683                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18684                        mTestPssMode, isSleeping(), now);
18685            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18686                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18687        }
18688        if (app.setProcState != app.curProcState) {
18689            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18690                    "Proc state change of " + app.processName
18691                    + " to " + app.curProcState);
18692            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18693            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18694            if (setImportant && !curImportant) {
18695                // This app is no longer something we consider important enough to allow to
18696                // use arbitrary amounts of battery power.  Note
18697                // its current wake lock time to later know to kill it if
18698                // it is not behaving well.
18699                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18700                synchronized (stats) {
18701                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18702                            app.pid, SystemClock.elapsedRealtime());
18703                }
18704                app.lastCpuTime = app.curCpuTime;
18705
18706            }
18707            // Inform UsageStats of important process state change
18708            // Must be called before updating setProcState
18709            maybeUpdateUsageStatsLocked(app);
18710
18711            app.setProcState = app.curProcState;
18712            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18713                app.notCachedSinceIdle = false;
18714            }
18715            if (!doingAll) {
18716                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18717            } else {
18718                app.procStateChanged = true;
18719            }
18720        }
18721
18722        if (changes != 0) {
18723            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18724                    "Changes in " + app + ": " + changes);
18725            int i = mPendingProcessChanges.size()-1;
18726            ProcessChangeItem item = null;
18727            while (i >= 0) {
18728                item = mPendingProcessChanges.get(i);
18729                if (item.pid == app.pid) {
18730                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18731                            "Re-using existing item: " + item);
18732                    break;
18733                }
18734                i--;
18735            }
18736            if (i < 0) {
18737                // No existing item in pending changes; need a new one.
18738                final int NA = mAvailProcessChanges.size();
18739                if (NA > 0) {
18740                    item = mAvailProcessChanges.remove(NA-1);
18741                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18742                            "Retrieving available item: " + item);
18743                } else {
18744                    item = new ProcessChangeItem();
18745                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18746                            "Allocating new item: " + item);
18747                }
18748                item.changes = 0;
18749                item.pid = app.pid;
18750                item.uid = app.info.uid;
18751                if (mPendingProcessChanges.size() == 0) {
18752                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18753                            "*** Enqueueing dispatch processes changed!");
18754                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18755                }
18756                mPendingProcessChanges.add(item);
18757            }
18758            item.changes |= changes;
18759            item.processState = app.repProcState;
18760            item.foregroundActivities = app.repForegroundActivities;
18761            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18762                    "Item " + Integer.toHexString(System.identityHashCode(item))
18763                    + " " + app.toShortString() + ": changes=" + item.changes
18764                    + " procState=" + item.processState
18765                    + " foreground=" + item.foregroundActivities
18766                    + " type=" + app.adjType + " source=" + app.adjSource
18767                    + " target=" + app.adjTarget);
18768        }
18769
18770        return success;
18771    }
18772
18773    private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18774        if (uidRec.pendingChange == null) {
18775            if (mPendingUidChanges.size() == 0) {
18776                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18777                        "*** Enqueueing dispatch uid changed!");
18778                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18779            }
18780            final int NA = mAvailUidChanges.size();
18781            if (NA > 0) {
18782                uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18783                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18784                        "Retrieving available item: " + uidRec.pendingChange);
18785            } else {
18786                uidRec.pendingChange = new UidRecord.ChangeItem();
18787                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18788                        "Allocating new item: " + uidRec.pendingChange);
18789            }
18790            uidRec.pendingChange.uidRecord = uidRec;
18791            uidRec.pendingChange.uid = uidRec.uid;
18792            mPendingUidChanges.add(uidRec.pendingChange);
18793        }
18794        uidRec.pendingChange.gone = gone;
18795        uidRec.pendingChange.processState = uidRec.setProcState;
18796    }
18797
18798    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18799            String authority) {
18800        if (app == null) return;
18801        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18802            UserState userState = mStartedUsers.get(app.userId);
18803            if (userState == null) return;
18804            final long now = SystemClock.elapsedRealtime();
18805            Long lastReported = userState.mProviderLastReportedFg.get(authority);
18806            if (lastReported == null || lastReported < now - 60 * 1000L) {
18807                mUsageStatsService.reportContentProviderUsage(
18808                        authority, providerPkgName, app.userId);
18809                userState.mProviderLastReportedFg.put(authority, now);
18810            }
18811        }
18812    }
18813
18814    private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
18815        if (DEBUG_USAGE_STATS) {
18816            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18817                    + "] state changes: old = " + app.setProcState + ", new = "
18818                    + app.curProcState);
18819        }
18820        if (mUsageStatsService == null) {
18821            return;
18822        }
18823        boolean isInteraction;
18824        // To avoid some abuse patterns, we are going to be careful about what we consider
18825        // to be an app interaction.  Being the top activity doesn't count while the display
18826        // is sleeping, nor do short foreground services.
18827        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18828            isInteraction = true;
18829            app.fgInteractionTime = 0;
18830        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18831            final long now = SystemClock.elapsedRealtime();
18832            if (app.fgInteractionTime == 0) {
18833                app.fgInteractionTime = now;
18834                isInteraction = false;
18835            } else {
18836                isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18837            }
18838        } else {
18839            isInteraction = app.curProcState
18840                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18841            app.fgInteractionTime = 0;
18842        }
18843        if (isInteraction && !app.reportedInteraction) {
18844            String[] packages = app.getPackageList();
18845            if (packages != null) {
18846                for (int i = 0; i < packages.length; i++) {
18847                    mUsageStatsService.reportEvent(packages[i], app.userId,
18848                            UsageEvents.Event.SYSTEM_INTERACTION);
18849                }
18850            }
18851        }
18852        app.reportedInteraction = isInteraction;
18853    }
18854
18855    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18856        if (proc.thread != null) {
18857            if (proc.baseProcessTracker != null) {
18858                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18859            }
18860            if (proc.repProcState >= 0) {
18861                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18862                        proc.repProcState);
18863            }
18864        }
18865    }
18866
18867    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18868            ProcessRecord TOP_APP, boolean doingAll, long now) {
18869        if (app.thread == null) {
18870            return false;
18871        }
18872
18873        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18874
18875        return applyOomAdjLocked(app, doingAll, now);
18876    }
18877
18878    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18879            boolean oomAdj) {
18880        if (isForeground != proc.foregroundServices) {
18881            proc.foregroundServices = isForeground;
18882            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18883                    proc.info.uid);
18884            if (isForeground) {
18885                if (curProcs == null) {
18886                    curProcs = new ArrayList<ProcessRecord>();
18887                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18888                }
18889                if (!curProcs.contains(proc)) {
18890                    curProcs.add(proc);
18891                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18892                            proc.info.packageName, proc.info.uid);
18893                }
18894            } else {
18895                if (curProcs != null) {
18896                    if (curProcs.remove(proc)) {
18897                        mBatteryStatsService.noteEvent(
18898                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18899                                proc.info.packageName, proc.info.uid);
18900                        if (curProcs.size() <= 0) {
18901                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18902                        }
18903                    }
18904                }
18905            }
18906            if (oomAdj) {
18907                updateOomAdjLocked();
18908            }
18909        }
18910    }
18911
18912    private final ActivityRecord resumedAppLocked() {
18913        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18914        String pkg;
18915        int uid;
18916        if (act != null) {
18917            pkg = act.packageName;
18918            uid = act.info.applicationInfo.uid;
18919        } else {
18920            pkg = null;
18921            uid = -1;
18922        }
18923        // Has the UID or resumed package name changed?
18924        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18925                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18926            if (mCurResumedPackage != null) {
18927                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18928                        mCurResumedPackage, mCurResumedUid);
18929            }
18930            mCurResumedPackage = pkg;
18931            mCurResumedUid = uid;
18932            if (mCurResumedPackage != null) {
18933                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18934                        mCurResumedPackage, mCurResumedUid);
18935            }
18936        }
18937        return act;
18938    }
18939
18940    final boolean updateOomAdjLocked(ProcessRecord app) {
18941        final ActivityRecord TOP_ACT = resumedAppLocked();
18942        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18943        final boolean wasCached = app.cached;
18944
18945        mAdjSeq++;
18946
18947        // This is the desired cached adjusment we want to tell it to use.
18948        // If our app is currently cached, we know it, and that is it.  Otherwise,
18949        // we don't know it yet, and it needs to now be cached we will then
18950        // need to do a complete oom adj.
18951        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18952                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18953        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18954                SystemClock.uptimeMillis());
18955        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18956            // Changed to/from cached state, so apps after it in the LRU
18957            // list may also be changed.
18958            updateOomAdjLocked();
18959        }
18960        return success;
18961    }
18962
18963    final void updateOomAdjLocked() {
18964        final ActivityRecord TOP_ACT = resumedAppLocked();
18965        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18966        final long now = SystemClock.uptimeMillis();
18967        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18968        final int N = mLruProcesses.size();
18969
18970        if (false) {
18971            RuntimeException e = new RuntimeException();
18972            e.fillInStackTrace();
18973            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18974        }
18975
18976        // Reset state in all uid records.
18977        for (int i=mActiveUids.size()-1; i>=0; i--) {
18978            final UidRecord uidRec = mActiveUids.valueAt(i);
18979            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18980                    "Starting update of " + uidRec);
18981            uidRec.reset();
18982        }
18983
18984        mAdjSeq++;
18985        mNewNumServiceProcs = 0;
18986        mNewNumAServiceProcs = 0;
18987
18988        final int emptyProcessLimit;
18989        final int cachedProcessLimit;
18990        if (mProcessLimit <= 0) {
18991            emptyProcessLimit = cachedProcessLimit = 0;
18992        } else if (mProcessLimit == 1) {
18993            emptyProcessLimit = 1;
18994            cachedProcessLimit = 0;
18995        } else {
18996            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18997            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18998        }
18999
19000        // Let's determine how many processes we have running vs.
19001        // how many slots we have for background processes; we may want
19002        // to put multiple processes in a slot of there are enough of
19003        // them.
19004        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19005                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19006        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19007        if (numEmptyProcs > cachedProcessLimit) {
19008            // If there are more empty processes than our limit on cached
19009            // processes, then use the cached process limit for the factor.
19010            // This ensures that the really old empty processes get pushed
19011            // down to the bottom, so if we are running low on memory we will
19012            // have a better chance at keeping around more cached processes
19013            // instead of a gazillion empty processes.
19014            numEmptyProcs = cachedProcessLimit;
19015        }
19016        int emptyFactor = numEmptyProcs/numSlots;
19017        if (emptyFactor < 1) emptyFactor = 1;
19018        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19019        if (cachedFactor < 1) cachedFactor = 1;
19020        int stepCached = 0;
19021        int stepEmpty = 0;
19022        int numCached = 0;
19023        int numEmpty = 0;
19024        int numTrimming = 0;
19025
19026        mNumNonCachedProcs = 0;
19027        mNumCachedHiddenProcs = 0;
19028
19029        // First update the OOM adjustment for each of the
19030        // application processes based on their current state.
19031        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19032        int nextCachedAdj = curCachedAdj+1;
19033        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19034        int nextEmptyAdj = curEmptyAdj+2;
19035        for (int i=N-1; i>=0; i--) {
19036            ProcessRecord app = mLruProcesses.get(i);
19037            if (!app.killedByAm && app.thread != null) {
19038                app.procStateChanged = false;
19039                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19040
19041                // If we haven't yet assigned the final cached adj
19042                // to the process, do that now.
19043                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19044                    switch (app.curProcState) {
19045                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19046                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19047                            // This process is a cached process holding activities...
19048                            // assign it the next cached value for that type, and then
19049                            // step that cached level.
19050                            app.curRawAdj = curCachedAdj;
19051                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19052                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19053                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19054                                    + ")");
19055                            if (curCachedAdj != nextCachedAdj) {
19056                                stepCached++;
19057                                if (stepCached >= cachedFactor) {
19058                                    stepCached = 0;
19059                                    curCachedAdj = nextCachedAdj;
19060                                    nextCachedAdj += 2;
19061                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19062                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19063                                    }
19064                                }
19065                            }
19066                            break;
19067                        default:
19068                            // For everything else, assign next empty cached process
19069                            // level and bump that up.  Note that this means that
19070                            // long-running services that have dropped down to the
19071                            // cached level will be treated as empty (since their process
19072                            // state is still as a service), which is what we want.
19073                            app.curRawAdj = curEmptyAdj;
19074                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19075                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19076                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19077                                    + ")");
19078                            if (curEmptyAdj != nextEmptyAdj) {
19079                                stepEmpty++;
19080                                if (stepEmpty >= emptyFactor) {
19081                                    stepEmpty = 0;
19082                                    curEmptyAdj = nextEmptyAdj;
19083                                    nextEmptyAdj += 2;
19084                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19085                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19086                                    }
19087                                }
19088                            }
19089                            break;
19090                    }
19091                }
19092
19093                applyOomAdjLocked(app, true, now);
19094
19095                // Count the number of process types.
19096                switch (app.curProcState) {
19097                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19098                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19099                        mNumCachedHiddenProcs++;
19100                        numCached++;
19101                        if (numCached > cachedProcessLimit) {
19102                            app.kill("cached #" + numCached, true);
19103                        }
19104                        break;
19105                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19106                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19107                                && app.lastActivityTime < oldTime) {
19108                            app.kill("empty for "
19109                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19110                                    / 1000) + "s", true);
19111                        } else {
19112                            numEmpty++;
19113                            if (numEmpty > emptyProcessLimit) {
19114                                app.kill("empty #" + numEmpty, true);
19115                            }
19116                        }
19117                        break;
19118                    default:
19119                        mNumNonCachedProcs++;
19120                        break;
19121                }
19122
19123                if (app.isolated && app.services.size() <= 0) {
19124                    // If this is an isolated process, and there are no
19125                    // services running in it, then the process is no longer
19126                    // needed.  We agressively kill these because we can by
19127                    // definition not re-use the same process again, and it is
19128                    // good to avoid having whatever code was running in them
19129                    // left sitting around after no longer needed.
19130                    app.kill("isolated not needed", true);
19131                } else {
19132                    // Keeping this process, update its uid.
19133                    final UidRecord uidRec = app.uidRecord;
19134                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19135                        uidRec.curProcState = app.curProcState;
19136                    }
19137                }
19138
19139                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19140                        && !app.killedByAm) {
19141                    numTrimming++;
19142                }
19143            }
19144        }
19145
19146        mNumServiceProcs = mNewNumServiceProcs;
19147
19148        // Now determine the memory trimming level of background processes.
19149        // Unfortunately we need to start at the back of the list to do this
19150        // properly.  We only do this if the number of background apps we
19151        // are managing to keep around is less than half the maximum we desire;
19152        // if we are keeping a good number around, we'll let them use whatever
19153        // memory they want.
19154        final int numCachedAndEmpty = numCached + numEmpty;
19155        int memFactor;
19156        if (numCached <= ProcessList.TRIM_CACHED_APPS
19157                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19158            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19159                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19160            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19161                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19162            } else {
19163                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19164            }
19165        } else {
19166            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19167        }
19168        // We always allow the memory level to go up (better).  We only allow it to go
19169        // down if we are in a state where that is allowed, *and* the total number of processes
19170        // has gone down since last time.
19171        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19172                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19173                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19174        if (memFactor > mLastMemoryLevel) {
19175            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19176                memFactor = mLastMemoryLevel;
19177                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19178            }
19179        }
19180        mLastMemoryLevel = memFactor;
19181        mLastNumProcesses = mLruProcesses.size();
19182        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19183        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19184        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19185            if (mLowRamStartTime == 0) {
19186                mLowRamStartTime = now;
19187            }
19188            int step = 0;
19189            int fgTrimLevel;
19190            switch (memFactor) {
19191                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19192                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19193                    break;
19194                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19195                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19196                    break;
19197                default:
19198                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19199                    break;
19200            }
19201            int factor = numTrimming/3;
19202            int minFactor = 2;
19203            if (mHomeProcess != null) minFactor++;
19204            if (mPreviousProcess != null) minFactor++;
19205            if (factor < minFactor) factor = minFactor;
19206            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19207            for (int i=N-1; i>=0; i--) {
19208                ProcessRecord app = mLruProcesses.get(i);
19209                if (allChanged || app.procStateChanged) {
19210                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19211                    app.procStateChanged = false;
19212                }
19213                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19214                        && !app.killedByAm) {
19215                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19216                        try {
19217                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19218                                    "Trimming memory of " + app.processName + " to " + curLevel);
19219                            app.thread.scheduleTrimMemory(curLevel);
19220                        } catch (RemoteException e) {
19221                        }
19222                        if (false) {
19223                            // For now we won't do this; our memory trimming seems
19224                            // to be good enough at this point that destroying
19225                            // activities causes more harm than good.
19226                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19227                                    && app != mHomeProcess && app != mPreviousProcess) {
19228                                // Need to do this on its own message because the stack may not
19229                                // be in a consistent state at this point.
19230                                // For these apps we will also finish their activities
19231                                // to help them free memory.
19232                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19233                            }
19234                        }
19235                    }
19236                    app.trimMemoryLevel = curLevel;
19237                    step++;
19238                    if (step >= factor) {
19239                        step = 0;
19240                        switch (curLevel) {
19241                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19242                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19243                                break;
19244                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19245                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19246                                break;
19247                        }
19248                    }
19249                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19250                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19251                            && app.thread != null) {
19252                        try {
19253                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19254                                    "Trimming memory of heavy-weight " + app.processName
19255                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19256                            app.thread.scheduleTrimMemory(
19257                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19258                        } catch (RemoteException e) {
19259                        }
19260                    }
19261                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19262                } else {
19263                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19264                            || app.systemNoUi) && app.pendingUiClean) {
19265                        // If this application is now in the background and it
19266                        // had done UI, then give it the special trim level to
19267                        // have it free UI resources.
19268                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19269                        if (app.trimMemoryLevel < level && app.thread != null) {
19270                            try {
19271                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19272                                        "Trimming memory of bg-ui " + app.processName
19273                                        + " to " + level);
19274                                app.thread.scheduleTrimMemory(level);
19275                            } catch (RemoteException e) {
19276                            }
19277                        }
19278                        app.pendingUiClean = false;
19279                    }
19280                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19281                        try {
19282                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19283                                    "Trimming memory of fg " + app.processName
19284                                    + " to " + fgTrimLevel);
19285                            app.thread.scheduleTrimMemory(fgTrimLevel);
19286                        } catch (RemoteException e) {
19287                        }
19288                    }
19289                    app.trimMemoryLevel = fgTrimLevel;
19290                }
19291            }
19292        } else {
19293            if (mLowRamStartTime != 0) {
19294                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19295                mLowRamStartTime = 0;
19296            }
19297            for (int i=N-1; i>=0; i--) {
19298                ProcessRecord app = mLruProcesses.get(i);
19299                if (allChanged || app.procStateChanged) {
19300                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19301                    app.procStateChanged = false;
19302                }
19303                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19304                        || app.systemNoUi) && app.pendingUiClean) {
19305                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19306                            && app.thread != null) {
19307                        try {
19308                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19309                                    "Trimming memory of ui hidden " + app.processName
19310                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19311                            app.thread.scheduleTrimMemory(
19312                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19313                        } catch (RemoteException e) {
19314                        }
19315                    }
19316                    app.pendingUiClean = false;
19317                }
19318                app.trimMemoryLevel = 0;
19319            }
19320        }
19321
19322        if (mAlwaysFinishActivities) {
19323            // Need to do this on its own message because the stack may not
19324            // be in a consistent state at this point.
19325            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19326        }
19327
19328        if (allChanged) {
19329            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19330        }
19331
19332        // Update from any uid changes.
19333        for (int i=mActiveUids.size()-1; i>=0; i--) {
19334            final UidRecord uidRec = mActiveUids.valueAt(i);
19335            if (uidRec.setProcState != uidRec.curProcState) {
19336                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19337                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19338                        + " to " + uidRec.curProcState);
19339                uidRec.setProcState = uidRec.curProcState;
19340                enqueueUidChangeLocked(uidRec, false);
19341            }
19342        }
19343
19344        if (mProcessStats.shouldWriteNowLocked(now)) {
19345            mHandler.post(new Runnable() {
19346                @Override public void run() {
19347                    synchronized (ActivityManagerService.this) {
19348                        mProcessStats.writeStateAsyncLocked();
19349                    }
19350                }
19351            });
19352        }
19353
19354        if (DEBUG_OOM_ADJ) {
19355            final long duration = SystemClock.uptimeMillis() - now;
19356            if (false) {
19357                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19358                        new RuntimeException("here").fillInStackTrace());
19359            } else {
19360                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19361            }
19362        }
19363    }
19364
19365    final void trimApplications() {
19366        synchronized (this) {
19367            int i;
19368
19369            // First remove any unused application processes whose package
19370            // has been removed.
19371            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19372                final ProcessRecord app = mRemovedProcesses.get(i);
19373                if (app.activities.size() == 0
19374                        && app.curReceiver == null && app.services.size() == 0) {
19375                    Slog.i(
19376                        TAG, "Exiting empty application process "
19377                        + app.processName + " ("
19378                        + (app.thread != null ? app.thread.asBinder() : null)
19379                        + ")\n");
19380                    if (app.pid > 0 && app.pid != MY_PID) {
19381                        app.kill("empty", false);
19382                    } else {
19383                        try {
19384                            app.thread.scheduleExit();
19385                        } catch (Exception e) {
19386                            // Ignore exceptions.
19387                        }
19388                    }
19389                    cleanUpApplicationRecordLocked(app, false, true, -1);
19390                    mRemovedProcesses.remove(i);
19391
19392                    if (app.persistent) {
19393                        addAppLocked(app.info, false, null /* ABI override */);
19394                    }
19395                }
19396            }
19397
19398            // Now update the oom adj for all processes.
19399            updateOomAdjLocked();
19400        }
19401    }
19402
19403    /** This method sends the specified signal to each of the persistent apps */
19404    public void signalPersistentProcesses(int sig) throws RemoteException {
19405        if (sig != Process.SIGNAL_USR1) {
19406            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19407        }
19408
19409        synchronized (this) {
19410            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19411                    != PackageManager.PERMISSION_GRANTED) {
19412                throw new SecurityException("Requires permission "
19413                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19414            }
19415
19416            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19417                ProcessRecord r = mLruProcesses.get(i);
19418                if (r.thread != null && r.persistent) {
19419                    Process.sendSignal(r.pid, sig);
19420                }
19421            }
19422        }
19423    }
19424
19425    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19426        if (proc == null || proc == mProfileProc) {
19427            proc = mProfileProc;
19428            profileType = mProfileType;
19429            clearProfilerLocked();
19430        }
19431        if (proc == null) {
19432            return;
19433        }
19434        try {
19435            proc.thread.profilerControl(false, null, profileType);
19436        } catch (RemoteException e) {
19437            throw new IllegalStateException("Process disappeared");
19438        }
19439    }
19440
19441    private void clearProfilerLocked() {
19442        if (mProfileFd != null) {
19443            try {
19444                mProfileFd.close();
19445            } catch (IOException e) {
19446            }
19447        }
19448        mProfileApp = null;
19449        mProfileProc = null;
19450        mProfileFile = null;
19451        mProfileType = 0;
19452        mAutoStopProfiler = false;
19453        mSamplingInterval = 0;
19454    }
19455
19456    public boolean profileControl(String process, int userId, boolean start,
19457            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19458
19459        try {
19460            synchronized (this) {
19461                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19462                // its own permission.
19463                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19464                        != PackageManager.PERMISSION_GRANTED) {
19465                    throw new SecurityException("Requires permission "
19466                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19467                }
19468
19469                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19470                    throw new IllegalArgumentException("null profile info or fd");
19471                }
19472
19473                ProcessRecord proc = null;
19474                if (process != null) {
19475                    proc = findProcessLocked(process, userId, "profileControl");
19476                }
19477
19478                if (start && (proc == null || proc.thread == null)) {
19479                    throw new IllegalArgumentException("Unknown process: " + process);
19480                }
19481
19482                if (start) {
19483                    stopProfilerLocked(null, 0);
19484                    setProfileApp(proc.info, proc.processName, profilerInfo);
19485                    mProfileProc = proc;
19486                    mProfileType = profileType;
19487                    ParcelFileDescriptor fd = profilerInfo.profileFd;
19488                    try {
19489                        fd = fd.dup();
19490                    } catch (IOException e) {
19491                        fd = null;
19492                    }
19493                    profilerInfo.profileFd = fd;
19494                    proc.thread.profilerControl(start, profilerInfo, profileType);
19495                    fd = null;
19496                    mProfileFd = null;
19497                } else {
19498                    stopProfilerLocked(proc, profileType);
19499                    if (profilerInfo != null && profilerInfo.profileFd != null) {
19500                        try {
19501                            profilerInfo.profileFd.close();
19502                        } catch (IOException e) {
19503                        }
19504                    }
19505                }
19506
19507                return true;
19508            }
19509        } catch (RemoteException e) {
19510            throw new IllegalStateException("Process disappeared");
19511        } finally {
19512            if (profilerInfo != null && profilerInfo.profileFd != null) {
19513                try {
19514                    profilerInfo.profileFd.close();
19515                } catch (IOException e) {
19516                }
19517            }
19518        }
19519    }
19520
19521    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19522        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19523                userId, true, ALLOW_FULL_ONLY, callName, null);
19524        ProcessRecord proc = null;
19525        try {
19526            int pid = Integer.parseInt(process);
19527            synchronized (mPidsSelfLocked) {
19528                proc = mPidsSelfLocked.get(pid);
19529            }
19530        } catch (NumberFormatException e) {
19531        }
19532
19533        if (proc == null) {
19534            ArrayMap<String, SparseArray<ProcessRecord>> all
19535                    = mProcessNames.getMap();
19536            SparseArray<ProcessRecord> procs = all.get(process);
19537            if (procs != null && procs.size() > 0) {
19538                proc = procs.valueAt(0);
19539                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19540                    for (int i=1; i<procs.size(); i++) {
19541                        ProcessRecord thisProc = procs.valueAt(i);
19542                        if (thisProc.userId == userId) {
19543                            proc = thisProc;
19544                            break;
19545                        }
19546                    }
19547                }
19548            }
19549        }
19550
19551        return proc;
19552    }
19553
19554    public boolean dumpHeap(String process, int userId, boolean managed,
19555            String path, ParcelFileDescriptor fd) throws RemoteException {
19556
19557        try {
19558            synchronized (this) {
19559                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19560                // its own permission (same as profileControl).
19561                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19562                        != PackageManager.PERMISSION_GRANTED) {
19563                    throw new SecurityException("Requires permission "
19564                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19565                }
19566
19567                if (fd == null) {
19568                    throw new IllegalArgumentException("null fd");
19569                }
19570
19571                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19572                if (proc == null || proc.thread == null) {
19573                    throw new IllegalArgumentException("Unknown process: " + process);
19574                }
19575
19576                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19577                if (!isDebuggable) {
19578                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19579                        throw new SecurityException("Process not debuggable: " + proc);
19580                    }
19581                }
19582
19583                proc.thread.dumpHeap(managed, path, fd);
19584                fd = null;
19585                return true;
19586            }
19587        } catch (RemoteException e) {
19588            throw new IllegalStateException("Process disappeared");
19589        } finally {
19590            if (fd != null) {
19591                try {
19592                    fd.close();
19593                } catch (IOException e) {
19594                }
19595            }
19596        }
19597    }
19598
19599    @Override
19600    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19601            String reportPackage) {
19602        if (processName != null) {
19603            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19604                    "setDumpHeapDebugLimit()");
19605        } else {
19606            synchronized (mPidsSelfLocked) {
19607                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19608                if (proc == null) {
19609                    throw new SecurityException("No process found for calling pid "
19610                            + Binder.getCallingPid());
19611                }
19612                if (!Build.IS_DEBUGGABLE
19613                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19614                    throw new SecurityException("Not running a debuggable build");
19615                }
19616                processName = proc.processName;
19617                uid = proc.uid;
19618                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19619                    throw new SecurityException("Package " + reportPackage + " is not running in "
19620                            + proc);
19621                }
19622            }
19623        }
19624        synchronized (this) {
19625            if (maxMemSize > 0) {
19626                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19627            } else {
19628                if (uid != 0) {
19629                    mMemWatchProcesses.remove(processName, uid);
19630                } else {
19631                    mMemWatchProcesses.getMap().remove(processName);
19632                }
19633            }
19634        }
19635    }
19636
19637    @Override
19638    public void dumpHeapFinished(String path) {
19639        synchronized (this) {
19640            if (Binder.getCallingPid() != mMemWatchDumpPid) {
19641                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19642                        + " does not match last pid " + mMemWatchDumpPid);
19643                return;
19644            }
19645            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19646                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19647                        + " does not match last path " + mMemWatchDumpFile);
19648                return;
19649            }
19650            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19651            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19652        }
19653    }
19654
19655    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19656    public void monitor() {
19657        synchronized (this) { }
19658    }
19659
19660    void onCoreSettingsChange(Bundle settings) {
19661        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19662            ProcessRecord processRecord = mLruProcesses.get(i);
19663            try {
19664                if (processRecord.thread != null) {
19665                    processRecord.thread.setCoreSettings(settings);
19666                }
19667            } catch (RemoteException re) {
19668                /* ignore */
19669            }
19670        }
19671    }
19672
19673    // Multi-user methods
19674
19675    /**
19676     * Start user, if its not already running, but don't bring it to foreground.
19677     */
19678    @Override
19679    public boolean startUserInBackground(final int userId) {
19680        return startUser(userId, /* foreground */ false);
19681    }
19682
19683    /**
19684     * Start user, if its not already running, and bring it to foreground.
19685     */
19686    boolean startUserInForeground(final int userId, Dialog dlg) {
19687        boolean result = startUser(userId, /* foreground */ true);
19688        dlg.dismiss();
19689        return result;
19690    }
19691
19692    /**
19693     * Refreshes the list of users related to the current user when either a
19694     * user switch happens or when a new related user is started in the
19695     * background.
19696     */
19697    private void updateCurrentProfileIdsLocked() {
19698        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19699                mCurrentUserId, false /* enabledOnly */);
19700        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19701        for (int i = 0; i < currentProfileIds.length; i++) {
19702            currentProfileIds[i] = profiles.get(i).id;
19703        }
19704        mCurrentProfileIds = currentProfileIds;
19705
19706        synchronized (mUserProfileGroupIdsSelfLocked) {
19707            mUserProfileGroupIdsSelfLocked.clear();
19708            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19709            for (int i = 0; i < users.size(); i++) {
19710                UserInfo user = users.get(i);
19711                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19712                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19713                }
19714            }
19715        }
19716    }
19717
19718    private Set<Integer> getProfileIdsLocked(int userId) {
19719        Set<Integer> userIds = new HashSet<Integer>();
19720        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19721                userId, false /* enabledOnly */);
19722        for (UserInfo user : profiles) {
19723            userIds.add(Integer.valueOf(user.id));
19724        }
19725        return userIds;
19726    }
19727
19728    @Override
19729    public boolean switchUser(final int userId) {
19730        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19731        String userName;
19732        synchronized (this) {
19733            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19734            if (userInfo == null) {
19735                Slog.w(TAG, "No user info for user #" + userId);
19736                return false;
19737            }
19738            if (userInfo.isManagedProfile()) {
19739                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19740                return false;
19741            }
19742            userName = userInfo.name;
19743            mTargetUserId = userId;
19744        }
19745        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19746        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19747        return true;
19748    }
19749
19750    private void showUserSwitchDialog(int userId, String userName) {
19751        // The dialog will show and then initiate the user switch by calling startUserInForeground
19752        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19753                true /* above system */);
19754        d.show();
19755    }
19756
19757    private boolean startUser(final int userId, final boolean foreground) {
19758        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19759                != PackageManager.PERMISSION_GRANTED) {
19760            String msg = "Permission Denial: switchUser() from pid="
19761                    + Binder.getCallingPid()
19762                    + ", uid=" + Binder.getCallingUid()
19763                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19764            Slog.w(TAG, msg);
19765            throw new SecurityException(msg);
19766        }
19767
19768        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19769
19770        final long ident = Binder.clearCallingIdentity();
19771        try {
19772            synchronized (this) {
19773                final int oldUserId = mCurrentUserId;
19774                if (oldUserId == userId) {
19775                    return true;
19776                }
19777
19778                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19779                        "startUser", false);
19780
19781                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19782                if (userInfo == null) {
19783                    Slog.w(TAG, "No user info for user #" + userId);
19784                    return false;
19785                }
19786                if (foreground && userInfo.isManagedProfile()) {
19787                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19788                    return false;
19789                }
19790
19791                if (foreground) {
19792                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19793                            R.anim.screen_user_enter);
19794                }
19795
19796                boolean needStart = false;
19797
19798                // If the user we are switching to is not currently started, then
19799                // we need to start it now.
19800                if (mStartedUsers.get(userId) == null) {
19801                    mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
19802                    updateStartedUserArrayLocked();
19803                    needStart = true;
19804                }
19805
19806                final Integer userIdInt = Integer.valueOf(userId);
19807                mUserLru.remove(userIdInt);
19808                mUserLru.add(userIdInt);
19809
19810                if (foreground) {
19811                    mCurrentUserId = userId;
19812                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19813                    updateCurrentProfileIdsLocked();
19814                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19815                    // Once the internal notion of the active user has switched, we lock the device
19816                    // with the option to show the user switcher on the keyguard.
19817                    mWindowManager.lockNow(null);
19818                } else {
19819                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19820                    updateCurrentProfileIdsLocked();
19821                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19822                    mUserLru.remove(currentUserIdInt);
19823                    mUserLru.add(currentUserIdInt);
19824                }
19825
19826                final UserState uss = mStartedUsers.get(userId);
19827
19828                // Make sure user is in the started state.  If it is currently
19829                // stopping, we need to knock that off.
19830                if (uss.mState == UserState.STATE_STOPPING) {
19831                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19832                    // so we can just fairly silently bring the user back from
19833                    // the almost-dead.
19834                    uss.mState = UserState.STATE_RUNNING;
19835                    updateStartedUserArrayLocked();
19836                    needStart = true;
19837                } else if (uss.mState == UserState.STATE_SHUTDOWN) {
19838                    // This means ACTION_SHUTDOWN has been sent, so we will
19839                    // need to treat this as a new boot of the user.
19840                    uss.mState = UserState.STATE_BOOTING;
19841                    updateStartedUserArrayLocked();
19842                    needStart = true;
19843                }
19844
19845                if (uss.mState == UserState.STATE_BOOTING) {
19846                    // Booting up a new user, need to tell system services about it.
19847                    // Note that this is on the same handler as scheduling of broadcasts,
19848                    // which is important because it needs to go first.
19849                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19850                }
19851
19852                if (foreground) {
19853                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19854                            oldUserId));
19855                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19856                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19857                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19858                            oldUserId, userId, uss));
19859                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19860                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19861                }
19862
19863                if (needStart) {
19864                    // Send USER_STARTED broadcast
19865                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19866                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19867                            | Intent.FLAG_RECEIVER_FOREGROUND);
19868                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19869                    broadcastIntentLocked(null, null, intent,
19870                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19871                            null, false, false, MY_PID, Process.SYSTEM_UID, userId);
19872                }
19873
19874                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19875                    if (userId != UserHandle.USER_OWNER) {
19876                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19877                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19878                        broadcastIntentLocked(null, null, intent, null,
19879                                new IIntentReceiver.Stub() {
19880                                    public void performReceive(Intent intent, int resultCode,
19881                                            String data, Bundle extras, boolean ordered,
19882                                            boolean sticky, int sendingUser) {
19883                                        onUserInitialized(uss, foreground, oldUserId, userId);
19884                                    }
19885                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19886                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19887                        uss.initializing = true;
19888                    } else {
19889                        getUserManagerLocked().makeInitialized(userInfo.id);
19890                    }
19891                }
19892
19893                if (foreground) {
19894                    if (!uss.initializing) {
19895                        moveUserToForeground(uss, oldUserId, userId);
19896                    }
19897                } else {
19898                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19899                }
19900
19901                if (needStart) {
19902                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19903                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19904                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19905                    broadcastIntentLocked(null, null, intent,
19906                            null, new IIntentReceiver.Stub() {
19907                                @Override
19908                                public void performReceive(Intent intent, int resultCode,
19909                                        String data, Bundle extras, boolean ordered, boolean sticky,
19910                                        int sendingUser) throws RemoteException {
19911                                }
19912                            }, 0, null, null,
19913                            new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
19914                            null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19915                }
19916            }
19917        } finally {
19918            Binder.restoreCallingIdentity(ident);
19919        }
19920
19921        return true;
19922    }
19923
19924    void dispatchForegroundProfileChanged(int userId) {
19925        final int N = mUserSwitchObservers.beginBroadcast();
19926        for (int i = 0; i < N; i++) {
19927            try {
19928                mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19929            } catch (RemoteException e) {
19930                // Ignore
19931            }
19932        }
19933        mUserSwitchObservers.finishBroadcast();
19934    }
19935
19936    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19937        long ident = Binder.clearCallingIdentity();
19938        try {
19939            Intent intent;
19940            if (oldUserId >= 0) {
19941                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19942                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19943                int count = profiles.size();
19944                for (int i = 0; i < count; i++) {
19945                    int profileUserId = profiles.get(i).id;
19946                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19947                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19948                            | Intent.FLAG_RECEIVER_FOREGROUND);
19949                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19950                    broadcastIntentLocked(null, null, intent,
19951                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19952                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19953                }
19954            }
19955            if (newUserId >= 0) {
19956                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19957                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19958                int count = profiles.size();
19959                for (int i = 0; i < count; i++) {
19960                    int profileUserId = profiles.get(i).id;
19961                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19962                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19963                            | Intent.FLAG_RECEIVER_FOREGROUND);
19964                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19965                    broadcastIntentLocked(null, null, intent,
19966                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19967                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19968                }
19969                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19970                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19971                        | Intent.FLAG_RECEIVER_FOREGROUND);
19972                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19973                broadcastIntentLocked(null, null, intent,
19974                        null, null, 0, null, null,
19975                        new String[] {android.Manifest.permission.MANAGE_USERS},
19976                        AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19977                        UserHandle.USER_ALL);
19978            }
19979        } finally {
19980            Binder.restoreCallingIdentity(ident);
19981        }
19982    }
19983
19984    void dispatchUserSwitch(final UserState uss, final int oldUserId,
19985            final int newUserId) {
19986        final int N = mUserSwitchObservers.beginBroadcast();
19987        if (N > 0) {
19988            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19989                int mCount = 0;
19990                @Override
19991                public void sendResult(Bundle data) throws RemoteException {
19992                    synchronized (ActivityManagerService.this) {
19993                        if (mCurUserSwitchCallback == this) {
19994                            mCount++;
19995                            if (mCount == N) {
19996                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19997                            }
19998                        }
19999                    }
20000                }
20001            };
20002            synchronized (this) {
20003                uss.switching = true;
20004                mCurUserSwitchCallback = callback;
20005            }
20006            for (int i=0; i<N; i++) {
20007                try {
20008                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
20009                            newUserId, callback);
20010                } catch (RemoteException e) {
20011                }
20012            }
20013        } else {
20014            synchronized (this) {
20015                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20016            }
20017        }
20018        mUserSwitchObservers.finishBroadcast();
20019    }
20020
20021    void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
20022        synchronized (this) {
20023            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
20024            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20025        }
20026    }
20027
20028    void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
20029        mCurUserSwitchCallback = null;
20030        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
20031        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
20032                oldUserId, newUserId, uss));
20033    }
20034
20035    void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
20036        synchronized (this) {
20037            if (foreground) {
20038                moveUserToForeground(uss, oldUserId, newUserId);
20039            }
20040        }
20041
20042        completeSwitchAndInitialize(uss, newUserId, true, false);
20043    }
20044
20045    void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
20046        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
20047        if (homeInFront) {
20048            startHomeActivityLocked(newUserId, "moveUserToFroreground");
20049        } else {
20050            mStackSupervisor.resumeTopActivitiesLocked();
20051        }
20052        EventLogTags.writeAmSwitchUser(newUserId);
20053        getUserManagerLocked().onUserForeground(newUserId);
20054        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
20055    }
20056
20057    void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
20058        completeSwitchAndInitialize(uss, newUserId, false, true);
20059    }
20060
20061    void completeSwitchAndInitialize(UserState uss, int newUserId,
20062            boolean clearInitializing, boolean clearSwitching) {
20063        boolean unfrozen = false;
20064        synchronized (this) {
20065            if (clearInitializing) {
20066                uss.initializing = false;
20067                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
20068            }
20069            if (clearSwitching) {
20070                uss.switching = false;
20071            }
20072            if (!uss.switching && !uss.initializing) {
20073                mWindowManager.stopFreezingScreen();
20074                unfrozen = true;
20075            }
20076        }
20077        if (unfrozen) {
20078            mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
20079            mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
20080                    newUserId, 0));
20081        }
20082        stopGuestUserIfBackground();
20083    }
20084
20085    /** Called on handler thread */
20086    void dispatchUserSwitchComplete(int userId) {
20087        final int observerCount = mUserSwitchObservers.beginBroadcast();
20088        for (int i = 0; i < observerCount; i++) {
20089            try {
20090                mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
20091            } catch (RemoteException e) {
20092            }
20093        }
20094        mUserSwitchObservers.finishBroadcast();
20095    }
20096
20097    /**
20098     * Stops the guest user if it has gone to the background.
20099     */
20100    private void stopGuestUserIfBackground() {
20101        synchronized (this) {
20102            final int num = mUserLru.size();
20103            for (int i = 0; i < num; i++) {
20104                Integer oldUserId = mUserLru.get(i);
20105                UserState oldUss = mStartedUsers.get(oldUserId);
20106                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
20107                        || oldUss.mState == UserState.STATE_STOPPING
20108                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
20109                    continue;
20110                }
20111                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
20112                if (userInfo.isGuest()) {
20113                    // This is a user to be stopped.
20114                    stopUserLocked(oldUserId, null);
20115                    break;
20116                }
20117            }
20118        }
20119    }
20120
20121    void scheduleStartProfilesLocked() {
20122        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20123            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20124                    DateUtils.SECOND_IN_MILLIS);
20125        }
20126    }
20127
20128    void startProfilesLocked() {
20129        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
20130        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
20131                mCurrentUserId, false /* enabledOnly */);
20132        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
20133        for (UserInfo user : profiles) {
20134            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
20135                    && user.id != mCurrentUserId) {
20136                toStart.add(user);
20137            }
20138        }
20139        final int n = toStart.size();
20140        int i = 0;
20141        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
20142            startUserInBackground(toStart.get(i).id);
20143        }
20144        if (i < n) {
20145            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
20146        }
20147    }
20148
20149    void finishUserBoot(UserState uss) {
20150        synchronized (this) {
20151            if (uss.mState == UserState.STATE_BOOTING
20152                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20153                uss.mState = UserState.STATE_RUNNING;
20154                final int userId = uss.mHandle.getIdentifier();
20155                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20156                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20157                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20158                broadcastIntentLocked(null, null, intent,
20159                        null, null, 0, null, null,
20160                        new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
20161                        AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID,
20162                        userId);
20163            }
20164        }
20165    }
20166
20167    void finishUserSwitch(UserState uss) {
20168        synchronized (this) {
20169            finishUserBoot(uss);
20170
20171            startProfilesLocked();
20172
20173            int num = mUserLru.size();
20174            int i = 0;
20175            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20176                Integer oldUserId = mUserLru.get(i);
20177                UserState oldUss = mStartedUsers.get(oldUserId);
20178                if (oldUss == null) {
20179                    // Shouldn't happen, but be sane if it does.
20180                    mUserLru.remove(i);
20181                    num--;
20182                    continue;
20183                }
20184                if (oldUss.mState == UserState.STATE_STOPPING
20185                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
20186                    // This user is already stopping, doesn't count.
20187                    num--;
20188                    i++;
20189                    continue;
20190                }
20191                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20192                    // Owner and current can't be stopped, but count as running.
20193                    i++;
20194                    continue;
20195                }
20196                // This is a user to be stopped.
20197                stopUserLocked(oldUserId, null);
20198                num--;
20199                i++;
20200            }
20201        }
20202    }
20203
20204    @Override
20205    public int stopUser(final int userId, final IStopUserCallback callback) {
20206        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20207                != PackageManager.PERMISSION_GRANTED) {
20208            String msg = "Permission Denial: switchUser() from pid="
20209                    + Binder.getCallingPid()
20210                    + ", uid=" + Binder.getCallingUid()
20211                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20212            Slog.w(TAG, msg);
20213            throw new SecurityException(msg);
20214        }
20215        if (userId < 0 || userId == UserHandle.USER_OWNER) {
20216            throw new IllegalArgumentException("Can't stop primary user " + userId);
20217        }
20218        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20219        synchronized (this) {
20220            return stopUserLocked(userId, callback);
20221        }
20222    }
20223
20224    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20225        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20226        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20227            return ActivityManager.USER_OP_IS_CURRENT;
20228        }
20229
20230        final UserState uss = mStartedUsers.get(userId);
20231        if (uss == null) {
20232            // User is not started, nothing to do...  but we do need to
20233            // callback if requested.
20234            if (callback != null) {
20235                mHandler.post(new Runnable() {
20236                    @Override
20237                    public void run() {
20238                        try {
20239                            callback.userStopped(userId);
20240                        } catch (RemoteException e) {
20241                        }
20242                    }
20243                });
20244            }
20245            return ActivityManager.USER_OP_SUCCESS;
20246        }
20247
20248        if (callback != null) {
20249            uss.mStopCallbacks.add(callback);
20250        }
20251
20252        if (uss.mState != UserState.STATE_STOPPING
20253                && uss.mState != UserState.STATE_SHUTDOWN) {
20254            uss.mState = UserState.STATE_STOPPING;
20255            updateStartedUserArrayLocked();
20256
20257            long ident = Binder.clearCallingIdentity();
20258            try {
20259                // We are going to broadcast ACTION_USER_STOPPING and then
20260                // once that is done send a final ACTION_SHUTDOWN and then
20261                // stop the user.
20262                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20263                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20264                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20265                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20266                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20267                // This is the result receiver for the final shutdown broadcast.
20268                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20269                    @Override
20270                    public void performReceive(Intent intent, int resultCode, String data,
20271                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20272                        finishUserStop(uss);
20273                    }
20274                };
20275                // This is the result receiver for the initial stopping broadcast.
20276                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20277                    @Override
20278                    public void performReceive(Intent intent, int resultCode, String data,
20279                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20280                        // On to the next.
20281                        synchronized (ActivityManagerService.this) {
20282                            if (uss.mState != UserState.STATE_STOPPING) {
20283                                // Whoops, we are being started back up.  Abort, abort!
20284                                return;
20285                            }
20286                            uss.mState = UserState.STATE_SHUTDOWN;
20287                        }
20288                        mBatteryStatsService.noteEvent(
20289                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20290                                Integer.toString(userId), userId);
20291                        mSystemServiceManager.stopUser(userId);
20292                        broadcastIntentLocked(null, null, shutdownIntent,
20293                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20294                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20295                    }
20296                };
20297                // Kick things off.
20298                broadcastIntentLocked(null, null, stoppingIntent,
20299                        null, stoppingReceiver, 0, null, null,
20300                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20301                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20302            } finally {
20303                Binder.restoreCallingIdentity(ident);
20304            }
20305        }
20306
20307        return ActivityManager.USER_OP_SUCCESS;
20308    }
20309
20310    void finishUserStop(UserState uss) {
20311        final int userId = uss.mHandle.getIdentifier();
20312        boolean stopped;
20313        ArrayList<IStopUserCallback> callbacks;
20314        synchronized (this) {
20315            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20316            if (mStartedUsers.get(userId) != uss) {
20317                stopped = false;
20318            } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20319                stopped = false;
20320            } else {
20321                stopped = true;
20322                // User can no longer run.
20323                mStartedUsers.remove(userId);
20324                mUserLru.remove(Integer.valueOf(userId));
20325                updateStartedUserArrayLocked();
20326
20327                // Clean up all state and processes associated with the user.
20328                // Kill all the processes for the user.
20329                forceStopUserLocked(userId, "finish user");
20330            }
20331
20332            // Explicitly remove the old information in mRecentTasks.
20333            mRecentTasks.removeTasksForUserLocked(userId);
20334        }
20335
20336        for (int i=0; i<callbacks.size(); i++) {
20337            try {
20338                if (stopped) callbacks.get(i).userStopped(userId);
20339                else callbacks.get(i).userStopAborted(userId);
20340            } catch (RemoteException e) {
20341            }
20342        }
20343
20344        if (stopped) {
20345            mSystemServiceManager.cleanupUser(userId);
20346            synchronized (this) {
20347                mStackSupervisor.removeUserLocked(userId);
20348            }
20349        }
20350    }
20351
20352    @Override
20353    public UserInfo getCurrentUser() {
20354        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20355                != PackageManager.PERMISSION_GRANTED) && (
20356                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20357                != PackageManager.PERMISSION_GRANTED)) {
20358            String msg = "Permission Denial: getCurrentUser() from pid="
20359                    + Binder.getCallingPid()
20360                    + ", uid=" + Binder.getCallingUid()
20361                    + " requires " + INTERACT_ACROSS_USERS;
20362            Slog.w(TAG, msg);
20363            throw new SecurityException(msg);
20364        }
20365        synchronized (this) {
20366            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20367            return getUserManagerLocked().getUserInfo(userId);
20368        }
20369    }
20370
20371    int getCurrentUserIdLocked() {
20372        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20373    }
20374
20375    @Override
20376    public boolean isUserRunning(int userId, boolean orStopped) {
20377        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20378                != PackageManager.PERMISSION_GRANTED) {
20379            String msg = "Permission Denial: isUserRunning() from pid="
20380                    + Binder.getCallingPid()
20381                    + ", uid=" + Binder.getCallingUid()
20382                    + " requires " + INTERACT_ACROSS_USERS;
20383            Slog.w(TAG, msg);
20384            throw new SecurityException(msg);
20385        }
20386        synchronized (this) {
20387            return isUserRunningLocked(userId, orStopped);
20388        }
20389    }
20390
20391    boolean isUserRunningLocked(int userId, boolean orStopped) {
20392        UserState state = mStartedUsers.get(userId);
20393        if (state == null) {
20394            return false;
20395        }
20396        if (orStopped) {
20397            return true;
20398        }
20399        return state.mState != UserState.STATE_STOPPING
20400                && state.mState != UserState.STATE_SHUTDOWN;
20401    }
20402
20403    @Override
20404    public int[] getRunningUserIds() {
20405        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20406                != PackageManager.PERMISSION_GRANTED) {
20407            String msg = "Permission Denial: isUserRunning() from pid="
20408                    + Binder.getCallingPid()
20409                    + ", uid=" + Binder.getCallingUid()
20410                    + " requires " + INTERACT_ACROSS_USERS;
20411            Slog.w(TAG, msg);
20412            throw new SecurityException(msg);
20413        }
20414        synchronized (this) {
20415            return mStartedUserArray;
20416        }
20417    }
20418
20419    private void updateStartedUserArrayLocked() {
20420        int num = 0;
20421        for (int i=0; i<mStartedUsers.size();  i++) {
20422            UserState uss = mStartedUsers.valueAt(i);
20423            // This list does not include stopping users.
20424            if (uss.mState != UserState.STATE_STOPPING
20425                    && uss.mState != UserState.STATE_SHUTDOWN) {
20426                num++;
20427            }
20428        }
20429        mStartedUserArray = new int[num];
20430        num = 0;
20431        for (int i=0; i<mStartedUsers.size();  i++) {
20432            UserState uss = mStartedUsers.valueAt(i);
20433            if (uss.mState != UserState.STATE_STOPPING
20434                    && uss.mState != UserState.STATE_SHUTDOWN) {
20435                mStartedUserArray[num] = mStartedUsers.keyAt(i);
20436                num++;
20437            }
20438        }
20439    }
20440
20441    @Override
20442    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20443        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20444                != PackageManager.PERMISSION_GRANTED) {
20445            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20446                    + Binder.getCallingPid()
20447                    + ", uid=" + Binder.getCallingUid()
20448                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20449            Slog.w(TAG, msg);
20450            throw new SecurityException(msg);
20451        }
20452
20453        mUserSwitchObservers.register(observer);
20454    }
20455
20456    @Override
20457    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20458        mUserSwitchObservers.unregister(observer);
20459    }
20460
20461    int[] getUsersLocked() {
20462        UserManagerService ums = getUserManagerLocked();
20463        return ums != null ? ums.getUserIds() : new int[] { 0 };
20464    }
20465
20466    UserManagerService getUserManagerLocked() {
20467        if (mUserManager == null) {
20468            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20469            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20470        }
20471        return mUserManager;
20472    }
20473
20474    private int applyUserId(int uid, int userId) {
20475        return UserHandle.getUid(userId, uid);
20476    }
20477
20478    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20479        if (info == null) return null;
20480        ApplicationInfo newInfo = new ApplicationInfo(info);
20481        newInfo.uid = applyUserId(info.uid, userId);
20482        newInfo.dataDir = Environment
20483                .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20484                .getAbsolutePath();
20485        return newInfo;
20486    }
20487
20488    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20489        if (aInfo == null
20490                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20491            return aInfo;
20492        }
20493
20494        ActivityInfo info = new ActivityInfo(aInfo);
20495        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20496        return info;
20497    }
20498
20499    private final class LocalService extends ActivityManagerInternal {
20500        @Override
20501        public void onWakefulnessChanged(int wakefulness) {
20502            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20503        }
20504
20505        @Override
20506        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20507                String processName, String abiOverride, int uid, Runnable crashHandler) {
20508            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20509                    processName, abiOverride, uid, crashHandler);
20510        }
20511
20512        @Override
20513        public SleepToken acquireSleepToken(String tag) {
20514            Preconditions.checkNotNull(tag);
20515
20516            synchronized (ActivityManagerService.this) {
20517                SleepTokenImpl token = new SleepTokenImpl(tag);
20518                mSleepTokens.add(token);
20519                updateSleepIfNeededLocked();
20520                return token;
20521            }
20522        }
20523
20524        @Override
20525        public ComponentName getHomeActivityForUser(int userId) {
20526            synchronized (ActivityManagerService.this) {
20527                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20528                return homeActivity == null ? null : homeActivity.realActivity;
20529            }
20530        }
20531    }
20532
20533    private final class SleepTokenImpl extends SleepToken {
20534        private final String mTag;
20535        private final long mAcquireTime;
20536
20537        public SleepTokenImpl(String tag) {
20538            mTag = tag;
20539            mAcquireTime = SystemClock.uptimeMillis();
20540        }
20541
20542        @Override
20543        public void release() {
20544            synchronized (ActivityManagerService.this) {
20545                if (mSleepTokens.remove(this)) {
20546                    updateSleepIfNeededLocked();
20547                }
20548            }
20549        }
20550
20551        @Override
20552        public String toString() {
20553            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20554        }
20555    }
20556
20557    /**
20558     * An implementation of IAppTask, that allows an app to manage its own tasks via
20559     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20560     * only the process that calls getAppTasks() can call the AppTask methods.
20561     */
20562    class AppTaskImpl extends IAppTask.Stub {
20563        private int mTaskId;
20564        private int mCallingUid;
20565
20566        public AppTaskImpl(int taskId, int callingUid) {
20567            mTaskId = taskId;
20568            mCallingUid = callingUid;
20569        }
20570
20571        private void checkCaller() {
20572            if (mCallingUid != Binder.getCallingUid()) {
20573                throw new SecurityException("Caller " + mCallingUid
20574                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20575            }
20576        }
20577
20578        @Override
20579        public void finishAndRemoveTask() {
20580            checkCaller();
20581
20582            synchronized (ActivityManagerService.this) {
20583                long origId = Binder.clearCallingIdentity();
20584                try {
20585                    if (!removeTaskByIdLocked(mTaskId, false)) {
20586                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20587                    }
20588                } finally {
20589                    Binder.restoreCallingIdentity(origId);
20590                }
20591            }
20592        }
20593
20594        @Override
20595        public ActivityManager.RecentTaskInfo getTaskInfo() {
20596            checkCaller();
20597
20598            synchronized (ActivityManagerService.this) {
20599                long origId = Binder.clearCallingIdentity();
20600                try {
20601                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20602                    if (tr == null) {
20603                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20604                    }
20605                    return createRecentTaskInfoFromTaskRecord(tr);
20606                } finally {
20607                    Binder.restoreCallingIdentity(origId);
20608                }
20609            }
20610        }
20611
20612        @Override
20613        public void moveToFront() {
20614            checkCaller();
20615            // Will bring task to front if it already has a root activity.
20616            startActivityFromRecentsInner(mTaskId, null);
20617        }
20618
20619        @Override
20620        public int startActivity(IBinder whoThread, String callingPackage,
20621                Intent intent, String resolvedType, Bundle options) {
20622            checkCaller();
20623
20624            int callingUser = UserHandle.getCallingUserId();
20625            TaskRecord tr;
20626            IApplicationThread appThread;
20627            synchronized (ActivityManagerService.this) {
20628                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20629                if (tr == null) {
20630                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20631                }
20632                appThread = ApplicationThreadNative.asInterface(whoThread);
20633                if (appThread == null) {
20634                    throw new IllegalArgumentException("Bad app thread " + appThread);
20635                }
20636            }
20637            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20638                    resolvedType, null, null, null, null, 0, 0, null, null,
20639                    null, options, false, callingUser, null, tr);
20640        }
20641
20642        @Override
20643        public void setExcludeFromRecents(boolean exclude) {
20644            checkCaller();
20645
20646            synchronized (ActivityManagerService.this) {
20647                long origId = Binder.clearCallingIdentity();
20648                try {
20649                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20650                    if (tr == null) {
20651                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20652                    }
20653                    Intent intent = tr.getBaseIntent();
20654                    if (exclude) {
20655                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20656                    } else {
20657                        intent.setFlags(intent.getFlags()
20658                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20659                    }
20660                } finally {
20661                    Binder.restoreCallingIdentity(origId);
20662                }
20663            }
20664        }
20665    }
20666}
20667